Merge "feat(rpi5): add PCI SMCCC support" into integration
diff --git a/.cz-adapter.cjs b/.cz-adapter.cjs
new file mode 100644
index 0000000..26aaeb2
--- /dev/null
+++ b/.cz-adapter.cjs
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * A workaround for:
+ *
+ *     https://github.com/conventional-changelog/commitlint/issues/3949
+ */
+
+exports.prompter = async (inquirerIns, commit) => {
+    ; (await import('@commitlint/cz-commitlint')).prompter(inquirerIns, commit)
+}
diff --git a/.cz.json b/.cz.json
index 556c39f..969a73b 100644
--- a/.cz.json
+++ b/.cz.json
@@ -1,3 +1,3 @@
 {
-    "path": "@commitlint/cz-commitlint"
+    "path": "./.cz-adapter.cjs"
 }
diff --git a/.husky/commit-msg b/.husky/commit-msg
index c1c9600..b5d407b 100755
--- a/.husky/commit-msg
+++ b/.husky/commit-msg
@@ -1,7 +1,4 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 "$(dirname "$0")/commit-msg.gerrit" "$@"
 "$(dirname "$0")/commit-msg.commitlint" "$@"
diff --git a/.husky/pre-commit b/.husky/pre-commit
index afcb1f6..f438ddb 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,6 +1,3 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 "$(dirname "$0")/pre-commit.copyright" "$@"
diff --git a/Makefile b/Makefile
index 6a1ea99..bbde1a7 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 2
-VERSION_MINOR			:= 10
+VERSION_MINOR			:= 11
 # VERSION_PATCH is only used for LTS releases
 VERSION_PATCH			:= 0
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
@@ -24,6 +24,7 @@
 MAKE_HELPERS_DIRECTORY := make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 
 ################################################################################
 # Default values for build configurations, and their dependencies
@@ -35,6 +36,17 @@
 # Configure the toolchains used to build TF-A and its tools
 ################################################################################
 
+#
+# The clean and check targets do not behave correctly if the user's environment
+# does not appropriately configure a toolchain. While we try to find a permanent
+# solution to this, do not try to detect any toolchains if we are building
+# exclusively with targets which do not use any toolchain tools.
+#
+
+ifeq ($(filter-out check% %clean doc %tool,$(or $(MAKECMDGOALS),all)),)
+        toolchains :=
+endif
+
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 # Assertions enabled for DEBUG builds by default
@@ -82,23 +94,10 @@
 # Process build options
 ################################################################################
 
-# Verbose flag
-ifeq (${V},0)
-	Q:=@
-	ECHO:=@echo
+ifeq ($(verbose),)
 	CHECKCODE_ARGS	+=	--no-summary --terse
-else
-	Q:=
-	ECHO:=$(ECHO_QUIET)
 endif
 
-ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
-	Q:=@
-	ECHO:=$(ECHO_QUIET)
-endif
-
-export Q ECHO
-
 ################################################################################
 # Auxiliary tools (fiptool, cert_create, etc)
 ################################################################################
@@ -155,11 +154,9 @@
 	endif
 
 else ifeq ($($(ARCH)-cc-id),gnu-gcc)
-	ifeq ($(ENABLE_LTO),1)
-		# Enable LTO only for aarch64
-		ifeq (${ARCH},aarch64)
-			LTO_CFLAGS	=	-flto
-		endif
+	# Enable LTO only for aarch64
+	ifeq (${ARCH},aarch64)
+		LTO_CFLAGS	=	$(if $(filter-out 0,$(ENABLE_LTO)),-flto)
 	endif
 endif #(clang)
 
@@ -301,7 +298,7 @@
 				-fsanitize-undefined-trap-on-error
 endif #(${SANITIZE_UB},trap)
 
-GCC_V_OUTPUT		:=	$(shell $($(ARCH)-cc) -v 2>&1)
+GCC_V_OUTPUT		:=	$(if $($(ARCH)-cc),$(shell $($(ARCH)-cc) -v 2>&1))
 
 TF_LDFLAGS		+=	-z noexecstack
 
@@ -325,6 +322,7 @@
 	ifeq ($(ENABLE_LTO),1)
 		ifeq (${ARCH},aarch64)
 			TF_LDFLAGS	+=	-flto -fuse-linker-plugin
+			TF_LDFLAGS      +=	-flto-partition=one
 		endif
 	endif #(ENABLE_LTO)
 
@@ -364,8 +362,8 @@
 # Setup ARCH_MAJOR/MINOR before parsing arch_features.
 ################################################################################
 ifeq (${ENABLE_RME},1)
-	ARM_ARCH_MAJOR := 8
-	ARM_ARCH_MINOR := 6
+	ARM_ARCH_MAJOR := 9
+	ARM_ARCH_MINOR := 2
 endif
 
 ################################################################################
@@ -373,6 +371,15 @@
 ################################################################################
 include lib/compiler-rt/compiler-rt.mk
 
+# Allow overriding the timestamp, for example for reproducible builds, or to
+# synchronize timestamps across multiple projects.
+# This must be set to a C string (including quotes where applicable).
+BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
+
+DEFINES += -DBUILD_MESSAGE_TIMESTAMP='$(BUILD_MESSAGE_TIMESTAMP)'
+DEFINES += -DBUILD_MESSAGE_VERSION_STRING='"$(VERSION_STRING)"'
+DEFINES += -DBUILD_MESSAGE_VERSION='"$(VERSION)"'
+
 BL_COMMON_SOURCES	+=	common/bl_common.c			\
 				common/tf_log.c				\
 				common/${ARCH}/debug.S			\
@@ -899,10 +906,6 @@
 	endif
 endif #(CTX_INCLUDE_PAUTH_REGS)
 
-ifeq ($(PSA_FWU_SUPPORT),1)
-        $(info PSA_FWU_SUPPORT is an experimental feature)
-endif #(PSA_FWU_SUPPORT)
-
 ifeq ($(FEATURE_DETECTION),1)
         $(info FEATURE_DETECTION is an experimental feature)
 endif #(FEATURE_DETECTION)
@@ -1009,6 +1012,10 @@
         $(info PSA_CRYPTO is an experimental feature)
 endif
 
+ifeq ($(DICE_PROTECTION_ENVIRONMENT),1)
+        $(info DICE_PROTECTION_ENVIRONMENT is an experimental feature)
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -1146,6 +1153,7 @@
 	HARDEN_SLS \
 	HW_ASSISTED_COHERENCY \
 	MEASURED_BOOT \
+	DICE_PROTECTION_ENVIRONMENT \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	OVERRIDE_LIBC \
@@ -1185,6 +1193,7 @@
 	COT_DESC_IN_DTB \
 	USE_SP804_TIMER \
 	PSA_FWU_SUPPORT \
+	PSA_FWU_METADATA_FW_STORE_DESC \
 	ENABLE_MPMM \
 	ENABLE_MPMM_FCONF \
 	FEATURE_DETECTION \
@@ -1196,6 +1205,8 @@
 	ENABLE_CONSOLE_GETC \
 	INIT_UNUSED_NS_EL2	\
 	PLATFORM_REPORT_CTX_MEM_USE \
+	EARLY_CONSOLE \
+	PRESERVE_DSU_PMU_REGS \
 )))
 
 # Numeric_Flags
@@ -1220,7 +1231,6 @@
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
 	ENABLE_FEAT_HCX \
-	ENABLE_FEAT_MTE \
 	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_RNG \
@@ -1234,7 +1244,6 @@
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
-	ENABLE_FEAT_MTE_PERM \
 	ENABLE_FEAT_MPAM \
 	ENABLE_RME \
 	ENABLE_SPE_FOR_NS \
@@ -1312,6 +1321,7 @@
 	HW_ASSISTED_COHERENCY \
 	LOG_LEVEL \
 	MEASURED_BOOT \
+	DICE_PROTECTION_ENVIRONMENT \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	PL011_GENERIC_UART \
@@ -1320,6 +1330,8 @@
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
 	RESET_TO_BL31 \
+	RME_GPT_BITLOCK_BLOCK \
+	RME_GPT_MAX_BLOCK \
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
@@ -1360,6 +1372,7 @@
 	NR_OF_FW_BANKS \
 	NR_OF_IMAGES_IN_FW_BANK \
 	PSA_FWU_SUPPORT \
+	PSA_FWU_METADATA_FW_STORE_DESC \
 	ENABLE_BRBE_FOR_NS \
 	ENABLE_TRBE_FOR_NS \
 	ENABLE_SYS_REG_TRACE_FOR_NS \
@@ -1381,9 +1394,7 @@
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
-	ENABLE_FEAT_MTE \
 	ENABLE_FEAT_MTE2 \
-	ENABLE_FEAT_MTE_PERM \
 	FEATURE_DETECTION \
 	TWED_DELAY \
 	ENABLE_FEAT_TWED \
@@ -1395,6 +1406,8 @@
 	ENABLE_CONSOLE_GETC \
 	INIT_UNUSED_NS_EL2	\
 	PLATFORM_REPORT_CTX_MEM_USE \
+	EARLY_CONSOLE \
+	PRESERVE_DSU_PMU_REGS \
 )))
 
 ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
@@ -1452,7 +1465,7 @@
 all: msg_start
 
 msg_start:
-	@echo "Building ${PLAT}"
+	$(s)echo "Building ${PLAT}"
 
 ifeq (${ERROR_DEPRECATED},0)
 # Check if deprecated declarations and cpp warnings should be treated as error or not.
@@ -1548,11 +1561,11 @@
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
 $(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
-	@${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
+	$(q)${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"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built SP Images successfully"
+	$(s)echo
 endif #(NEED_SP_PKG)
 
 locate-checkpatch:
@@ -1565,37 +1578,37 @@
 endif #(CHECKPATCH)
 
 clean:
-	@echo "  CLEAN"
+	$(s)echo "  CLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
 ifdef UNIX_MK
-	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
-	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
+	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
 endif #(UNIX_MK)
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
-	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 realclean distclean:
-	@echo "  REALCLEAN"
+	$(s)echo "  REALCLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_BASE})
 	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
 ifdef UNIX_MK
-	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
-	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
+	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
 endif #(UNIX_MK)
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
-	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
+	$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 checkcodebase:		locate-checkpatch
-	@echo "  CHECKING STYLE"
-	@if test -d .git ; then						\
+	$(s)echo "  CHECKING STYLE"
+	$(q)if test -d .git ; then						\
 		git ls-files | grep -E -v 'libfdt|libc|docs|\.rst' |	\
 		while read GIT_FILE ;					\
 		do ${CHECKPATCH} ${CHECKCODE_ARGS} -f $$GIT_FILE ;	\
@@ -1611,11 +1624,11 @@
 	fi
 
 checkpatch:		locate-checkpatch
-	@echo "  CHECKING STYLE"
-	@if test -n "${CHECKPATCH_OPTS}"; then				\
+	$(s)echo "  CHECKING STYLE"
+	$(q)if test -n "${CHECKPATCH_OPTS}"; then				\
 		echo "    with ${CHECKPATCH_OPTS} option(s)";		\
 	fi
-	${Q}COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT});	\
+	$(q)COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT});	\
 	for commit in `git rev-list --no-merges $$COMMON_COMMIT..HEAD`;	\
 	do								\
 		printf "\n[*] Checking style of '$$commit'\n\n";	\
@@ -1630,44 +1643,44 @@
 certtool: ${CRTTOOL}
 
 ${CRTTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${CRTTOOLPATH} all
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} --no-print-directory -C ${CRTTOOLPATH} all
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ifneq (${GENERATE_COT},0)
 certificates: ${CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "Certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "Certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FIP_CMD})
-	${Q}${FIPTOOL} create ${FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ifneq (${GENERATE_COT},0)
 fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${FWU_CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "FWU certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${FWU_CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "FWU certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FWU_FIP_NAME}: ${FWU_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FWU_FIP_CMD})
-	${Q}${FIPTOOL} create ${FWU_FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${FWU_FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 fiptool: ${FIPTOOL}
 fip: ${BUILD_PLAT}/${FIP_NAME}
@@ -1675,85 +1688,85 @@
 
 ${FIPTOOL}: FORCE
 ifdef UNIX_MK
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${FIPTOOLPATH} all
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} --no-print-directory -C ${FIPTOOLPATH} all
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
-	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
+	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
 endif #(UNIX_MK)
 
 romlib.bin: libraries FORCE
-	${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
+	$(q)${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
 
 memmap: all
 ifdef UNIX_MK
-	${Q}PYTHONPATH=${CURDIR}/tools/memory \
+	$(q)PYTHONPATH=${CURDIR}/tools/memory \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 else
-	${Q}set PYTHONPATH=${CURDIR}/tools/memory && \
+	$(q)set PYTHONPATH=${CURDIR}/tools/memory && \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 endif
 
 doc:
-	@echo "  BUILD DOCUMENTATION"
-	${Q}${MAKE} --no-print-directory -C ${DOCS_PATH} html
+	$(s)echo "  BUILD DOCUMENTATION"
+	$(q)${MAKE} --no-print-directory -C ${DOCS_PATH} html
 
 enctool: ${ENCTOOL}
 
 ${ENCTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${ENCTOOLPATH} all
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} --no-print-directory -C ${ENCTOOLPATH} all
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 cscope:
-	@echo "  CSCOPE"
-	${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
-	${Q}cscope -b -q -k
+	$(s)echo "  CSCOPE"
+	$(q)find ${CURDIR} -name "*.[chsS]" > cscope.files
+	$(q)cscope -b -q -k
 
 help:
-	@echo "usage: ${MAKE} [PLAT=<platform>] [OPTIONS] [TARGET]"
-	@echo ""
-	@echo "PLAT is used to specify which platform you wish to build."
-	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
-	@echo ""
-	@echo "platform = ${PLATFORM_LIST}"
-	@echo ""
-	@echo "Please refer to the User Guide for a list of all supported options."
-	@echo "Note that the build system doesn't track dependencies for build "
-	@echo "options. Therefore, if any of the build options are changed "
-	@echo "from a previous build, a clean build must be performed."
-	@echo ""
-	@echo "Supported Targets:"
-	@echo "  all            Build all individual bootloader binaries"
-	@echo "  bl1            Build the BL1 binary"
-	@echo "  bl2            Build the BL2 binary"
-	@echo "  bl2u           Build the BL2U binary"
-	@echo "  bl31           Build the BL31 binary"
-	@echo "  bl32           Build the BL32 binary. If ARCH=aarch32, then "
-	@echo "                 this builds secure payload specified by AARCH32_SP"
-	@echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
-	@echo "  fip            Build the Firmware Image Package (FIP)"
-	@echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
-	@echo "  checkcodebase  Check the coding style of the entire source tree"
-	@echo "  checkpatch     Check the coding style on changes in the current"
-	@echo "                 branch against BASE_COMMIT (default origin/master)"
-	@echo "  clean          Clean the build for the selected platform"
-	@echo "  cscope         Generate cscope index"
-	@echo "  distclean      Remove all build artifacts for all platforms"
-	@echo "  certtool       Build the Certificate generation tool"
-	@echo "  enctool        Build the Firmware encryption tool"
-	@echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
-	@echo "  sp             Build the Secure Partition Packages"
-	@echo "  sptool         Build the Secure Partition Package creation tool"
-	@echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
-	@echo "  memmap         Print the memory map of the built binaries"
-	@echo "  doc            Build html based documentation using Sphinx tool"
-	@echo ""
-	@echo "Note: most build targets require PLAT to be set to a specific platform."
-	@echo ""
-	@echo "example: build all targets for the FVP platform:"
-	@echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
+	$(s)echo "usage: ${MAKE} [PLAT=<platform>] [OPTIONS] [TARGET]"
+	$(s)echo ""
+	$(s)echo "PLAT is used to specify which platform you wish to build."
+	$(s)echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
+	$(s)echo ""
+	$(s)echo "platform = ${PLATFORM_LIST}"
+	$(s)echo ""
+	$(s)echo "Please refer to the User Guide for a list of all supported options."
+	$(s)echo "Note that the build system doesn't track dependencies for build "
+	$(s)echo "options. Therefore, if any of the build options are changed "
+	$(s)echo "from a previous build, a clean build must be performed."
+	$(s)echo ""
+	$(s)echo "Supported Targets:"
+	$(s)echo "  all            Build all individual bootloader binaries"
+	$(s)echo "  bl1            Build the BL1 binary"
+	$(s)echo "  bl2            Build the BL2 binary"
+	$(s)echo "  bl2u           Build the BL2U binary"
+	$(s)echo "  bl31           Build the BL31 binary"
+	$(s)echo "  bl32           Build the BL32 binary. If ARCH=aarch32, then "
+	$(s)echo "                 this builds secure payload specified by AARCH32_SP"
+	$(s)echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
+	$(s)echo "  fip            Build the Firmware Image Package (FIP)"
+	$(s)echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
+	$(s)echo "  checkcodebase  Check the coding style of the entire source tree"
+	$(s)echo "  checkpatch     Check the coding style on changes in the current"
+	$(s)echo "                 branch against BASE_COMMIT (default origin/master)"
+	$(s)echo "  clean          Clean the build for the selected platform"
+	$(s)echo "  cscope         Generate cscope index"
+	$(s)echo "  distclean      Remove all build artifacts for all platforms"
+	$(s)echo "  certtool       Build the Certificate generation tool"
+	$(s)echo "  enctool        Build the Firmware encryption tool"
+	$(s)echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
+	$(s)echo "  sp             Build the Secure Partition Packages"
+	$(s)echo "  sptool         Build the Secure Partition Package creation tool"
+	$(s)echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
+	$(s)echo "  memmap         Print the memory map of the built binaries"
+	$(s)echo "  doc            Build html based documentation using Sphinx tool"
+	$(s)echo ""
+	$(s)echo "Note: most build targets require PLAT to be set to a specific platform."
+	$(s)echo ""
+	$(s)echo "example: build all targets for the FVP platform:"
+	$(s)echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
 
 .PHONY: FORCE
 FORCE:;
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index d25ec63..636aebe 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -116,6 +116,8 @@
     ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
         "BL1_RW_BASE address is not aligned on a page boundary.")
 
+    __RW_START__ = .;
+
     DATA_SECTION >RAM AT>ROM
 
     __DATA_RAM_START__ = __DATA_START__;
@@ -148,6 +150,8 @@
     } >RAM
 #endif /* USE_COHERENT_MEM */
 
+    __RW_END__ = .;
+
     __BL1_RAM_START__ = ADDR(.data);
     __BL1_RAM_END__ = .;
 
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index dbb646b..db0eafc 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -12,6 +12,7 @@
 				lib/cpus/${ARCH}/cpu_helpers.S		\
 				lib/cpus/errata_report.c		\
 				lib/el3_runtime/${ARCH}/context_mgmt.c	\
+				lib/locks/exclusive/${ARCH}/spinlock.S	\
 				plat/common/plat_bl1_common.c		\
 				plat/common/${ARCH}/platform_up_stack.S \
 				${MBEDTLS_SOURCES}
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 6fe5511..2b3a827 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <arch_helpers.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
@@ -39,31 +40,13 @@
 #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.
- ******************************************************************************/
-void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			meminfo_t *bl2_mem_layout)
-{
-	assert(bl1_mem_layout != NULL);
-	assert(bl2_mem_layout != NULL);
-
-	/*
-	 * Remove BL1 RW data from the scope of memory visible to BL2.
-	 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
-	 */
-	assert(BL1_RW_BASE > bl1_mem_layout->total_base);
-	bl2_mem_layout->total_base = bl1_mem_layout->total_base;
-	bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
-
-	flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
-}
-
-/*******************************************************************************
  * Setup function for BL1.
  ******************************************************************************/
 void bl1_setup(void)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl1_early_platform_setup();
 
@@ -94,7 +77,7 @@
 
 	/* Announce our arrival */
 	NOTICE(FIRMWARE_WELCOME_STR);
-	NOTICE("BL1: %s\n", version_string);
+	NOTICE("BL1: %s\n", build_version_string);
 	NOTICE("BL1: %s\n", build_message);
 
 	INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index 923a554..f12c1a5 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <bl1/bl1.h>
 #include <bl2/bl2.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
@@ -41,6 +42,9 @@
 void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 		   u_register_t arg3)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);
 
@@ -63,6 +67,9 @@
 void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 	       u_register_t arg3)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
 
@@ -92,7 +99,7 @@
 	PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_ENTRY, PMF_CACHE_MAINT);
 #endif
 
-	NOTICE("BL2: %s\n", version_string);
+	NOTICE("BL2: %s\n", build_version_string);
 	NOTICE("BL2: %s\n", build_message);
 
 	/* Perform remaining generic architectural setup in S-EL1 */
diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c
index fcb73b9..cd13def 100644
--- a/bl2u/bl2u_main.c
+++ b/bl2u/bl2u_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <bl1/bl1.h>
 #include <bl2u/bl2u.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/console.h>
@@ -27,7 +28,7 @@
  ******************************************************************************/
 void bl2u_main(void)
 {
-	NOTICE("BL2U: %s\n", version_string);
+	NOTICE("BL2U: %s\n", build_version_string);
 	NOTICE("BL2U: %s\n", build_message);
 
 #if SCP_BL2U_BASE
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 962c362..e47b082 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -450,7 +450,7 @@
 	 *
 	 * handler = (base + off) + (index << log2(size))
 	 */
-	adr	x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+	adr_l	x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
 	lsl	w10, w15, #RT_SVC_SIZE_LOG2
 	ldr	x15, [x11, w10, uxtw]
 
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index cd61d01..40add91 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -52,13 +52,17 @@
 				${SPMC_SOURCES}					\
 				${SPM_SOURCES}
 
+VENDOR_EL3_SRCS		+=	services/el3/ven_el3_svc.c
+
 ifeq (${ENABLE_PMF}, 1)
-BL31_SOURCES		+=	lib/pmf/pmf_main.c
+BL31_SOURCES		+=	lib/pmf/pmf_main.c				\
+				${VENDOR_EL3_SRCS}
 endif
 
 include lib/debugfs/debugfs.mk
 ifeq (${USE_DEBUGFS},1)
-	BL31_SOURCES	+= $(DEBUGFS_SRCS)
+BL31_SOURCES		+=	${DEBUGFS_SRCS}					\
+				${VENDOR_EL3_SRCS}
 endif
 
 ifeq (${PLATFORM_REPORT_CTX_MEM_USE},1)
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index c8cc2c7..83be0f6 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <bl31/bl31.h>
 #include <bl31/ehf.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/feat_detect.h>
 #include <common/runtime_svc.h>
@@ -83,7 +84,7 @@
 /*******************************************************************************
  * Simple function to initialise all BL31 helper libraries.
  ******************************************************************************/
-void __init bl31_lib_init(void)
+static void __init bl31_lib_init(void)
 {
 	cm_init();
 }
@@ -94,6 +95,9 @@
 void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 		u_register_t arg3)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl31_early_platform_setup2(arg0, arg1, arg2, arg3);
 
@@ -128,7 +132,7 @@
 	/* Init per-world context registers for non-secure world */
 	manage_extensions_nonsecure_per_world();
 
-	NOTICE("BL31: %s\n", version_string);
+	NOTICE("BL31: %s\n", build_version_string);
 	NOTICE("BL31: %s\n", build_message);
 
 #if FEATURE_DETECTION
@@ -211,8 +215,6 @@
 	 */
 	bl31_prepare_next_image_entry();
 
-	console_flush();
-
 	/*
 	 * Perform any platform specific runtime setup prior to cold boot exit
 	 * from BL31
@@ -220,9 +222,12 @@
 	bl31_plat_runtime_setup();
 
 #if ENABLE_RUNTIME_INSTRUMENTATION
-	PMF_CAPTURE_TIMESTAMP(bl_svc, BL31_EXIT, PMF_CACHE_MAINT);
 	console_flush();
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL31_EXIT, PMF_CACHE_MAINT);
 #endif
+
+	console_flush();
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*******************************************************************************
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index d14a91e..47a555a 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -36,7 +36,7 @@
 {
 	u_register_t hcr_el2 = read_hcr_el2();
 
-	return ((read_feat_vhe_id_field() != 0U) && ((hcr_el2 & HCR_TGE_BIT) != 0U));
+	return ((is_feat_vhe_present()) && ((hcr_el2 & HCR_TGE_BIT) != 0U));
 }
 
 /*
@@ -97,7 +97,7 @@
  * NOTE: This piece of code must be reviewed every release to ensure that
  * we keep up with new ARCH features which introduces a new SPSR bit.
  */
-static u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
 {
 	u_register_t new_spsr = 0;
 	u_register_t sctlr;
@@ -116,7 +116,7 @@
 
 	/* If FEAT_BTI is present, clear BTYPE bits */
 	new_spsr |= old_spsr & (SPSR_BTYPE_MASK_AARCH64 << SPSR_BTYPE_SHIFT_AARCH64);
-	if (is_armv8_5_bti_present()) {
+	if (is_feat_bti_present()) {
 		new_spsr &= ~(SPSR_BTYPE_MASK_AARCH64 << SPSR_BTYPE_SHIFT_AARCH64);
 	}
 
@@ -165,7 +165,7 @@
 
 	/* If FEAT_MTE2 is implemented mask tag faults by setting TCO bit */
 	new_spsr |= old_spsr & SPSR_TCO_BIT_AARCH64;
-	if (read_feat_mte_id_field() >= MTE_IMPLEMENTED_ELX) {
+	if (is_feat_mte2_present()) {
 		new_spsr |= SPSR_TCO_BIT_AARCH64;
 	}
 
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 5b78ebb..3a14635 100644
--- a/bl31/ehf.c
+++ b/bl31/ehf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -203,10 +203,20 @@
 	 * one stashed earlier if there are no more to deactivate.
 	 */
 	cur_pri_idx = get_pe_highest_active_idx(pe_data);
-	if (cur_pri_idx == EHF_INVALID_IDX)
+
+#if GIC600_ERRATA_WA_2384374
+	if (cur_pri_idx == EHF_INVALID_IDX) {
+		old_mask = plat_ic_deactivate_priority(pe_data->init_pri_mask);
+	} else {
+		old_mask = plat_ic_deactivate_priority(priority);
+	}
+#else
+	if (cur_pri_idx == EHF_INVALID_IDX) {
 		old_mask = plat_ic_set_priority_mask(pe_data->init_pri_mask);
-	else
+	} else {
 		old_mask = plat_ic_set_priority_mask(priority);
+	}
+#endif
 
 	if (old_mask > priority) {
 		ERROR("Deactivation priority (0x%x) lower than Priority Mask (0x%x)\n",
diff --git a/bl31/interrupt_mgmt.c b/bl31/interrupt_mgmt.c
index 68c7f10..a2b2c06 100644
--- a/bl31/interrupt_mgmt.c
+++ b/bl31/interrupt_mgmt.c
@@ -34,7 +34,7 @@
  *
  *           All other bits are reserved and SBZ.
  ******************************************************************************/
-typedef struct intr_type_desc {
+typedef struct {
 	interrupt_type_handler_t handler;
 	u_register_t scr_el3[2];
 	uint32_t flags;
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index 693dd4b..ba9d90d 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -118,8 +118,7 @@
 	mov	r1, r10
 	mov	r2, r11
 	mov	r3, r12
-	bl	sp_min_early_platform_setup2
-	bl	sp_min_plat_arch_setup
+	bl	sp_min_setup
 
 	/* Jump to the main function */
 	bl	sp_min_main
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 427e39b..b1f4343 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -13,16 +13,17 @@
 
 INCLUDES		+=	-Iinclude/bl32/sp_min
 
-BL32_SOURCES		+=	bl32/sp_min/sp_min_main.c		\
-				bl32/sp_min/aarch32/entrypoint.S	\
-				common/runtime_svc.c			\
-				plat/common/aarch32/plat_sp_min_common.c\
+BL32_SOURCES		+=	bl32/sp_min/sp_min_main.c			\
+				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	\
+				services/std_svc/std_svc_setup.c		\
 				${PSCI_LIB_SOURCES}
 
 ifeq (${ENABLE_PMF}, 1)
-BL32_SOURCES		+=	lib/pmf/pmf_main.c
+BL32_SOURCES		+=	services/el3/ven_el3_svc.c			\
+				lib/pmf/pmf_main.c
 endif
 
 ifneq (${ENABLE_FEAT_AMU},0)
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index 26cf207..a26910c 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <context.h>
@@ -170,12 +171,26 @@
 }
 
 /******************************************************************************
+ * The SP_MIN setup function. Calls platforms init functions
+ *****************************************************************************/
+void sp_min_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+		  u_register_t arg3)
+{
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
+	/* Perform early platform-specific setup */
+	sp_min_early_platform_setup2(arg0, arg1, arg2, arg3);
+	sp_min_plat_arch_setup();
+}
+
+/******************************************************************************
  * The SP_MIN main function. Do the platform and PSCI Library setup. Also
  * initialize the runtime service framework.
  *****************************************************************************/
 void sp_min_main(void)
 {
-	NOTICE("SP_MIN: %s\n", version_string);
+	NOTICE("SP_MIN: %s\n", build_version_string);
 	NOTICE("SP_MIN: %s\n", build_message);
 
 	/* Perform the SP_MIN platform setup */
diff --git a/bl32/sp_min/sp_min_private.h b/bl32/sp_min/sp_min_private.h
index 628581a..9c6b5fb 100644
--- a/bl32/sp_min/sp_min_private.h
+++ b/bl32/sp_min/sp_min_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,10 @@
 #ifndef SP_MIN_PRIVATE_H
 #define SP_MIN_PRIVATE_H
 
+#include <stdint.h>
+
+void sp_min_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+		  u_register_t arg3);
 void sp_min_main(void);
 void sp_min_warm_boot(void);
 void sp_min_fiq(void);
diff --git a/bl32/tsp/tsp_common.c b/bl32/tsp/tsp_common.c
index 908b4ff..3a6c9d9 100644
--- a/bl32/tsp/tsp_common.c
+++ b/bl32/tsp/tsp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,6 +66,9 @@
  ******************************************************************************/
 void tsp_setup(void)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup. */
 	tsp_early_platform_setup();
 
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 1c8c68f..8273060 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <arch_helpers.h>
 #include <bl32/tsp/tsp.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include "ffa_helpers.h"
 #include <lib/psci/psci.h>
@@ -554,7 +555,7 @@
 {
 	smc_args_t smc_args = {0};
 
-	NOTICE("TSP: %s\n", version_string);
+	NOTICE("TSP: %s\n", build_version_string);
 	NOTICE("TSP: %s\n", build_message);
 	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
 	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index d8031f9..ae38d69 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -12,6 +12,7 @@
 #include <arch_helpers.h>
 #include <bl32/tsp/tsp.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <lib/spinlock.h>
 #include <plat/common/platform.h>
@@ -27,7 +28,7 @@
  ******************************************************************************/
 uint64_t tsp_main(void)
 {
-	NOTICE("TSP: %s\n", version_string);
+	NOTICE("TSP: %s\n", build_version_string);
 	NOTICE("TSP: %s\n", build_message);
 	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
 	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
@@ -239,10 +240,10 @@
 	service_arg1 = (uint64_t)(service_args >> 64U);
 
 	/*
-	 * Write a dummy value to an MTE register, to simulate usage in the
+	 * Write a dummy value to an MTE2 register, to simulate usage in the
 	 * secure world
 	 */
-	if (is_feat_mte_supported()) {
+	if (is_feat_mte2_supported()) {
 		write_gcr_el1(0x99);
 	}
 
diff --git a/changelog.yaml b/changelog.yaml
index 5135d69..6a235cd 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -116,8 +116,11 @@
       - title: Memory Partitioning and Monitoring (MPAM) Extension (FEAT_MPAM)
         scope: mpam
 
-      - title: Memory Tagging Extension
-        scope: mte
+      - title: Memory Tagging Extension2
+        scope: mte2
+
+        deprecated:
+          - mte
 
       - title: Pointer Authentication Extension
         scope: pauth
@@ -149,11 +152,15 @@
       - title: Self-hosted Trace Extensions (FEAT_TRF)
         scope: trf
 
+      - title: DynamIQ Shared Unit (DSU)
+        scope: dsu
+
   - title: Platforms
     scope: platforms
 
     deprecated:
       - plat/common
+      - plat
 
     subsections:
       - title: Allwinner
@@ -212,25 +219,36 @@
           - title: N1SDP
             scope: n1sdp
 
-          - title: RD
-            scope: rd
+          - title: Neoverse-RD
+            scope: neoverse-rd
 
             subsections:
-              - title: RD-N1 Edge
+              - title: SGI-575
+                scope: sgi575
+
+              - title: RD-E1-Edge
+                scope: rde1edge
+
+              - title: RD-N1-Edge
                 scope: rdn1edge
 
+              - title: RD-V1
+                scope: rdv1
+
+              - title: RD-V1-MC
+                scope: rdv1mc
+
               - title: RD-N2
                 scope: rdn2
 
+              - title: RD-Fremont
+                scope: rdfremont
+
                 deprecated:
                   - board/rdn2
 
-          - title: SGI
-            scope: sgi
-
             deprecated:
-              - plat/sgi
-              - plat/arm/sgi
+              - neoverse
 
           - title: TC
             scope: tc
@@ -413,6 +431,9 @@
               - title: i.MX 8
                 scope: imx8
 
+              - title: i.MX 8ULP
+                scope: imx8ulp
+
               - title: i.MX 9
                 scope: imx9
 
@@ -496,6 +517,13 @@
                   - title: LS1088AQDS
                     scope: ls1088aqds
 
+          - title: S32G274A
+            scope: s32g274a
+
+            subsections:
+              - title: S32G274ARDB
+                scope: s32g274ardb
+
       - title: QEMU
         scope: qemu
 
@@ -636,12 +664,11 @@
               - plat/xilinx/versal
               - plat/versal
 
-            subsections:
-             - title: Versal NET
-               scope: versal-net
+          - title: Versal NET
+            scope: versal-net
 
-               deprecated:
-                 - versal_net
+            deprecated:
+              - versal_net
 
           - title: ZynqMP
             scope: zynqmp
@@ -650,6 +677,13 @@
               - plat/zynqmp
               - plat/xilinx/zynqmp
 
+      - title: AMD
+        scope: amd
+
+        subsections:
+          - title: Versal Gen 2
+            scope: versal2
+
       - title: Nuvoton
         scope: nuvoton
 
@@ -737,6 +771,9 @@
         deprecated:
           - errata_abi
 
+      - title: ChromeOS
+        scope: cros
+
   - title: Libraries
     scope: lib
 
@@ -804,6 +841,9 @@
         deprecated:
           - lib/psa
 
+      - title: DICE Protection Environment
+        scope: dice
+
       - title: Context Management
         scope: context-mgmt
 
@@ -816,6 +856,9 @@
       - title: Firmware Handoff
         scope: handoff
 
+      - title: Exception Handling Framework (EHF)
+        scope: ehf
+
   - title: Drivers
 
     subsections:
@@ -946,11 +989,12 @@
             deprecated:
               - drivers/arm/mhu
 
-          - title: RSS
-            scope: rss
+          - title: RSE
+            scope: rse
 
             deprecated:
               - drivers/arm/rss
+              - rss
 
           - title: TZC
             scope: tzc
@@ -1102,6 +1146,9 @@
           - title: TRDC
             scope: imx-trdc
 
+          - title: Clock
+            scope: nxp-clk
+
       - title: Renesas
         scope: renesas-drivers
 
@@ -1369,6 +1416,9 @@
       - title: Certificate Creation Tool
         scope: cert-create
 
+      - title: Firmware Encryption Tool
+        scope: encrypt-fw
+
       - title: Memory Mapping Tool
         scope: memmap
 
diff --git a/common/bl_common.c b/common/bl_common.c
index 8fce02f..2a9f32f 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/io/io_storage.h>
@@ -210,18 +211,18 @@
 {
 	int err;
 
-/*
- * All firmware banks should be part of the same non-volatile storage as per
- * PSA FWU specification, hence don't check for any alternate boot source
- * when PSA FWU is enabled.
- */
-#if PSA_FWU_SUPPORT
-	err = load_auth_image_internal(image_id, image_data);
-#else
-	do {
+	if ((plat_try_img_ops == NULL) || (plat_try_img_ops->next_instance == NULL)) {
 		err = load_auth_image_internal(image_id, image_data);
-	} while ((err != 0) && (plat_try_next_boot_source() != 0));
-#endif /* PSA_FWU_SUPPORT */
+	} else {
+		do {
+			err = load_auth_image_internal(image_id, image_data);
+			if (err != 0) {
+				if (plat_try_img_ops->next_instance(image_id) != 0) {
+					return err;
+				}
+			}
+		} while (err != 0);
+	}
 
 	if (err == 0) {
 		/*
@@ -275,6 +276,5 @@
  */
 const char *get_version(void)
 {
-	extern const char version[];
-	return version;
+	return build_version;
 }
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 7a2f0d7..8e3e3dd 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -70,37 +70,187 @@
 #endif
 }
 
-/****************************************************
- * Feature : FEAT_BTI (Branch Target Identification)
- ***************************************************/
-static void read_feat_bti(void)
+static unsigned int read_feat_rng_trap_id_field(void)
 {
-#if (ENABLE_BTI == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_5_bti_present(), "BTI");
-#endif
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
+			     ID_AA64PFR1_EL1_RNDR_TRAP_MASK);
 }
 
-/**************************************************
- * Feature : FEAT_RME (Realm Management Extension)
- *************************************************/
-static void read_feat_rme(void)
+static unsigned int read_feat_bti_id_field(void)
 {
-#if (ENABLE_RME == FEAT_STATE_ALWAYS)
-	feat_detect_panic((get_armv9_2_feat_rme_support() !=
-			ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
-#endif
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_BT_SHIFT,
+			     ID_AA64PFR1_EL1_BT_MASK);
 }
 
-/******************************************************************
- * Feature : FEAT_RNG_TRAP (Trapping support for RNDR/RNDRRS)
- *****************************************************************/
-static void read_feat_rng_trap(void)
+static unsigned int read_feat_sb_id_field(void)
 {
-#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_feat_rng_trap_present(), "RNG_TRAP");
-#endif
+	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT,
+			     ID_AA64ISAR1_SB_MASK);
 }
 
+static unsigned int read_feat_csv2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2_SHIFT,
+			     ID_AA64PFR0_CSV2_MASK);
+}
+
+static unsigned int read_feat_pmuv3_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT,
+			     ID_AA64DFR0_PMUVER_MASK);
+}
+
+static unsigned int read_feat_vhe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE_SHIFT,
+			     ID_AA64MMFR1_EL1_VHE_MASK);
+}
+
+static unsigned int read_feat_sve_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE_SHIFT,
+			     ID_AA64PFR0_SVE_MASK);
+}
+
+static unsigned int read_feat_ras_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS_SHIFT,
+			     ID_AA64PFR0_RAS_MASK);
+}
+
+static unsigned int read_feat_dit_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT_SHIFT,
+			     ID_AA64PFR0_DIT_MASK);
+}
+
+static unsigned int  read_feat_amu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU_SHIFT,
+			     ID_AA64PFR0_AMU_MASK);
+}
+
+static unsigned int read_feat_mpam_version(void)
+{
+	return (unsigned int)((((read_id_aa64pfr0_el1() >>
+		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
+			((read_id_aa64pfr1_el1() >>
+		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
+}
+
+static unsigned int read_feat_nv_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV_SHIFT,
+			     ID_AA64MMFR2_EL1_NV_MASK);
+}
+
+static unsigned int read_feat_sel2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2_SHIFT,
+			     ID_AA64PFR0_SEL2_MASK);
+}
+
+static unsigned int read_feat_trf_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT_SHIFT,
+			     ID_AA64DFR0_TRACEFILT_MASK);
+}
+static unsigned int get_armv8_5_mte_support(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_MTE_SHIFT,
+			     ID_AA64PFR1_EL1_MTE_MASK);
+}
+static unsigned int read_feat_rng_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR_SHIFT,
+			     ID_AA64ISAR0_RNDR_MASK);
+}
+static unsigned int read_feat_fgt_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT_SHIFT,
+			     ID_AA64MMFR0_EL1_FGT_MASK);
+}
+static unsigned int read_feat_ecv_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV_SHIFT,
+			     ID_AA64MMFR0_EL1_ECV_MASK);
+}
+static unsigned int read_feat_twed_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED_SHIFT,
+			     ID_AA64MMFR1_EL1_TWED_MASK);
+}
+
+static unsigned int read_feat_hcx_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX_SHIFT,
+			     ID_AA64MMFR1_EL1_HCX_MASK);
+}
+static unsigned int read_feat_tcr2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX_SHIFT,
+			     ID_AA64MMFR3_EL1_TCRX_MASK);
+}
+static unsigned int read_feat_s2pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE_SHIFT,
+			     ID_AA64MMFR3_EL1_S2PIE_MASK);
+}
+static unsigned int read_feat_s1pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE_SHIFT,
+			     ID_AA64MMFR3_EL1_S1PIE_MASK);
+}
+static unsigned int read_feat_s2poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE_SHIFT,
+			     ID_AA64MMFR3_EL1_S2POE_MASK);
+}
+static unsigned int read_feat_s1poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE_SHIFT,
+			     ID_AA64MMFR3_EL1_S1POE_MASK);
+}
+static unsigned int read_feat_brbe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE_SHIFT,
+			     ID_AA64DFR0_BRBE_MASK);
+}
+static unsigned int read_feat_trbe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER_SHIFT,
+			     ID_AA64DFR0_TRACEBUFFER_MASK);
+}
+static unsigned int read_feat_sme_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_SME_SHIFT,
+			     ID_AA64PFR1_EL1_SME_MASK);
+}
+static unsigned int read_feat_gcs_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS_SHIFT,
+			     ID_AA64PFR1_EL1_GCS_MASK);
+}
+
+static unsigned int read_feat_rme_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_FEAT_RME_SHIFT,
+			     ID_AA64PFR0_FEAT_RME_MASK);
+}
+
+static unsigned int read_feat_pan_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN_SHIFT,
+			     ID_AA64MMFR1_EL1_PAN_MASK);
+}
+
+static unsigned int read_feat_mtpmu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT,
+			     ID_AA64DFR0_MTPMU_MASK);
+
+}
+
 /***********************************************************************************
  * TF-A supports many Arm architectural features starting from arch version
  * (8.0 till 8.7+). These features are mostly enabled through build flags. This
@@ -139,7 +289,7 @@
 	 * revisions so that we catch them as they come along
 	 */
 	check_feature(FEAT_STATE_ALWAYS, read_feat_pmuv3_id_field(),
-		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P7);
+		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P8);
 
 	/* v8.1 features */
 	check_feature(ENABLE_FEAT_PAN, read_feat_pan_id_field(), "PAN", 1, 3);
@@ -151,6 +301,7 @@
 	check_feature(ENABLE_FEAT_RAS, read_feat_ras_id_field(), "RAS", 1, 2);
 
 	/* v8.3 features */
+	/* TODO: Pauth yet to convert to tri-state feat detect logic */
 	read_feat_pauth();
 
 	/* v8.4 features */
@@ -167,13 +318,12 @@
 		      "TRF", 1, 1);
 
 	/* v8.5 features */
-	check_feature(ENABLE_FEAT_MTE, read_feat_mte_id_field(), "MTE",
-		      MTE_IMPLEMENTED_EL0, MTE_IMPLEMENTED_ASY);
-	check_feature(ENABLE_FEAT_MTE2, read_feat_mte_id_field(), "MTE2",
+	check_feature(ENABLE_FEAT_MTE2, get_armv8_5_mte_support(), "MTE2",
 		      MTE_IMPLEMENTED_ELX, MTE_IMPLEMENTED_ASY);
 	check_feature(ENABLE_FEAT_RNG, read_feat_rng_id_field(), "RNG", 1, 1);
-	read_feat_bti();
-	read_feat_rng_trap();
+	check_feature(ENABLE_BTI, read_feat_bti_id_field(), "BTI", 1, 1);
+	check_feature(ENABLE_FEAT_RNG_TRAP, read_feat_rng_trap_id_field(),
+		      "RNG_TRAP", 1, 1);
 
 	/* v8.6 features */
 	check_feature(ENABLE_FEAT_AMUv1p1, read_feat_amu_id_field(),
@@ -204,8 +354,6 @@
 		      "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);
 	check_feature(ENABLE_FEAT_CSV2_3, read_feat_csv2_id_field(),
 		      "CSV2_3", 3, 3);
 
@@ -223,8 +371,7 @@
 
 	/* v9.4 features */
 	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
-
-	read_feat_rme();
+	check_feature(ENABLE_RME, read_feat_rme_id_field(), "RME", 1, 1);
 
 	if (tainted) {
 		panic();
diff --git a/docs/Makefile b/docs/Makefile
index 5bc24db..9fd7d76 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,11 +1,13 @@
 #
-# Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 # Minimal makefile for Sphinx documentation
 #
 
+include ../make_helpers/common.mk
+
 # You can set these variables from the command line.
 SPHINXOPTS    = -W
 SPHINXBUILD   = sphinx-build
@@ -13,20 +15,13 @@
 SOURCEDIR     = .
 BUILDDIR      = build
 
-V ?= 0
-ifeq ($(V),0)
-  Q := @
-else
-  Q :=
-endif
-
 # Put it first so that "make" without argument is like "make help".
 help:
-	${Q}$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+	$(q)$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 .PHONY: help Makefile
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
-	${Q}$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+.DEFAULT: Makefile
+	$(q)$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/about/features.rst b/docs/about/features.rst
index c12509d..9b7bdf9 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -128,7 +128,7 @@
 in a platform:
 
 -  MPU translation library ``lib/xlat_mpu``
--  RSS comms driver ``drivers/arm/rss``
+-  RSE comms driver ``drivers/arm/rse``
 
 Still to come
 -------------
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 4531a03..cbed72f 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -63,8 +63,8 @@
 :|G|: `bipinravi-arm`_
 :|M|: Joanna Farley <joanna.farley@arm.com>
 :|G|: `joannafarley-arm`_
-:|M|: Okash Khawaja <okash@google.com>
-:|G|: `bytefire`_
+:|M|: Jidong Sun <jidong@google.com>
+:|G|: `jidongsun`_
 :|M|: Varun Wadekar <vwadekar@nvidia.com>
 :|G|: `vwadekar`_
 :|M|: Yann Gautier <yann.gautier@st.com>
@@ -114,6 +114,8 @@
 :|M|: Marc Bonnici <marc.bonnici@arm.com>
 :|G|: `marcbonnici`_
 :|F|: services/std_svc/spm/el3_spmc/\*
+:|F|: include/services/el3_spmc\_\*
+:|F|: include/services/spmc_svc.h
 
 Secure Partition Manager Dispatcher (SPMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +123,13 @@
 :|G|: `odeprez`_
 :|M|: Joao Alves <Joao.Alves@arm.com>
 :|G|: `J-Alves`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
 :|F|: services/std_svc/spmd/\*
+:|F|: plat/common/plat_spmd_manifest.c
+:|F|: include/services/ffa_svc.h
+:|F|: include/services/el3_spmd_logical_sp.h
+:|F|: include/services/spmd_svc.h
 
 Exception Handling Framework (EHF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,6 +139,16 @@
 :|G|: `manish-pandey-arm`_
 :|F|: bl31/ehf.c
 
+Runtime Exceptions and Interrupt Management
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: bl31/aarch64/
+:|F|: bl31/interrupt_mgmt.c
+:|F|: include/bl31/interrupt_mgmt.h
+
 Realm Management Monitor Dispatcher (RMMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
@@ -216,12 +234,14 @@
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/psci/
+:|F|: include/lib/psci/
 
 DebugFS
 ^^^^^^^
 :|M|: Olivier Deprez <olivier.deprez@arm.com>
 :|G|: `odeprez`_
 :|F|: lib/debugfs/
+:|F|: include/lib/debugfs.h
 
 Firmware Configuration Framework (FCONF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,6 +252,10 @@
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/fconf/
+:|F|: plat/arm/common/fconf/
+:|F|: include/lib/fconf/
+:|F|: include/plat/arm/common/arm_fconf\_\*
+:|F|: include/plat/arm/common/fconf\_\*
 
 Performance Measurement Framework (PMF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -253,6 +277,7 @@
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/cpus/
+:|F|: include/lib/cpus/
 
 Reliability Availability Serviceabilty (RAS) framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -337,12 +362,12 @@
 :|F|: include/drivers/arm/mhu.h
 :|F|: drivers/arm/mhu
 
-Runtime Security Subsystem (RSS) comms driver
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Runtime Security Engine (RSE) comms driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: David Vincze <david.vincze@arm.com>
 :|G|: `davidvincze`_
-:|F|: include/drivers/arm/rss_comms.h
-:|F|: drivers/arm/rss
+:|F|: include/drivers/arm/rse_comms.h
+:|F|: drivers/arm/rse
 
 Libfdt wrappers
 ^^^^^^^^^^^^^^^
@@ -380,6 +405,8 @@
 :|M|: Manish Pandey <manish.pandey2@arm.com>
 :|G|: `manish-pandey-arm`_
 :|F|: services/std_svc/drtm
+:|F|: include/plat/common/plat_drtm.h
+:|F|: include/services/drtm_svc.h
 
 PSA Firmware Update
 ^^^^^^^^^^^^^^^^^^^
@@ -433,6 +460,32 @@
 :|F|: lib/transfer_list
 :|F|: include/lib/transfer_list.h
 
+Context Management
+^^^^^^^^^^^^^^^^^^
+:|M|: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
+:|G|: `jayanthchidanand-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: bl1/aarch32/bl1_context_mgmt.c
+:|F|: bl1/aarch64/bl1_context_mgmt.c
+:|F|: bl31/bl31_context_mgmt.c
+:|F|: lib/el3_runtime/
+:|F|: include/lib/el3_runtime/
+
+Runtime Services
+^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: services/std_svc/std_svc_setup.c
+:|F|: common/runtime_svc.c
+:|F|: include/common/runtime_svc.h
+:|F|: include/services/arm_arch_svc.h
+:|F|: include/services/std_svc.h
+
 Platform Ports
 ~~~~~~~~~~~~~~
 
@@ -524,13 +577,14 @@
 :|G|: `thomas-arm`_
 :|M|: Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com>
 :|G|: `vijayenthiran-arm`_
-:|F|: plat/arm/css/sgi/
-:|F|: plat/arm/board/rde1edge/
-:|F|: plat/arm/board/rdn1edge/
-:|F|: plat/arm/board/rdn2/
-:|F|: plat/arm/board/rdv1/
-:|F|: plat/arm/board/rdv1mc/
-:|F|: plat/arm/board/sgi575/
+:|M|: Rohit Mathew <Rohit.Mathew@arm.com>
+:|G|: `rohit-arm`_
+:|F|: plat/arm/board/neoverse_rd/common
+:|F|: plat/arm/board/neoverse_rd/platform/rdn1edge/
+:|F|: plat/arm/board/neoverse_rd/platform/rdn2/
+:|F|: plat/arm/board/neoverse_rd/platform/rdv1/
+:|F|: plat/arm/board/neoverse_rd/platform/rdv1mc/
+:|F|: plat/arm/board/neoverse_rd/platform/sgi575/
 
 Arm Total Compute platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -576,8 +630,6 @@
 
 MediaTek platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Rex-BC Chen <rex-bc.chen@mediatek.com>
-:|G|: `mtk-rex-bc-chen`_
 :|M|: Leon Chen <leon.chen@mediatek.com>
 :|G|: `leon-chen-mtk`_
 :|M|: Jason-CH Chen <jason-ch.chen@mediatek.com>
@@ -605,7 +657,6 @@
 :|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/
@@ -646,6 +697,13 @@
 :|F|: docs/plat/imx8m.rst
 :|F|: plat/imx/imx8m/
 
+NXP i.MX8ULP platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Jacky Bai <ping.bai@nxp.com>
+:|G|: `JackyBai`_
+:|F|: docs/plat/imx8ulp.rst
+:|F|: plat/imx/imx8ulp/
+
 NXP i.MX9 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Jacky Bai <ping.bai@nxp.com>
@@ -704,6 +762,16 @@
 :|F|: plat/nxp/soc-ls1088a/ls1088ardb
 :|F|: plat/nxp/soc-ls1088a/ls1088aqds
 
+NXP SoC Part S32G274A and its platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
+:|G|: `gprocopciucnxp`_
+:|F|: docs/plat/s32g274a.rst
+:|F|: drivers/nxp/clk/s32cc
+:|F|: drivers/nxp/console/linflex_console.S
+:|F|: include/drivers/nxp/console/linflex.h
+:|F|: plat/nxp/s32
+
 QEMU platform port
 ^^^^^^^^^^^^^^^^^^
 :|M|: Jens Wiklander <jens.wiklander@linaro.org>
@@ -794,10 +862,12 @@
 :|G|: `jwerner-chromium`_
 :|F|: plat/rockchip/
 
-STM32MP1 platform port
-^^^^^^^^^^^^^^^^^^^^^^
+STMicroelectronics platform ports
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Yann Gautier <yann.gautier@st.com>
 :|G|: `Yann-lms`_
+:|M|: Maxime Méré <maxime.mere@foss.st.com>
+:|G|: `meremST`_
 :|F|: docs/plat/st/*
 :|F|: docs/plat/stm32mp1.rst
 :|F|: drivers/st/
@@ -805,12 +875,15 @@
 :|F|: include/drivers/st/
 :|F|: include/dt-bindings/\*/stm32\*
 :|F|: plat/st/
+:|F|: tools/fiptool/plat_fiptool/st/
 :|F|: tools/stm32image/
 
 Synquacer platform port
 ^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Sumit Garg <sumit.garg@linaro.org>
 :|G|: `b49020`_
+:|M|: Masahisa Kojima <kojima.masahisa@socionext.com>
+:|G|: `masahisak`_
 :|F|: docs/plat/synquacer.rst
 :|F|: plat/socionext/synquacer/
 
@@ -947,94 +1020,101 @@
 :|G|: `CJKay`_
 :|F|: tools/conventional-changelog-tf-a
 
+.. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
+.. _Akshay-Belsare: https://github.com/Akshay-Belsare
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
+.. _amit-nagal: https://github.com/amit-nagal
 .. _andersdellien-arm: https://github.com/andersdellien-arm
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
+.. _anukou: https://github.com/anukou
+.. _arugan02: https://github.com/arugan02
+.. _arve-android: https://github.com/arve-android
+.. _avifishman: https://github.com/avifishman
+.. _b49020: https://github.com/b49020
+.. _BenjaminLimJL: https://github.com/BenjaminLimJL
 .. _bijucdas: https://github.com/bijucdas
+.. _bipinravi-arm: https://github.com/bipinravi-arm
 .. _bryanodonoghue: https://github.com/bryanodonoghue
-.. _b49020: https://github.com/b49020
+.. _jidongsun: https://github.com/jidongsun
 .. _carlocaione: https://github.com/carlocaione
+.. _chandnich: https://github.com/chandnich
+.. _ChiaweiW: https://github.com/chiaweiw
+.. _CJKay: https://github.com/cjkay
 .. _danh-arm: https://github.com/danh-arm
 .. _davidvincze: https://github.com/davidvincze
 .. _etienne-lms: https://github.com/etienne-lms
 .. _glneo: https://github.com/glneo
+.. _gprocopciucnxp: https://github.com/gprocopciucnxp
 .. _grandpaul: https://github.com/grandpaul
+.. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
+.. _hilamirandakuzi1: https://github.com/hilamirandakuzi1
 .. _hzhuang1: https://github.com/hzhuang1
 .. _JackyBai: https://github.com/JackyBai
+.. _J-Alves: https://github.com/J-Alves
+.. _jason-ch-chen: https://github.com/jason-ch-chen
+.. _javieralso-arm: https://github.com/javieralso-arm
+.. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
 .. _jcorbier: https://github.com/jcorbier
 .. _jenswi-linaro: https://github.com/jenswi-linaro
+.. _JiafeiPan: https://github.com/JiafeiPan
+.. _jimmy-brisson: https://github.com/theotherjimmy
+.. _joannafarley-arm: https://github.com/joannafarley-arm
 .. _jslater8: https://github.com/jslater8
 .. _jwerner-chromium: https://github.com/jwerner-chromium
 .. _kostapr: https://github.com/kostapr
 .. _lachitp: https://github.com/lachitp
+.. _laurenw-arm: https://github.com/laurenw-arm
+.. _leon-chen-mtk: https://github.com/leon-chen-mtk
+.. _linyidi: https://github.com/linyidi
+.. _madhukar-Arm: https://github.com/madhukar-Arm
+.. _manish-pandey-arm: https://github.com/manish-pandey-arm
+.. _ManishVB-Arm: https://github.com/ManishVB-Arm
+.. _marcbonnici: https://github.com/marcbonnici
+.. _marcone: https://github.com/marcone
+.. _mardyk01: https://github.com/mardyk01
 .. _marex: https://github.com/marex
 .. _masahir0y: https://github.com/masahir0y
+.. _masahisak: https://github.com/masahisak
+.. _max-shvetsov: https://github.com/max-shvetsov
+.. _meremST: https://github.com/meremST
 .. _michalsimek: https://github.com/michalsimek
 .. _mmind: https://github.com/mmind
 .. _MrVan: https://github.com/MrVan
-.. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
-.. _leon-chen-mtk: https://github.com/leon-chen-mtk
-.. _jason-ch-chen: https://github.com/jason-ch-chen
-.. _linyidi: https://github.com/linyidi
+.. _Neal-liu: https://github.com/neal-liu
 .. _niej: https://github.com/niej
+.. _nmenon: https://github.com/nmenon
 .. _npoushin: https://github.com/npoushin
+.. _odeprez: https://github.com/odeprez
+.. _pangupta: https://github.com/pangupta
 .. _prabhakarlad: https://github.com/prabhakarlad
 .. _quic_mkf: https://github.com/quicmkf
+.. _raghuncstate: https://github.com/raghuncstate
+.. _raymo200915: https://github.com/raymo200915
 .. _remi-triplefault: https://github.com/repk
 .. _rockchip-linux: https://github.com/rockchip-linux
+.. _rohit-arm: https://github.com/rohit-arm
+.. _rupsin01: https://github.com/rupsin01
+.. _rutigl: https://github.com/rutigl
 .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm
 .. _sgorecha: https://github.com/sgorecha
 .. _shawnguo2: https://github.com/shawnguo2
+.. _sieumunt: https://github.com/sieumunt
 .. _smaeul: https://github.com/smaeul
 .. _soby-mathew: https://github.com/soby-mathew
 .. _sreekare: https://github.com/sreekare
 .. _stefanasimion: https://github.com/stefanasimion
 .. _stephan-gh: https://github.com/stephan-gh
-.. _sieumunt: https://github.com/sieumunt
-.. _BenjaminLimJL: https://github.com/BenjaminLimJL
 .. _thomas-arm: https://github.com/thomas-arm
 .. _TonyXie06: https://github.com/TonyXie06
 .. _TravMurav: https://github.com/TravMurav
-.. _vwadekar: https://github.com/vwadekar
-.. _Yann-lms: https://github.com/Yann-lms
-.. _manish-pandey-arm: https://github.com/manish-pandey-arm
-.. _mardyk01: https://github.com/mardyk01
-.. _odeprez: https://github.com/odeprez
-.. _bipinravi-arm: https://github.com/bipinravi-arm
-.. _joannafarley-arm: https://github.com/joannafarley-arm
-.. _ManishVB-Arm: https://github.com/ManishVB-Arm
-.. _max-shvetsov: https://github.com/max-shvetsov
-.. _javieralso-arm: https://github.com/javieralso-arm
-.. _laurenw-arm: https://github.com/laurenw-arm
-.. _J-Alves: https://github.com/J-Alves
-.. _madhukar-Arm: https://github.com/madhukar-Arm
-.. _raghuncstate: https://github.com/raghuncstate
-.. _CJKay: https://github.com/cjkay
-.. _nmenon: https://github.com/nmenon
-.. _anukou: https://github.com/anukou
-.. _chandnich: https://github.com/chandnich
-.. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
-.. _vishnu-banavath: https://github.com/vishnu-banavath
-.. _vijayenthiran-arm: https://github.com/vijayenthiran-arm
-.. _arugan02: https://github.com/arugan02
 .. _uarif1: https://github.com/uarif1
-.. _pangupta: https://github.com/pangupta
-.. _JiafeiPan: https://github.com/JiafeiPan
-.. _arve-android: https://github.com/arve-android
-.. _marcone: https://github.com/marcone
-.. _marcbonnici: https://github.com/marcbonnici
-.. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
-.. _bytefire: https://github.com/bytefire
-.. _rupsin01: https://github.com/rupsin01
-.. _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
+.. _vijayenthiran-arm: https://github.com/vijayenthiran-arm
+.. _vishnu-banavath: https://github.com/vishnu-banavath
+.. _vwadekar: https://github.com/vwadekar
 .. _xueliang-zhong-arm: https://github.com/xueliang-zhong-arm
-.. _raymo200915: https://github.com/raymo200915
-.. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
+.. _Yann-lms: https://github.com/Yann-lms
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 654d65f..7fafe03 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -68,6 +68,8 @@
 +-----------------+---------------------------+------------------------------+
 | v2.10           | 4th week of Nov '23       | 2nd week of Nov '23          |
 +-----------------+---------------------------+------------------------------+
+| v2.11           | 4th week of May '24       | 2nd week of May '24          |
++-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
 --------------------------------
@@ -81,9 +83,7 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| Mbedtls-2.x                    |     2.10    |   2.10  | Support for TF-A builds with Mbedtls-2.x will be removed|
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| STM32MP15_OPTEE_RSV_SHM        |     2.10    |   3.0   | OP-TEE manages its own memory on STM32MP15              |
+|                                |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 Removal of Deprecated Drivers
@@ -101,6 +101,19 @@
 | None at this time.             |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
+Build Options deprecated/removed
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Populated table provides details about build options that were removed or deprecated.
+
++-----------------------+--------------------------------+
+| Build Option          | Deprecated from TF-A Version   |
++=======================+================================+
+| CTX_INCLUDE_MTE_REGS  | 2.11                           |
++-----------------------+--------------------------------+
+| ENABLE_FEAT_MTE       | 2.11                           |
++-----------------------+--------------------------------+
+
 --------------
 
-*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/change-log.md b/docs/change-log.md
index cfc8c56..1e6647f 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,924 @@
 This document contains a summary of the new features, changes, fixes and known
 issues in each release of Trusted Firmware-A.
 
+## [2.11.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.10.0..refs/tags/v2.11.0) (2024-05-17)
+
+### âš  BREAKING CHANGES
+
+- **Architecture**
+
+  - **Memory Tagging Extension2**
+
+    - Any platform or downstream code trying to use
+      SCR_EL3.ATA bit(26) will see failures as this is now moved to be
+      used only with FEAT_MTE2 with
+      commit@ef0d0e5478a3f19cbe70a378b9b184036db38fe2
+
+      **See:** remove mte, mte_perm ([c282384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c282384dbb45b6185b4aba14efebbad110d18e49))
+
+- **Services**
+
+  - **SPM**
+
+    - **SPMD**
+
+      - Given the optimizations made in TF-A SPMD to simplify NS EL1 context
+        management, platform integrators must use SPMC binaries built by
+        picking commits after 2fc6dcfa97e05159f95859fcf68db3031586f8c7 from
+        hafnium repository.
+
+        **See:** skip NS EL1 context save & restore operations ([2d960a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d960a11601be6e7f24c38d84b2a4fdbb52efb9b))
+
+- **Drivers**
+
+  - **Arm**
+
+    - **RSE**
+
+      - remove PLAT_RSS_NOT_SUPPORTED build option
+
+        **See:** remove PLAT_RSS_NOT_SUPPORTED build option ([878354a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/878354a845cbc51c198b879d3d92ed472e21889c))
+
+  - **FWU**
+
+    - add a config flag for including image info in the FWU metadata ([11d05a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11d05a77295885f27530cf07029ebc2b36f49918))
+    - add a function to obtain an alternate FWU bank to boot ([26aab79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/26aab79560a2281c4207b01102495459c2bddefc))
+    - add some sanity checks for the FWU metadata ([d2566cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2566cfb896672ea07c31c37e7acd9ef77abc4fb))
+    - document the config flag for including image info in the FWU metadata ([7ae1619](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ae16196cc73a580f298734bb98f2ccb210e3ba9))
+    - migrate FWU metadata structure to version 2 ([a89d58b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a89d58bb204c00db260225859bce0b55aa5e2385))
+
+### New Features
+
+- **Architecture**
+
+  - **CPU feature / ID register handling in general**
+
+    - add cortex-a35 l2 extended control register ([a727d59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a727d59d9c1ef5ecf2f221ce289506da2011dda1))
+    - add feature detection for FEAT_CSV2_3 ([30019d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30019d8698b219d4a642dc59e7178006f59654ff))
+    - added few helper functions ([30f05b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30f05b4f5db605ddc1a3ca0ae0cbd13ed0e728b6))
+
+  - **DynamIQ Shared Unit (DSU)**
+
+    - save/restore DSU PMU register ([f99a69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f99a69c386ce5448edfc47eaf146d1a20ac8216e))
+
+  - **Memory Tagging Extension2**
+
+    - add mte2 feat ([8e39788](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e3978899a481484d8c60bf276be503aebd43afb))
+
+- **Platforms**
+
+  - update SZ_* macros ([6d511a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d511a8c31f0d792695566ae75c8f7b08b3b7236))
+
+  - **Arm**
+
+    - add COT_DESC_IN_DTB option for CCA CoT ([b76a43c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b76a43c9382e85969cac896cd4d5d6774d0d1553))
+    - add trusty_sp_fw_config build option ([0686a01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0686a01b0cacb9aab840a5c334409b5739a95a97))
+    - move GPT setup to common BL source ([341df6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/341df6af6eb911ffd175e129f61fc59efcf9fcea))
+    - retrieve GPT related data from platform ([86e4859](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86e4859a05614b40ff3cf38f8bd4efc856c546fe))
+    - support FW handoff b/w BL1 & BL2 ([9c11ed7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c11ed7e3e5536ad1fcb9190560e0368da9c5ab5))
+    - support FW handoff b/w BL2 & BL31 ([a5566f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5566f65fd1be689ca5c63baa1f5b61b40960c8d))
+    - add platform API that gets cluster ID ([e6ae019](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6ae019a84c4d2ad2d2825b32fbcbe304752e3ae))
+
+    - **CSS**
+
+      - initialise generic timer early in the boot ([3447ba1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3447ba1f0405a8590ec31e4b79737efe151c3d5b))
+
+    - **FVP**
+
+      - add CCA CoT in DTB support ([4c79b86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c79b86ed6a36b572cf9e96f0269eb5dd0b46d5f))
+      - add stdout-path ([8c30a0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c30a0c7fe0162de0618b26fb34cc91ea582e5f7))
+      - add support for virto-net, virtio-9p and virtio-rng ([51b8b9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51b8b9c3c46cec87ebb7b484727c80ff29d73057))
+      - added calls to unprotect/protect memory ([6873088](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6873088c2cd6983025b6777d4c3bde912eade571))
+      - delegate FFH RAS handling to SP ([d07d4d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d07d4d63374b0d155b9281f9fcaf6b44f18117c8))
+      - remove left-over RSS usage ([a1726fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1726fa7ffecdcc8f8f4d09bd0bdc97ef3b72f11))
+
+    - **Neoverse-RD**
+
+      - add scope for RD-V1 ([86a4949](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86a4949fd012a9912c8bf909d14e20657bba2240))
+      - add scope for RD-V1-MC ([6fb16da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6fb16dac6e6672040ec80f85f2f337f52cf3f3d3))
+      - add scope for SGI-575 ([18b5070](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18b50707f7732a8b3deb46d8d011566199711c0b))
+      - disable SPMD_SPM_AT_SEL2 for A75/V1/N1 platforms ([b9c3273](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9c32730e5b7efe5170ed3c0dda7ab9db397c478))
+      - disable SPMD_SPM_AT_SEL2 for N2/V2 platforms ([301c017](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/301c01748ea717d0f2cf3ba1f0a2fe389b6fb155))
+      - enable AMU if supported by the platform ([fed9368](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fed9368529e5bc2c9111ac5a743688166661fd8f))
+      - remove unused SGI_PLAT build-option ([2d32517](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d32517ce64886f154c6d509f80d0fcde05dc498))
+
+      - **SGI-575**
+
+        - remove SGI-575 from deprecated list ([f104eec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f104eecdea209af87de43c62811a0a9456f2838c))
+
+      - **RD-E1-Edge**
+
+        - remove support for RD-E1-Edge ([c69253c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69253cc3ad3063380c8f905125fe85f6d942d09))
+
+      - **RD-N1-Edge**
+
+        - remove RD-N1-Edge from deprecated list ([78b7939](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/78b793956f3a86a3dd62394c858ae9ee41379b8b))
+
+      - **RD-N2**
+
+        - enable NEOVERSE_Nx_EXTERNAL_LLC flag ([ab2b363](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab2b3632171dd5488952ba3f68693e490857e9dc))
+        - add dts for secure partition ([49df726](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49df7261be44d5199a930c95667edb6b878355d1))
+        - enable AMU if present on the platform ([2cfedfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2cfedfad9c2c59316adf17d4f0ee561b50a041b6))
+        - enable MTE2 if present on the platform ([3a5b375](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a5b3753033561cb5d7cd7aace634cc66eab0fa7))
+        - update power message value to 0 ([08f6398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/08f6398b2b9566812cd110498e3135dfc2e3e494))
+
+    - **TC**
+
+      - add arm_ffa node in dts ([4fc4e9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fc4e9c969930d83f1144441199301d3b4b34a5a))
+      - add DPE backend to the measured boot framework ([e7f1181](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7f1181f8a7729acb07ebac86944e36932bcd09e))
+      - add DPE context handle node to device tree ([1f47a71](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f47a7133f7fe7fb038aca97fc93533964b2b429))
+      - add dummy TRNG support to be able to boot pVMs ([7be391d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7be391d1ce5683c717fcf2be584f3d294ebc2bf3))
+      - add firmware update secure partition ([d062872](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0628728a627ee11c97839640d404221a74c3a65))
+      - add memory node in the device tree ([5ee4deb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ee4deb8e69175f57fa51519ef37e3674aa6b9a0))
+      - add PMU entry ([553b06b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/553b06b5d4f7ec8e49796e0ffdf081bf5cf30d53))
+      - add RSS SDS region right after SCMI payload ([6f503e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6f503e0eea23a2663ed5cbfe9b925e1e0d65c236))
+      - add save/restore DSU PMU register support ([b87d7ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b87d7ab13f4b03f872c3c4a3dd7c755baf3a38d3))
+      - add SCMI power domain and IOMMU toggles ([a658b46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a658b46dc74ceaa51d119bd7bd9eccdefb0cc455))
+      - add spmc manifest with trusty sp ([ba197f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba197f5f708fe8e033971c6f4d5b25f6783aaa45))
+      - add TC3 platform definitions ([62320dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62320dc4fd2c13d9f4b227fe73cad2a79bdba42c))
+      - allow booting from DRAM ([18f754a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18f754a275083ea66823b1c9f39e234cf430140e))
+      - choose the DPU address and irq based on the target ([8e94163](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e94163ec041f2d7df41c2dfd8625c06655ba08e))
+      - enable gpu/dpu scmi power domain and also gpu perf domain ([127eabe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/127eabeddfc4fb596a1b499fe68ee6f7e5b5b6d5))
+      - factor in FVP/FPGA differences ([1b8ed09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b8ed0993fc5c04f76d949df7e2851e67040bbf9))
+      - get the parent component provided DPE context_handle ([467bdf2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/467bdf26b64a38cfbfb3bf8ab915eb97eb6b3037))
+      - group components into certificates ([6df8d76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6df8d7647dad5c347d363554d25e590d24eb05e5))
+      - interrupt numbers for `smmu_700` ([2c406dd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c406ddaf700e0f1c80535e309a2245b9e0bee92))
+      - introduce an FPGA subvariant and TC3 CPUs ([a02bb36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a02bb36caa521259ae57a904dedb7fd4e6a51340))
+      - pass the DTB address to BL33 in R0 ([638e4a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/638e4a92d80346b4d46ef2cc5fbb7941d1b7fd31))
+      - provide a mock mbedtls-random generation function ([a877818](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8778185d2fd2b80cee8af7879ecb92be1aa3898))
+      - share DPE context handle with child component ([03d388d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03d388d8e3eb5c6cce65afba060a16fae83d4d12))
+
+  - **Intel**
+
+    - add in QSPI ECC for Linux ([4d122e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d122e5f199ad1531650ae11de5121057cfc0855))
+    - enable query of fip offset on RSU ([6cbe2c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cbe2c5d19c4af0ba6bbba049962bf55454da8bb))
+    - enable SDMMC frontdoor load for ATF->Linux ([32a87d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32a87d440087e0a71765a61ec341af7cfcfbda97))
+    - increase bl2 size limit ([2d46b2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d46b2e46189120b6779cd27ec6bd6ec9901f72c))
+    - restructure watchdog ([47ca43b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47ca43bcb4565a992bf527f68e1ff60fc036fd12))
+    - support QSPI ECC Linux for Agilex ([d6ae69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6ae69c8c69016d05d64752538aad53f319b88a2))
+    - support QSPI ECC Linux for N5X ([6cf16b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cf16b36821b9f2a60ed9abbaa593ef62b8b9f2b))
+    - support QSPI ECC Linux for Stratix10 ([8be16e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8be16e44cf0143e8651090d80bd14194aa78b1f2))
+    - support query of fip offset using RSU ([62be2a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62be2a1ae3efcba0bb8b7ec8ef73b2a0f5a437e3))
+    - support SDM mailbox safe inject seu error for Linux ([fffcb25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fffcb25c3c2171624c582d92173154f570708a9a))
+    - support wipe DDR after calibration ([68bb3e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68bb3e836e93b271f9f1c05787025dd3f04dd788))
+
+  - **MediaTek**
+
+    - remove bl32 flag for mtk_bl ([9c41cc1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c41cc182dd7acf541565ab3df7a4261fb7eaf1b))
+
+    - **MT8188**
+
+      - add secure iommu support ([5fb5ff5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fb5ff5694c1bcf0ddfc972600b69d7494ca6645))
+      - remove apusys kernel handler usage constraints ([0c77651](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c77651fb47c7ffd4b1b37a74aea77373179ab5d))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - add 3600 MTps DDR PLL rate ([f1bb459](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1bb459c3192eb6b3fc6b9b77658d82227eae2d5))
+        - add defines for csu_sa access security ([81de503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81de50372c9192098118fc8bddaf086a620add87))
+        - add imx csu_sa enum type defines for imx8m ([2ac4909](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2ac4909a5ec0a50a75cab9bb587fb1b8e592794d))
+        - make bl33 start configurable via PRELOADED_BL33_BASE ([9260a8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9260a8c818aadbf513b2744cad978c18d0f65a8e))
+        - obtain boot image set for imx8mn/mp ([6d2c502](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d2c502afb845e7af94c610ab5a375b868c885ba))
+
+        - **i.MX 8M Mini**
+
+          - restrict peripheral access to secure world ([1156c76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1156c76361c170c83c6b9a9dd7c22aa401a4ce2e))
+          - set and lock almost all peripherals as non-secure ([f4b11e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4b11e59b81af3e485e6992b10b50b362902eee1))
+
+        - **i.MX 8M Plus**
+
+          - restrict peripheral access to secure world ([0324081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0324081af0105af536992c8ced2caa5a1928010f))
+          - set and lock almost all peripherals as non-secure ([cba7daa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cba7daa10576684670e06d05ff02888a5b4f16bf))
+
+        - **i.MX 8Q**
+
+          - detect console base address during runtime ([52ee817](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52ee8173041c46aafcfa43f004029dddbfa9f9b5))
+
+      - **i.MX 8ULP**
+
+        - add a flag check for the ddr status ([4fafccb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fafccb9a8f7b35406b08743f6d9c9b519b01c61))
+        - add APD power down mode(PD) support in system suspend ([478af8d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/478af8d3c34576793a820733ddba6449c2cf2fac))
+        - add i.MX8ULP basic support ([fcd41e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fcd41e8692ce8e8fc98d069bc131820cbf83c55c))
+        - add memory region policy ([5fd0642](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fd06421f8bf9f5b67e73828281534f14f302630))
+        - add OPTEE support ([e7b82a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7b82a7d2fa1fc3f32724e6836b8f6078d20c103))
+        - add some delay before cmc1 access ([c514d3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c514d3cfa7640313c4d78674df9d7cbe9227420b))
+        - add system power off support ([891c547](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/891c547e9658c1827559d8da5e3b87de5a2e9f6a))
+        - add the basic support for idle & system suspned ([daa4478](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/daa4478a3cb2f86501c37e5a301cd4d6a6e60ee6))
+        - add the initial XRDC support ([ac5d69b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac5d69b628736f66f72e99532656105fdc07a3fe))
+        - add trusty support ([e853041](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e853041920b15b77839027ab802d0cd9a08c7c35))
+        - adjust the dram mapped region ([8d50c91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d50c91b476474cc403c30eb6de6af28cb246e5a))
+        - adjust the voltage when sys dvfs enabled ([416c443](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/416c4433f0047a86165e450e60f93020c561151b))
+        - allocated caam did for the non secure world ([7c5eedc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c5eedca4c7f176448e6b92eb5c22ee2ea45e70a))
+        - allow RTD to reset APD through MU ([ea1f7a2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea1f7a2e109181f19f5bdeb71533e7dfda753df7))
+        - ddrc switch auto low power and software interface ([ee25e6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ee25e6a51bf20c92471e737ccba98af4a74d1383))
+        - enable 512KB cache after resume on imx8ulp ([bcca70b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcca70b9688c5effa0731f39e2b209071f54be2c))
+        - enable the DDR frequency scaling support ([caee273](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/caee2733ba4e7a09ea656b0be85f150a275cc57c))
+        - give HIFI4 DSP access to more resources ([351976b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/351976bb063cca7866e214a6bda9302f9ab018b3))
+        - not power off LPAV PD when LPAV owner is RTD ([ab787db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab787dba7726bdf58c15626e5cc9a3525aade8a3))
+        - protect TEE region for secure access only ([ff5e179](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff5e1793b95ed4297deae72cdb665178e6e72e44))
+        - update the upower config for power optimization ([36af80c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36af80c2b420cb32ff57273eda0d7d0e93b49153))
+        - update XRDC for ELE to access DDR with CA35 DID ([d159c00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d159c00532afe50686dd92215de9b420d60502f6))
+
+    - **S32G274A**
+
+      - add S32G274ARDB2 board support ([8b81a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b81a39e28a087e1123271a42c04a7ce3b496a58))
+      - enable BL31 stage ([e73c3c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e73c3c3a6cbc1e81de4c9d73a5d713e6b37ae3b2))
+
+  - **QEMU**
+
+    - allow ARM_ARCH_MAJOR/MINOR override ([e769f83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e769f830d3116f49ed82769d9d731c4dca8f6188))
+    - enable FEAT_ECV when present ([1b694c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b694c77c497cb8272c97417ef1fa4f5f9c869c1))
+    - enable transfer list to BL31/32 ([305825b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/305825b490a77e5b0ee816ea29c53bc6444a1d63))
+    - load and run RMM image ([8ffe0b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ffe0b2edea6b00c9fe7d9ecaeca43c734d3764d))
+    - setup Granule Protection Table ([6cd113f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cd113fe06fdaa67a8457391eb6bcffd295f87fd))
+    - setup memory map for RME ([cd75693](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd75693f5ed303c1366fdff9b392d766848b6b67))
+    - support TRP for RME ([ebe82a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ebe82a392f06aa0adddf9cc5caa7af8f561b2fb4))
+    - update mapping types for RME ([a5ab1ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5ab1ef7febb2dc931cd8f7fcd76caac04d628cd))
+    - update to manifest v0.3 ([762a1c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/762a1c44b985b71495a90bc3484b576d28c8511a))
+    - use mock attestation functions for RME ([c69e95e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69e95eed0491b481971b48f5df855402ed5392a))
+
+    - **SBSA**
+
+      - handle CPU information ([42925c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42925c15bee09162c6dfc8c2204843ffac6201c1))
+      - handle memory information ([8b7dd83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b7dd8397dd017b61ecda8447e8956a1d9d6d5d3))
+      - mpidr needs to be present ([4fc54c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fc54c99d08926c2d42173902c8aaf3862722c84))
+
+  - **Raspberry Pi**
+
+    - add Raspberry Pi 5 support ([f834b64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f834b64f889c1c4e03e590d44a6a52e3ac79cf42))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - **R-Car 3**
+
+        - add cache operations to boot process ([7e06b06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e06b06753b12d567b6f48b6e60d6d0a56cf72e5))
+        - change CAM setting to improve bus latency of R-Car Gen3 ([e366f8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e366f8cf3349189daafb7ac2ab74d98931757a60))
+        - change MMU configurations ([5e8c2d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e8c2d8e23ca0760bca7e5b692ee95dd2871ec89))
+        - enable the stack protection ([cfa466a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfa466ab733ff021771b94b4a98d22bfdd246139))
+        - update IPL and Secure Monitor Rev.4.0.0 ([516a98e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/516a98ef277626aa1858d9a4018d13ab2aeb39e7))
+
+  - **ST**
+
+    - add a function to clear the FWU trial state counter ([6e99fee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e99fee43efa256bdac3b38864206c94bd9ae3c8))
+    - add logic to boot the platform from an alternate bank ([6166051](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6166051426638087b5433eff1739d26478313dff))
+    - do not directly call BSEC functions in common code ([3007c72](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3007c72844c72e0911721e499dbab37b3eca1cdc))
+    - get the state of the active bank directly ([588b01b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/588b01b5e4726cd4a6d235e9f566a546ef17f631))
+    - use stm32_get_otp_value_from_idx() in BL31 ([189db94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/189db9486ddd949f279faa970bfc1dd9cc0e3623))
+
+    - **STM32MP1**
+
+      - only fuse monotonic counter on closed devices ([d6bb94f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6bb94f3a14ddbcf44c667134ed302eff054954c))
+
+    - **STM32MP2**
+
+      - add BSEC and OTP support ([197ac78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/197ac780d73c3421c4643e0bc02d112ceffd248f))
+      - add ddr-fw parameter for fiptool ([e494afc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e494afc05f8562455e09b4f131f2699990a744f8))
+      - add plat_my_core_pos ([d1c85da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d1c85da8ef23a99387823272b03399a07e3a00da))
+      - add STM32MP_USB_PROGRAMMER compilation ([2e905c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e905c0682b4e6d2cfdbd42e41f6097b16967ff5))
+      - put back core 1 in wfi after debugger's halt ([2331a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2331a34f783b29a9a1fe86f5142d0a359cacb259))
+      - use early traces ([47ea303](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47ea303389f6d0ac81617366973ece9d93dc49c9))
+
+  - **Xilinx**
+
+    - add handler for power down req sgi irq ([ade92a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ade92a64e4d2fbb5f246e6ad891465d10e0d9b26))
+    - add new state to identify cpu power down ([5949701](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5949701600c7f3c3a6589d0efd743615156c34b6))
+    - add wrapper to handle cpu power down req ([3dd118c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3dd118cf9d60e1eab97af505eb63a2cdc044d747))
+    - power down all cores on receiving cpu pwrdwn req ([c3280df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3280df1bb95ed09b5d5f91f8977bbe99c6a923b))
+    - request cpu power down from reset ([88ee081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88ee0816a7429689890659f69b895ac84e48f141))
+    - send SGI to mailbox driver ([9a7f892](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a7f892e29ea81c67f6f6b1342a367234e125b63))
+
+    - **Versal**
+
+      - enable errata management feature ([d766f99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d766f994d2bd00c538f66e95686fc47b45ccbdb9))
+      - extend platform address space sizes ([663f024](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/663f024f207bddb7b80167e661c094d77955e292))
+
+      - **Versal NET**
+
+        - add bufferless IPI Support ([511e4a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/511e4a48ccd5e74af338041be238f5df12fffe3e))
+
+    - **ZynqMP**
+
+      - remove unused pm_get_proc_by_node() ([b03ba48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b03ba4801d39da1d5acc7a58d9c7736e57efc099))
+
+- **Bootloader Images**
+
+  - **BL32**
+
+    - create an sp_min_setup function ([a1255c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1255c758593f9f6fb85b70165fad21de7491e1e))
+
+- **Services**
+
+  - **FF-A**
+
+    - update FF-A version to v1.2 ([e830e4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e830e4cdee3d2238314326ef8c259b35d1c4f167))
+
+  - **RME**
+
+    - build TF-A with ENABLE_RME for Armv9.2 ([7d5fc98](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d5fc98f5483efb942f7cbe4c04bf546a9a8598c))
+    - pass console info via RMM-EL3 ifc ([3290447](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32904472cc55a4bc9d8181a389ce3419033e0101))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - add support for FFA_CONSOLE_LOG ([638a6f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/638a6f8e04c543649369374492524f2952f8d6b6))
+      - add support for FFA_MEM_PERM_GET and SET ABIs ([1f6b2b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f6b2b26535d5254d998239f232d997972d0475b))
+      - add support to handle power mgmt calls for s-el0 sp ([5917379](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59173793f47e27a66c871a0e8237e0f0d462080d))
+      - add support to map S-EL0 SP device regions ([727ab1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/727ab1c4ab1e5ce1559fa6efec510114ce51fdf8))
+      - add support to map S-EL0 SP memory regions ([83c3da7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c3da7711a246e04f4d0a64593fc0ab46f08bad))
+      - add support to setup S-EL0 context ([48db2b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/48db2b0120d1726208ff38a0edf6962f55a988bf))
+      - synchronize access to the s-el0 sp context ([5ed8e25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ed8e255096bd34d12bc6621e48cf9139bf414b2))
+
+    - **SPMD**
+
+      - add FFA_MSG_SEND_DIR_REQ2 ([cc6047b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc6047b3de52e412988f321723f67077a409e27d))
+      - add FFA_MSG_SEND_DIR_RESP2 ([0651b7b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0651b7beb7e08a01c6e28be61026b053d53308fa))
+      - initialize SCR_EL3.EEL2 bit at RESET ([8815cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8815cdaf57806901cfd388b8ee8c7979a8a2fe15))
+      - pass SMCCCv1.3 SVE hint to lower EL ([c925867](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c925867ec1be039abb72a7d65bff1b6a85b3d67a))
+
+  - **DRTM**
+
+    - add ACPI table region size to the DLME header ([5dde96b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5dde96b02490829d023b37931737c2ba2a6ed431))
+    - add additional return codes ([89f5c75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89f5c753af8e5b8091543e8b1cae4d37e345ed7f))
+    - for TPM features fw hash algorithm should be 16-bits ([c86cfa3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c86cfa35975542d25d2192b81908074195aafe96))
+    - update DRTM version to 1.0 ([9c36b90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c36b900f904642f41e201024df584c0eaef9fc5))
+    - update references to DRTM beta0 ([b94d590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b94d59099f0addb32389952dc6ecf35136a23859))
+    - update return code if secondary PE is not off ([bc9064a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc9064ae5c983aaca56102c2c0d3513ed022fd46))
+
+  - **ChromeOS**
+
+    - add ChromeOS widevine SMC handler ([b22e689](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b22e6898e1493eb00d0f0de6d48655d744264cb6))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add support for Poseidon V CPU ([b77f55d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b77f55d6c7e51025d6c7ada1b4aa9506a046cf0f))
+    - support to update External LLC presence in Neoverse N3 ([6fbc98b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6fbc98b15d92d881c4fbb74fd1344f0ef3f128ad))
+    - support to update External LLC presence in Neoverse V2 ([6aa5d1b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aa5d1b3ab7b29c85ffe05942f2991da869e7fed))
+
+  - **EL3 Runtime**
+
+    - introduce UNDEF injection to lower EL ([3c789bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3c789bfccca548ebcbdafbc7ecb07461d9368bea))
+
+  - **FCONF**
+
+    - support signing-key in root cert node ([04ac0b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04ac0b3c2711a4cb2f35983e91ff0ee842b52bbd))
+
+  - **OP-TEE**
+
+    - enable transfer list in opteed ([0e8def9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e8def996e73673d3e2c3d755a84e2b759ab3052))
+
+  - **PSCI**
+
+    - add psci_do_manage_extensions API ([160e843](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/160e8434baa48cc19d69913b00d2a643c788caec))
+
+  - **GPT**
+
+    - validate CRC of GPT partition entries ([7a9e9f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a9e9f6e96a93617abd33ef48734b65ad792ec13))
+
+  - **SMCCC**
+
+    - add vendor specific el3 id ([be5b1e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be5b1e22346c6d8ce4b0c56604c99f7a9d3676cc))
+    - add vendor-specific el3 service ([de6b79d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de6b79d8b5e15262b328051095e15ad4c67518eb))
+    - add version FID for PMF ([42cbefc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42cbefc72721a9cbf68a70d81cbcb141a2d085f1))
+
+  - **C Standard Library**
+
+    - add printf support for space padding ([0926d2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0926d2df7a5606c2b7c341d51f04a396084c39f2))
+
+  - **Locks**
+
+    - add bitlock ([222f885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/222f885df38c3abd34ee239a721654155609631b))
+
+  - **DICE Protection Environment (Experimental)**
+
+    - add cert_id argument to dpe_derive_context() ([6a415bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a415bd1e71ac944c0ac67507b01f251e63361c3))
+    - add client API for DICE Protection Environment ([b03fe8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b03fe8c025f1c8025e70e7289339ecbc6cf83aae))
+    - add DPE driver to measured boot ([0ae9c63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ae9c631eaa32a30df3ff10cb4f0abafccb6c409))
+    - add QCBOR library as a dependency of DPE ([c19977b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c19977be0c3654e12accd51d4aef7059411106a6))
+    - add typedefs from the Open DICE repo ([584052c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/584052c7f80b406666b9597447eeccef4d6deca4))
+
+  - **Context Management**
+
+    - report context memory usage ([bfef8b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfef8b908e3a3cc29656c1d30a6b53490c79539b))
+    - add documentation for context management library ([4efd219](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4efd2193621ab7b933f4edfa28888379f3e03cbd))
+
+  - **Firmware Handoff**
+
+    - add additional TE tags ([a312bfb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a312bfb34487774a0e3244266ee45f63af86e2e8))
+    - add support for RESET_TO_BL2 ([f019c80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f019c8013e9c5efeb85eec7792fe901543a5832c))
+    - add TE's for BL1 handoff interface ([0646c9b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0646c9b293a2d8cdfd4626d15395385b5c1c2a6c))
+    - add TL source files to BL1 ([469b1d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/469b1d8412a748819f8c1bf51f695f2cb9f20489))
+    - enhance transfer list library ([40fd755](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40fd755bad9411d1e9e55984107186dde4137635))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - add explicit entries for key OIDs ([2b53106](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b53106a0e91e0865bf855935de04b24ef1cfa02))
+
+    - **mbedTLS**
+
+      - update config for 3.6.0 ([55aed7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/55aed7d798f3d48d6aa08d58eb46c4cda318bcfb))
+
+  - **Console**
+
+    - introduce EARLY_CONSOLE ([ae770fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae770fedf459d5643125d29f48659e3e936ebd2d))
+
+  - **FWU**
+
+    - modify the check for getting the FWU bank's state ([56724d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56724d09c2c55ee2b8486b7c706f5fb9d980df88))
+    - update the URL links for the FWU specification ([e106a78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e106a78ef00df4c70a1594a89520af07b939cd92))
+
+  - **SCMI**
+
+    - add scmi sensor support ([e63819f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e63819f2bc307e7a42d43151242009f91ceeb06b))
+
+  - **Arm**
+
+    - **SMMU**
+
+      - fix to perform INV_ALL before enabling GPC ([70d849c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70d849c14de99e7320cc381b441af8bfe2a38375))
+      - separate out smmuv3_security_init from smmuv3_init ([a23710b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a23710b4b943a15a418a5d41236b2b57bd071de6))
+
+    - **MHU**
+
+      - add MHUv3 doorbell driver ([bc17476](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc174764f0daa82128bf60163653fc20db9a7e87))
+      - add MHUv3 wrapper APIs for RSS comm driver ([4b4f850](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b4f8505e7c58ba80a00c47a11f5feaf6d6f44f2))
+      - use compile flag to choose mhu version ([996b3af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/996b3af84cc6aeca90bc0dd3559abffd8bdc0ed7))
+
+    - **RSE**
+
+      - add defines for 'type' range and use them in psa_call() ([002b106](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/002b10604ba0b90ac6e85d445ce2184cab52e39b))
+      - adjust parameter packing to match TF-M changes ([5abcc83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5abcc83991770a2fdbcb57dfc01000c6354da915))
+
+  - **NXP**
+
+    - add Linflex driver ([306946b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/306946b01490cfe0675300412cf738840bd099ef))
+
+  - **ST**
+
+    - **BSEC**
+
+      - add driver for the new IP version BSEC3 ([ae6542f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae6542f6c7ac9224843448424d3a539733bd651b))
+      - use early traces ([cf237f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf237f8d55255da1aad4f8dccb3110bab6060eba))
+
+    - **Clock**
+
+      - add function to control MCU subsystem ([77b4ca0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77b4ca0b2fd2c35e3bcb516078e1d9e3573172b3))
+
+    - **SDMMC2**
+
+      - set FIFO size to 1024 on STM32MP25 ([d5b4d5d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5b4d5d2e62e57acdcb2dbbcd4fe208bde92dc4c))
+
+- **Miscellaneous**
+
+  - **AArch64**
+
+    - add functions for TLBI RPALOS ([8754cc5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8754cc5d1c1b33d645b321f465bcfe61bc3915d6))
+
+  - **DT Bindings**
+
+    - introduce CCA CoT, rename TBBR ([c4b35ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4b35cebffb0d034aa7bdba7cfdb65ba93939e35))
+
+  - **FDTs**
+
+    - **STM32MP2**
+
+      - add board ID OTP in STM32MP257F-EV1 ([88528f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88528f55771fdc0a94b2ddd7f49f495a83044a24))
+      - add OTP nodes in STM32MP251 SoC DT file ([c238a46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c238a46a76660cbfa9ed40da4b1d0e5d477c3dd7))
+
+  - **Security**
+
+    - add support for SLS mitigation ([538516f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/538516f5d3db6e2c30dfa9f0b82859389f529e78))
+
+- **Documentation**
+
+  - update maintainer list for neoverse_rd ([2d7902d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d7902d9bf0bafceee9f571225862c476de0cdce))
+
+- **Build System**
+
+  - check that .text section starts at page boundary ([3d6edc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d6edc325c52082ab63ffd003c55a4ed875a52c5))
+  - redirect stdin to nul during toolchain detection ([b9014f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9014f858d1fd963a466228ec15572b0892a8490))
+
+- **Tools**
+
+  - **Memory Mapping Tool**
+
+    - add RELA section display ([a6462e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6462e05cf1cd55da44002cdede04053a928cf0a))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **Memory Tagging Extension2**
+
+    - remove CTX_INCLUDE_MTE_REGS usage ([30788a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30788a8455779b70aebd38d53afc8aa19d776c6c))
+    - use ATA bit with FEAT_MTE2 ([ef0d0e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef0d0e5478a3f19cbe70a378b9b184036db38fe2))
+
+  - **Performance Monitors Extension (FEAT_PMUv3)**
+
+    - fix breakage on ARMv7 CPUs with SP_min as BL32 ([e6f8fc7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6f8fc7437f6b9483ea0463315809d7ff6d5c0ec))
+
+  - **Statistical profiling Extension (FEAT_SPE)**
+
+    - invoke spe_disable during power domain off/suspend ([777f1f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/777f1f6897b57fe98c70d17c0d318aab3b86e119))
+
+- **Platforms**
+
+  - **Arm**
+
+    - move console flush/switch in common function ([6bdc856](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6bdc856bc9135db420196683501b4f201b30ae3a))
+    - only expose `arm_bl2_dyn_cfg_init` to BL2 ([3b48ca1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b48ca17f350d8b0999e89e8d9215993701e16a0))
+
+    - **FVP**
+
+      - added ranges for linux ([b7491c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7491c77d7ad2991b8c7c01f0311ebb3b0eca397))
+      - don't check MPIDRs with the power controller in BL1 ([6d8546f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d8546f9fc49a03a817b15b20a9d62fadda74b9c))
+      - permit enabling SME for SPD=spmd ([0b0fd0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b0fd0b47616b706e2f07c6da548cdc913fecd17))
+
+    - **FPGA**
+
+      - halve number of PEs per core ([70b9204](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70b9204e6f98f1ec4f0529e8c1c88e8ece490d22))
+
+    - **Neoverse-RD**
+
+      - **SGI**
+
+        - align to misra rule for braces ([cacee06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cacee0605684a75bbe8783c74fddba97b9abcffa))
+        - apply workarounds for N2 CPU erratum ([7934b68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7934b68af6b446783823a114f25c3be06244c0e4))
+        - increase BL31 carveout size ([0737bd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0737bd33faba5c9e6a0e98969e015430e2782332))
+        - reduce cper buffer carveout size ([f10d3e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f10d3e4953741eb3be1f9e4c09e7420554a0f050))
+        - update spi_id max for sgi multichip platforms ([89d8577](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89d857780c50bddf94db26f158c008b4cc846edf))
+
+      - **RD-N1-Edge**
+
+        - update RD-N1-Edge's changelog title ([d239ede](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d239edea5644657ac72458cc13e3ce6bb5754ff8))
+
+      - **RD-N2**
+
+        - populate TOS_CONFIG only when SPMC_AT_EL3 is enabled ([10dcffe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10dcffedb36a658cf8a3389fbdeb499d4e7e4446))
+
+    - **TC**
+
+      - correct interrupts ([d2e44e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2e44e7d71863e3b302b5e72c8262bb0f3964fe6))
+      - do not enable MPMM and Aux AMU counters always ([fc42f84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc42f84560d33c53b248e14913bbd6a69a8d310a))
+      - do not use r0 for HW_CONFIG ([a5a966b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5a966b12d9fe51a337db3204e7463ad95ba99c6))
+      - enable FEAT_MTE2 ([154eb0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/154eb0a22fa0a88d1f46e3674e3979626a83e063))
+      - guard PSA crypto headers under TF-M test-suite define ([d2ce6aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2ce6aa066ce1539908726de0d94a59c16634c4a))
+      - increase BL2 maximum size limit ([19258a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19258a5839cae9a81fb7256fbea34ff118220161))
+      - increase stack size when TRUSTED_BOARD_BOOT=0 ([44ddee6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44ddee6f0a993ed5b3409e6626c0c70b7ed7d7a2))
+      - missing device regions in spmc manifest ([5e47112](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e4711208db622ff6150e69c87962b506742a544))
+      - remove timer interrupt from G1S ([9bf31a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9bf31a59d187f6537066f05677972d9767e96c82))
+
+  - **Intel**
+
+    - add HPS remapper to remap base address for SDM ([b727664](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b727664e0dcf62be39552521c451ecde02091917))
+    - bl31 overwrite OCRAM configuration ([cfbac59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfbac59590056e6b639aed56a1da480cd46f6f3e))
+    - fix hardcoded mpu frequency ticks ([150d2be](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/150d2be0d2d440011c91c9bf8013a1ab602b464c))
+    - read QSPI bank buffer data in bytes ([2f17ac0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f17ac01adf28edb90a5ec8f446be1be76971b5c))
+    - revert back to use L4 clock ([d0e400b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0e400b3c626be647b9a20bc4f4869e20cc15dde))
+    - revert sys counter to 400MHz ([460692a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/460692afb5b934720b69c410e3b02c540a3b1ddf))
+    - temporarily workaround for Zephyr SMP ([68820f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68820f642191cef67df38516ef1c2ed1411c579f))
+    - update DDR range checking for Agilex5 ([f4aaa9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4aaa9fd6e6b4edd03976680b94e1c24aa582a68))
+    - update fcs crypto init code to check for mode ([b0f4478](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0f447897d3e2ddd72b291cb450165f4d220663e))
+    - update fcs functions to check ddr range ([e8a3454](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8a3454cb74a9b55c0cb678d47a8553ece660439))
+    - update from INFO to VERBOSE when print debug message ([56c8d02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56c8d022b00ba212f3e21dcfab20c14f3a44eec4))
+    - update HPS bridges for Agilex5 SoC FPGA ([2973054](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2973054d9b4ba4fbcad7e04303ce8e0838b2f2b3))
+    - update individual return result for hps and fpga bridges ([82752c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/82752c412362607549068d1c10cf7688f309d249))
+    - update nand driver to match GHRD design ([a773f41](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a773f4121b3064fba24631e980c6226f23378e06))
+    - update stream id to non-secure for SDM ([8fbd307](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fbd3073cacfc7a23efdfda4eecfaf6607515306))
+    - update system counter back to 400MHz ([a72f86a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a72f86ac4208e2aae5da83229cdd9ac97f651e36))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - align 3200 MTps rate with U-Boot ([060fe63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/060fe63337097c6cadea76ef5d2d383f0d90ef01))
+        - fix CSU_SA_REG to work with all sa registers ([c13016b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c13016bac6a6960acbbfb3e0176e1894a7e9fa3a))
+        - handle 3734 in addition to 3733 and 3732 MTps rates ([cb60a87](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb60a876efc156c87afcd5ec53b9cf356f30211d))
+
+        - **i.MX 8M Plus**
+
+          - uncondtionally enable only the USB power domain ([ae6ce19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae6ce196df5b932f38c543cd8c6d8d86ee600009))
+
+      - **i.MX 8ULP**
+
+        - add sw workaround for csi/hotplug test hang ([e1d5c3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1d5c3c8f435424394367e2ff19240b1b8a3073c))
+        - fix suspend/resume issue when DBD owner is s400 only ([68f132b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68f132b88bb24277ee34d5c3c94d16c26d7d4545))
+        - increase the mmap region num ([047d7d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/047d7d1ba2fc84d8377156f7f45d2d69c3cb5f84))
+
+  - **QEMU**
+
+    - disable FEAT_SB ([59bdb42](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59bdb426d300a6350334523a8dbc3fa6ae9f3bfc))
+    - increase max FIP size ([f465ac2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f465ac221001f82bed907be356917675645d92eb))
+
+  - **Raspberry Pi**
+
+    - consider MT when calculating core index from MPIDR ([6744d07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6744d07d9475adb49352fa57aa72fce17a95d757))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - fix implicit rule invocations in tools ([e068a7c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e068a7ca860f35a171f608d55fb8a2a00ebd7561))
+
+      - **R-Car 3**
+
+        - change RAM protection configurations ([e9afde1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9afde1a2e311df0197a8e9102ef535382aef228))
+        - fix load address range check ([4f7e0fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f7e0fa38fdb6a25b07afafff492985bcc4e63a0))
+
+  - **Rockchip**
+
+    - add support for building with LTO enabled ([e5e9ccd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5e9ccdb0c070d3066e7d778e5e2b563acd7ba98))
+    - fix documentation in how build bl31 in AARCH64 ([6611e81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6611e81e14ed4aa16844e3865fd8a9f6fa99a074))
+
+    - **RK3328**
+
+      - apply ERRATA_A53_1530924 erratum ([dd2c888](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd2c888606dcdd638354c6345e08d4415d9d09fd))
+
+  - **ST**
+
+    - **STM32MP2**
+
+      - add missing include ([cb0d6b5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb0d6b5b5f7530335eac3c387bbb82d86608b0ea))
+      - correct early/crash console init ([4da462d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4da462dcdc2e435c8b732f3ceff4c94ca28b4c43))
+
+  - **Texas Instruments**
+
+    - do not stop non-secure timer on world switch ([d2e1f6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2e1f6a8811e52505556f7b91156499d82488751))
+
+    - **K3**
+
+      - increment while reading trail bytes ([0bdaf5c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0bdaf5c804f852fe21f6172e436524157c9f6919))
+
+  - **Xilinx**
+
+    - add console_flush() before shutdown ([7ec53af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ec53afaade308b35f546480990dbc9304e06e7d))
+    - add FIT image check in DT console ([e2d9dfe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2d9dfe2bffe4fde28f2714058c8c882ea90102a))
+    - add FIT image check in prepare_dtb ([046e130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/046e1304721e8bbf3d304dac22aa290bcbb0d10c))
+    - check proc variable before use ([652c1ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/652c1ab1526877d3505218f87ea96e6a9b2ccc11))
+    - deprecate SiP service count query ([6a80c20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a80c20eff74054c28273b42f3fe8e1a8fc5add4))
+    - fix sending sgi to linux ([427e46d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/427e46ddea1e528d4c57b1d8215482055bd79c3e))
+    - follow MISRA-C standards for condition check ([655e62a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/655e62aa5bede7ace8f8c6df571707aca9d6e14f))
+    - rename macros to align with ARM ([7995319](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79953190bc856ac3f47281029a80e5129bb4437d))
+    - update correct return types ([8eb6a1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8eb6a1da1229b8f0bff33293cbb86ce20d09259d))
+
+    - **Versal**
+
+      - initialize cntfrq_el0 register ([f000744](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f000744e0f501c89fb2240b47e91c261e3082249))
+
+      - **Versal NET**
+
+        - setup counter frequency ([07625d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07625d9dd42d81c0e15f101fc0b6efa1c784b6f4))
+        - use arm common GIC handlers ([b225926](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b2259261815961042d2a994401929bc76a0d3ee9))
+
+    - **ZynqMP**
+
+      - resolve null pointer dereferencing ([20fa9fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/20fa9fc82334c67834eb22e20a3f4a07bcbe069d))
+
+  - **Nuvoton**
+
+    - gfx frame buffer memory corruption during secondary boot ([ae2b4a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae2b4a5494f9b4985fc2434e543ab0921e3b5a34))
+    - prevent changing clock frequency ([fe8cc55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe8cc55a0cb5e47a0c0e28b147ee3e8dfdae07b2))
+
+- **Bootloader Images**
+
+  - **BL1**
+
+    - add missing `__RW_{START,END}__` symbols ([d701b48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d701b48eef4bb4b4b13ce5ef4091a37047e49a0b))
+    - add missing spinlock dependency ([e40b563](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e40b563e87fd4ff58474a289909a1827c8d2bca7))
+
+  - **BL2**
+
+    - make BL2 SRAM footprint flexible ([e0e03a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0e03a8d8b7eac45606812d1f2a9685b51e44515))
+
+- **Services**
+
+  - **FF-A**
+
+    - add NS memory node to fvp_spmc_optee_sp manifest ([92bba3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/92bba3e711a21f2d31842bee64a1bd87e4b65414))
+
+  - **RME**
+
+    - **RMMD**
+
+      - avoid TRP when external RMM is defined ([57bc3c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57bc3c40560285e6029742b7360f8a0d0ac2346c))
+      - fix bug, raised by coverity, when zeroing manifest struct ([83a4e8e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83a4e8e0c69c64219e4d9de6c7f51fb10e3adc5a))
+
+  - **SPM**
+
+    - add device-regions used in tf-a-tests ([45716e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45716e377ecb30c17aa3b375ce1e232d15492b9c))
+    - not defining load-address in SP config ([04e7f80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04e7f80823e8a083138dd25963a5509bacd93257))
+    - reduce verbosity on passing tf-a-tests ([29872eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/29872eb330201334fcb8e418b7dc7ae8ff0dc192))
+    - silence warning in sp_mk_generator ([6a3225e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a3225e2277df18e5c3aceb6173579cccefece51))
+
+    - **EL3 SPMC**
+
+      - add datastore linker script markers ([ba33528](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba33528a00bb83f5562918131cb37574fc287193))
+      - fix dangling pointer in FFA_CONSOLE_LOG ([83129bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83129bcd8e75f1ffbfc9a3bae3d60749b1d22fe3))
+
+    - **SPMD**
+
+      - register group0 handler only if supported ([fca5f0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fca5f0ebe5c2b5cf1c9d5096db6001a60ff7e089))
+      - skip NS EL1 context save & restore operations ([2d960a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d960a11601be6e7f24c38d84b2a4fdbb52efb9b))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - workaround for Cortex-A520 erratum 2630792 ([f03bfc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f03bfc304599540d859c4a07ac85d1bd9ae2c4f0))
+    - workaround for Cortex-A520 erratum 2858100 ([34db353](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34db3531ba085f111274b3b8e18476c4a392c245))
+    - workaround for Cortex-A710 erratum 2778471 ([c9508d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9508d6a1062ec3de4baaa3bd79ceed13eb972ad))
+    - workaround for Cortex-A715 erratum 2331818 ([53b3cd2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53b3cd2532dbdb794ddfedcc8a3985d2404eb6f7))
+    - workaround for Cortex-A715 erratum 2344187 ([33c665a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33c665ae955fe5f5ae255f56ef6cdf073a9f601f))
+    - workaround for Cortex-A715 erratum 2413290 ([15a0461](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15a04615bb6834d93ab0077b89726dc17e3ba8b0))
+    - workaround for Cortex-A715 erratum 2420947 ([1f73247](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f732471320cee7b4f355ecff7dcfab7018e48ae))
+    - workaround for Cortex-A715 erratum 2429384 ([262dc9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/262dc9f76086970dab3dc43815890bed0ea29c79))
+    - workaround for Cortex-A715 erratum 2561034 ([6a6b282](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a6b282378340dc61cf088ff5a06770cf68f44d8))
+    - workaround for Cortex-A715 erratum 2728106 ([10134e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10134e3556ca61e670017e681eb637889b1bd4f8))
+    - workaround for Cortex-A720 erratum 2926083 ([152f4cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/152f4cfa16bc3d2786f598390450af38f4b2d0be))
+    - workaround for Cortex-A720 erratum 2940794 ([7385213](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7385213e602465d27530015a9b28ebc36a77b1c1))
+    - workaround for Cortex-A78C erratum 2683027 ([68cac6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68cac6a0f273dbe4f44563b467c996fafef07016))
+    - workaround for Cortex-A78C erratum 2743232 ([81d4094](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81d4094d637871ff34ddd7c2e2b3e842915f30f5))
+    - workaround for Cortex-X2 erratum 2778471 ([b01a93d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b01a93d7789a794ef0635e0a7b0e7e53cc8519e5))
+    - workaround for Cortex-X3 erratum 2266875 ([a65c5ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a65c5ba351178e6119299fa935a3576453cf900b))
+    - workaround for Cortex-X3 erratum 2302506 ([3f9df2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3f9df2c6ad053172c5dab74cd12d82a5b2c93c34))
+    - workaround for Cortex-X3 erratum 2372204 ([7f69a40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f69a40697c3cc64e3fc553f6b50c72b97238dc9))
+    - workaround for Cortex X3 erratum 2641945 ([c1aa3fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1aa3fa5555250dfbcae99fb6944ad24c4ee6a0b))
+    - workaround for Cortex X3 erratum 2743088 ([f43e9f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f43e9f57dc37a806bcd5e25a46b9f9bb1f365a64))
+    - workaround for Cortex-X3 erratum 2779509 ([355ce0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/355ce0a43abc1559b072b9cd9905f5194a6f0b86))
+    - workaround for Cortex-X4 erratum 2701112 ([cc41b56](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc41b56f41af14b00ce9f5c802e2f883786cef38))
+    - workaround for Cortex-X4 erratum 2740089 ([c833ca6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c833ca66a6fecbc54e038164e466be677559ec4e))
+    - workaround for Cortex-X4 erratum 2763018 ([4731211](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47312115dea140dd7ba26cf0512856a41f3e3067))
+    - workaround for Neoverse V1 erratum 2348377 ([71ed917](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71ed91733140c82a392161c81869fcadb445c01a))
+    - workaround for Neoverse V2 erratum 2618597 ([c0f8ce5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0f8ce5379a77e61e89d91e225784801e5bbd3e0))
+    - workaround for Neoverse V2 erratum 2662553 ([912c409](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/912c4090fff207b445dde4bff72cc9b6e057e8b7))
+    - workaround for Neoverse V2 erratum 3099206 ([8815cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8815cdaf57806901cfd388b8ee8c7979a8a2fe15))
+    - add Cortex-A520 definitions ([ae19093](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae19093f2aa6dd95cc7819accb0d05c0ebe4eeb3))
+    - workaround for Cortex-A715 erratum 2413290 re-factored with ENABLE_SPE_FOR_NS=1 ([bd2f7d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd2f7d325826f75acd729d4ee2719fd6130a7c5e))
+    - fix a defect in Cortex-A715 erratum 2561034 ([57ab6d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57ab6d897656f71d229268d80e41b26e62179400))
+    - add erratum 2701951 to Cortex-X3's list ([106c428](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/106c4283a564e4f37976ebc7dd8bc7d35f6592e4))
+    - update status of Cortex-X3 erratum 2615812 ([f589a2a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f589a2a5f1b032ff3a09a419e49db0b97ccd8595))
+    - fix incorrect AMU trap settings for N2 CPU ([54b86d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/54b86d47eb05f09330df57519b7d04b9968890e5))
+    - correct variant name for default Poseidon CPU ([61a2968](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/61a29682c66d0437806f81fb8ab0e3ff321dfe04))
+    - check for SCU before accessing DSU ([5b5562b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b5562b2e5855f949f1fc0579d7aff15e6b274ef))
+
+  - **EL3 Runtime**
+
+    - **Context Management**
+
+      - add more feature registers to EL1 context mgmt ([d6c76e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6c76e6c65429326e7572e10f521dd9108a3a1e3))
+      - add more system registers to EL1 context mgmt ([ed9bb82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed9bb824e4a3815e60acaa69ed66796279f4afbf))
+      - hide `cm_init_context_by_index` from BL1 ([a6b3643](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6b3643c2a1a95146e93c8b6f07c2e491a1230d6))
+      - remove ENABLE_FEAT_MTE usage ([a796d5a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a796d5aa11b25622841cd2283630ff9348eed699))
+      - save guarded control stack registers ([6aae3ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aae3acfd0d48e49e2367e6cd883dda7dca974c8))
+      - update gic el2 sysregs save/restore mechanism ([937d6fd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/937d6fdb70cd24602fd2638a5dbd5c46d32559c1))
+      - couple el2 registers with dependent feature flags ([d6af234](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6af23443179f6d2239c7f5f190f0d8828bd68cf))
+      - move EL1 save/restore routines into C ([59f8882](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59f8882b44845ab865e354eeda8ce653f5d5fcf3))
+
+  - **FCONF**
+
+    - boot fails using ARM_ARCH_MINOR=8 ([0c86a84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c86a846d9149ee5af7e1ee4bb185c532ed9d0f8))
+
+  - **OP-TEE**
+
+    - set interrupt handler before kernel boot ([0ec69a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ec69a5bfbfcdf4566db8e96adaf29ad847d3d58))
+
+  - **PSCI**
+
+    - fix parent_idx in psci_validate_state_coordination ([412d92f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/412d92fdfd28d2f850a48e5f0aee95faa894a556))
+    - mask the Last in Level nibble in StateId ([0a9c244](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a9c244b05ef2d2d4b946ba81bb9b9584b479b48))
+
+  - **GPT**
+
+    - declare gpt_tlbi_by_pa_ll() ([832e4ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/832e4ed520d5ed7e64249fe98c1ffb4550db5eca))
+    - unify logging messages ([b99926e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b99926ef7b287738c4b4a87ee7ab4eaed1e4038f))
+    - use DC CIGDPAPA when MTE2 is implemented ([62d6465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62d64652134ca1d3ea68da65ea9e4ae136f6c44e))
+
+  - **C Standard Library**
+
+    - add memcpy_s source file to libc_asm mk ([99db13b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99db13bfaa5b11345730937c2e0e56cb670c01a5))
+    - memset inclusion to libc makefiles ([84eb3ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84eb3ef6c9f596e968b4f9b83a3a01deda2a8a9d))
+
+  - **PSA**
+
+    - fix static check failure ([bc0ff02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc0ff02cbb046388eff1a95efd0043757d6ac317))
+
+  - **Context Management**
+
+    - align the memory address of EL2 context registers ([8c56a78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c56a78894ddc69167bc093fe19f173feced720c))
+
+  - **Firmware Handoff**
+
+    - correct representation of tag_id ([d594ace](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d594ace68d4fa62cf2f1d5d13503b737b85924e5))
+
+  - **Exception Handling Framework (EHF)**
+
+    - restrict secure world FIQ routing model to SPM_MM ([7671008](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7671008fcfc826dbc3166ff1bdbb9cd7fbc7f68b))
+
+  - **SMCCC**
+
+    - correctly find pmf version ([62865b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62865b4ee455806e37a9c5bd52255b8c09cf1a1a))
+
+- **Drivers**
+
+  - **Measured Boot**
+
+    - add missing image identifier string ([a8a09e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8a09e3141354b159e7699d7c9c325bdd817b1f5))
+
+  - **SCMI**
+
+    - induce a delay in monitoring SCMI channel status ([af1ac2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af1ac2d7db47717bc69afd69b56f398aa34b2fb6))
+
+  - **Arm**
+
+    - **GIC**
+
+      - **GICv3**
+
+        - **GIC-600**
+
+          - workaround for Part 1 of GIC600 erratum 2384374 ([24a4a0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24a4a0a5ec25e179f2e567a6e13a9b5c87db1b81))
+
+      - **GICv2**
+
+        - fix SGIR_NSATT bitshift ([eef240c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eef240cfdedcc59f09dd5cd942448c5dcecc75d6))
+
+    - **MHU**
+
+      - use MHUv2 if PLAT_MHU_VERSION undefined ([c34dd06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c34dd06a843d71cdba2fa1c3c9067f6f130a0c73))
+      - provide only the usable size of memory ([5cd1084](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5cd10848be4f6ac19daa66803c3d512e3eea4266))
+
+    - **RSE**
+
+      - fix bound check during protocol selection ([f754bd4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f754bd466749a9338561f991bfb85140dd034e03))
+
+  - **Renesas**
+
+    - **R-Car3**
+
+      - add integer overflow check ([ef38fb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef38fb1f5a5f2bdb897158e4244a1eddd2396eeb))
+      - add integer overflow check ([93b8952](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93b8952eefa14141c142070a71fc017736c8910c))
+      - check "rcar_image_number" variable before use ([b469880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b469880e3b6b26849c3d43d3fe88a755a25249bc))
+      - check for length underflow ([9778b27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9778b270e29bac3e16f57f9557098c45858c05de))
+      - check loaded NS image area ([ae4860b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae4860b0f5c283aeca4def1449f0293ef22ff508))
+
+  - **USB**
+
+    - add missing include ([f84f21f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f84f21fa8d17662dcdc6b0b8b0caca4a45cd9ccd))
+
+- **Miscellaneous**
+
+    - **TBBR**
+
+      - move rotpk definitions out of arm_def.h ([0f0fd49](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f0fd499dedd799e19279f0aa1f4f686085a944a))
+
+    - code coverage optimization fix ([152ad11](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/152ad112d73402523302f3cb252aee0efc145736))
+    - fix MISRA defects ([c42d0d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c42d0d8754ae8818a7e7a63e873ca7699a7f102b))
+    - static checks on spmc dts ([c35299d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c35299d6b4e8b2757e47dc4c5a3b2e0836f89a7d))
+
+- **Documentation**
+
+  - revise the description of REGISTER_CRYPTO_LIB ([5710229](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5710229f9e837f28e4bafee6b51e828f901bf3f1))
+  - typo in the romlib design ([3b57ae2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b57ae23e0891e44d5b648575b80cbad4fc10405))
+
+- **Build System**
+
+  - add forgotten BL_LDFLAGS to lto command line ([49ba1df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49ba1df52204e721f06a6da76ef0f8692ce1b2f8))
+  - don't generate build-id ([304ad94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/304ad94b34c2117823169a199558e7484139caa1))
+  - don't rely on that gcc-ar is in the same directory as gcc ([7ef0b83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ef0b8377fa7fb3697dda5adfa44dafd7e14150f))
+  - enforce single partition for LTO build ([31f80ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31f80efeefaee2c59db50a46cabe2b5fdf20e4ae))
+  - march handling with arch-features ([7275ac2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7275ac2af86277e2442ef4b0fee6c35cbe830056))
+  - move comment for VERSION_PATCH ([c25d1cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c25d1ccf1e205b2781ecd0de91e91d35e57b79bc))
+  - mute sp_mk_generator from build log ([fbd32ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbd32ac081c421929728f454427b7839235d2075))
+  - properly manage versions in .versionrc.js ([7f74030](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f74030b89136a1673e2a949564403709bc48f5d))
+  - wrap toolchain paths in double quotes ([4731c00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4731c00bb60915c0d4b29c082a752e9925a244b4))
+
+- **Tools**
+
+  - **Certificate Creation Tool**
+
+    - add guardrails around brainpool usage ([c0c280d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0c280dfda7322dcaebb5c6341c0880bdf524e13))
+    - use a salt length equal to digest length for RSA-PSS ([e639ad2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e639ad23c8c7a1b320af9ebd519420ae7d431531))
+
+  - **Memory Mapping Tool**
+
+    - fix footprint free space calculation ([9e72d01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9e72d01ed29c350dfc0567c59bc482901211634b))
+    - fix memory map dump when SEPARATE_CODE_AND_RODATA=0 ([6dc8ee6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dc8ee61ffeee8ea5aafdbef3121fa4e82b57932))
+
+  - **Marvell Tools**
+
+    - include mbedtls/version.h before use ([8eb4efe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8eb4efe70bd5b03917e2063ab8ff5646de88922a))
+
 ## [2.10.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.9.0..refs/tags/v2.10.0) (2023-11-21)
 
 ### âš  BREAKING CHANGES
@@ -2667,11 +3585,11 @@
       - route GIC IPI interrupts during setup ([04cc91b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04cc91b43c1d10fcba563e18f06336987e6e3a24))
       - use only one space for indentation ([dee5885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dee588591328b96d9b9ef908869c8b42bd2632f2))
 
-      - **Versal NET**
+    - **Versal NET**
 
-        - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
-        - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
-        - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
+      - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
+      - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
+      - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
 
     - **ZynqMP**
 
@@ -8839,7 +9757,7 @@
 
 ______________________________________________________________________
 
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
 [mbed tls releases]: https://tls.mbed.org/tech-updates/releases
 [pr#1002]: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
diff --git a/docs/components/arm-sip-service.rst b/docs/components/arm-sip-service.rst
index b51a94d..74a40a3 100644
--- a/docs/components/arm-sip-service.rst
+++ b/docs/components/arm-sip-service.rst
@@ -15,19 +15,20 @@
 
 The Arm SiP implementation offers the following services:
 
--  Performance Measurement Framework (PMF)
 -  Execution State Switching service
--  DebugFS interface
 
 Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header
 file.
 
-Performance Measurement Framework (PMF)
----------------------------------------
++----------------------------+----------------------------+---------------------------------------+
+| ARM_SIP_SVC_VERSION_MAJOR  | ARM_SIP_SVC_VERSION_MINOR  | Changes                               |
++============================+============================+=======================================+
+|                          1 |                          0 | Move DebugFS and PMF to the new vendor|
+|                            |                            | specific FID range. The old FID range |
+|                            |                            | for these services are deprecated     |
++----------------------------+----------------------------+---------------------------------------+
 
-The :ref:`Performance Measurement Framework <firmware_design_pmf>`
-allows callers to retrieve timestamps captured at various paths in TF-A
-execution.
+*Table 1: Showing different versions of arm-sip-service and changes done with each version*
 
 Execution State Switching service
 ---------------------------------
@@ -88,348 +89,8 @@
 and 1 populated with the supplied *Cookie hi* and *Cookie lo* values,
 respectively.
 
-DebugFS interface
------------------
-
-The optional DebugFS interface is accessed through an SMC SiP service. Refer
-to the component documentation for details.
-
-String parameters are passed through a shared buffer using a specific union:
-
-.. code:: c
-
-    union debugfs_parms {
-        struct {
-            char fname[MAX_PATH_LEN];
-        } open;
-
-        struct mount {
-            char srv[MAX_PATH_LEN];
-            char where[MAX_PATH_LEN];
-            char spec[MAX_PATH_LEN];
-        } mount;
-
-        struct {
-            char path[MAX_PATH_LEN];
-            dir_t dir;
-        } stat;
-
-        struct {
-            char oldpath[MAX_PATH_LEN];
-            char newpath[MAX_PATH_LEN];
-        } bind;
-    };
-
-Format of the dir_t structure as such:
-
-.. code:: c
-
-    typedef struct {
-        char		name[NAMELEN];
-        long		length;
-        unsigned char	mode;
-        unsigned char	index;
-        unsigned char	dev;
-        qid_t		qid;
-    } dir_t;
-
-
-* Identifiers
-
-======================== =============================================
-SMC_OK                   0
-SMC_UNK                  -1
-DEBUGFS_E_INVALID_PARAMS -2
-======================== =============================================
-
-======================== =============================================
-MOUNT                    0
-CREATE                   1
-OPEN                     2
-CLOSE                    3
-READ                     4
-WRITE                    5
-SEEK                     6
-BIND                     7
-STAT                     8
-INIT                     10
-VERSION                  11
-======================== =============================================
-
-MOUNT
-~~~~~
-
-Description
-^^^^^^^^^^^
-This operation mounts a blob of data pointed to by path stored in `src`, at
-filesystem location pointed to by path stored in `where`, using driver pointed
-to by path in `spec`.
-
-Parameters
-^^^^^^^^^^
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``MOUNT``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed
-=============== ==========================================================
-
-OPEN
-~~~~
-
-Description
-^^^^^^^^^^^
-This operation opens the file path pointed to by `fname`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``OPEN``
-uint32_t mode
-======== ============================================================
-
-mode can be one of:
-
-.. code:: c
-
-    enum mode {
-        O_READ   = 1 << 0,
-        O_WRITE  = 1 << 1,
-        O_RDWR   = 1 << 2,
-        O_BIND   = 1 << 3,
-        O_DIR    = 1 << 4,
-        O_STAT   = 1 << 5
-    };
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed
-
-uint32_t        w1: file descriptor id on success.
-=============== ==========================================================
-
-CLOSE
-~~~~~
-
-Description
-^^^^^^^^^^^
-
-This operation closes a file described by a file descriptor obtained by a
-previous call to OPEN.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``CLOSE``
-uint32_t File descriptor id returned by OPEN
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed
-=============== ==========================================================
-
-READ
-~~~~
-
-Description
-^^^^^^^^^^^
-
-This operation reads a number of bytes from a file descriptor obtained by
-a previous call to OPEN.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``READ``
-uint32_t File descriptor id returned by OPEN
-uint32_t Number of bytes to read
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-On success, the read data is retrieved from the shared buffer after the
-operation.
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed
-
-uint32_t        w1: number of bytes read on success.
-=============== ==========================================================
-
-SEEK
-~~~~
-
-Description
-^^^^^^^^^^^
-
-Move file pointer for file described by given `file descriptor` of given
-`offset` related to `whence`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``SEEK``
-uint32_t File descriptor id returned by OPEN
-sint32_t offset in the file relative to whence
-uint32_t whence
-======== ============================================================
-
-whence can be one of:
-
-========= ============================================================
-KSEEK_SET 0
-KSEEK_CUR 1
-KSEEK_END 2
-========= ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed
-=============== ==========================================================
-
-BIND
-~~~~
-
-Description
-^^^^^^^^^^^
-
-Create a link from `oldpath` to `newpath`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``BIND``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed
-=============== ==========================================================
-
-STAT
-~~~~
-
-Description
-^^^^^^^^^^^
-
-Perform a stat operation on provided file `name` and returns the directory
-entry statistics into `dir`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``STAT``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed
-=============== ==========================================================
-
-INIT
-~~~~
-
-Description
-^^^^^^^^^^^
-Initial call to setup the shared exchange buffer. Notice if successful once,
-subsequent calls fail after a first initialization. The caller maps the same
-page frame in its virtual space and uses this buffer to exchange string
-parameters with filesystem primitives.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``INIT``
-uint64_t Physical address of the shared buffer.
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ======================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if already initialized,
-                or internal error occurred.
-=============== ======================================================
-
-VERSION
-~~~~~~~
-
-Description
-^^^^^^^^^^^
-Returns the debugfs interface version if implemented in TF-A.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``VERSION``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ======================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == SMC_UNK if interface is not implemented
-
-uint32_t        w1: On success, debugfs interface version, 32 bits
-                value with major version number in upper 16 bits and
-                minor version in lower 16 bits.
-=============== ======================================================
-
-* CREATE(1) and WRITE (5) command identifiers are unimplemented and
-  return `SMC_UNK`.
-
 --------------
 
-*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/components/context-management-library.rst b/docs/components/context-management-library.rst
new file mode 100644
index 0000000..56ba2ec
--- /dev/null
+++ b/docs/components/context-management-library.rst
@@ -0,0 +1,501 @@
+Context Management Library
+**************************
+
+This document provides an overview of the Context Management library implementation
+in Trusted Firmware-A (TF-A). It enumerates and describes the APIs implemented
+and their accessibility from other components at EL3.
+
+Overview
+========
+
+Arm TrustZone architecture facilitates hardware-enforced isolation between
+software running in various security states (Secure/Non-Secure/Realm).
+The general-purpose registers, most of the system registers and vector registers
+are not banked per world. When moving between the security states it is the
+responsibility of the secure monitor software (BL31(AArch64) / BL32(Aarch32))
+in TF-A, not the hardware, to save and restore register state.
+Refer to `Trustzone for AArch64`_ for more details.
+
+EL3 Runtime Firmware, also termed as secure monitor firmware, is integrated
+with a context management library to handle the context of the CPU, managing the
+saving and restoring of register states across the worlds.
+
+TF-A Context
+============
+
+In TF-A, the context is represented as a data structure used by the EL3 firmware
+to preserve the state of the CPU at the next lower exception level (EL) in a given
+security state and save enough EL3 metadata to be able to return to that exception
+level and security state. The memory for the context data structures are allocated
+in BSS section of EL3 firmware.
+
+In a trusted system at any instance, a given CPU could be executing in one of the
+security states (Non-Secure, Secure, Realm). Each world must have its
+configuration of system registers independent of other security states to access
+and execute any of the architectural features.
+
+If the CPU switches across security states (for example: from Non-secure to Secure
+or vice versa), the register contents, especially the ones that are not banked
+(EL2/EL1, vector, general-purpose registers), will be overwritten, as the software
+running in either state has the privileges to access them. Additionally, some of
+the architectural features enabled in the former security state will be unconditionally
+accessible in the latter security state as well. This can be a major concern when
+dealing with security-specific bits, as they need to be explicitly enabled or
+disabled in each state to prevent data leakage across the worlds.
+
+In general, an ideal trusted system should have Secure world-specific configurations
+that are not influenced by Normal World operations. Therefore, for each CPU, we
+need to maintain world-specific context to ensure that register entries from one
+world do not leak or impact the execution of the CPU in other worlds.
+This will help ensure the integrity and security of the system, preventing any
+unauthorized access or data corruption between the different security states.
+
+Design
+======
+
+The Context Management library in TF-A is designed to cover all the requirements
+for maintaining world-specific context essential for a trusted system.
+This includes implementing CPU context initialization and management routines,
+as well as other helper APIs that are required by dispatcher components in EL3
+firmware, which are collectively referred to as CPU Context Management.
+The APIs and their usecases are listed in detail under the :ref:`Library APIs`
+section.
+
+Originally, the Context Management library in TF-A was designed to cater for a
+two-world system, comprising of Non-Secure and Secure Worlds. In this case, the
+EL3 Firmware is assumed to be running in Secure World.
+With introduction of Realm Management Extension (RME), from Armv9.2 a system
+can have four distinct worlds (Non-Secure, Secure, Realm, Root).
+RME isolates EL3 from all other Security states and moves it into its own security
+state called root. EL3 firmware now runs at Root World and thereby is
+trusted from software in Non-secure, Secure, and Realm states.
+Refer to `Security States with RME`_ for more details.
+
+Key principles followed in designing the context management library :
+
+1. **EL3 should only initialize immediate used lower EL**
+
+Context Management library running at EL3 should only initialize and monitor the
+immediate used lower EL. This implies that, when S-EL2 is present in the system,
+EL3 should initialise and monitor S-EL2 registers only. S-EL1 registers should
+not be the concern of EL3 while S-EL2 is in place. In systems where S-EL2 is
+absent, S-EL1 registers should be initialised from EL3.
+
+2. **Decentralized model for context management**
+
+Each world (Non-Secure, Secure, and Realm) should have their separate component
+in EL3 responsible for their respective world context management.
+Both the Secure and Realm world have associated dispatcher components in EL3
+firmware to allow management of the respective worlds. For the Non-Secure world,
+PSCI Library (BL31)/context management library provides routines to help
+initialize the Non-Secure world context.
+
+3. **Flexibility for Dispatchers to select desired feature set to save and restore**
+
+Each feature is supported with a helper function ``is_feature_supported(void)``,
+to detect its presence at runtime. This helps dispatchers to select the desired
+feature set, and thereby save and restore the configuration associated with them.
+
+4. **Dynamic discovery of Feature enablement by EL3**
+
+TF-A supports three states for feature enablement at EL3, to make them available
+for lower exception levels.
+
+.. code:: c
+
+	#define FEAT_STATE_DISABLED	0
+	#define FEAT_STATE_ENABLED	1
+	#define FEAT_STATE_CHECK	2
+
+A pattern is established for feature enablement behavior.
+Each feature must support the 3 possible values with rigid semantics.
+
+- **FEAT_STATE_DISABLED** - all code relating to this feature is always skipped.
+  Firmware is unaware of this feature.
+
+- **FEAT_STATE_ALWAYS** - all code relating to this feature is always executed.
+  Firmware expects this feature to be present in hardware.
+
+- **FEAT_STATE_CHECK** - same as ``FEAT_STATE_ALWAYS`` except that the feature's
+  existence will be checked at runtime. Default on dynamic platforms (example: FVP).
+
+.. note::
+   ``FEAT_RAS`` is an exception here, as it impacts the execution of EL3 and
+   it is essential to know its presence at compile time. Refer to ``ENABLE_FEAT``
+   macro under :ref:`Build Options` section for more details.
+
+Code Structure
+==============
+
+`lib/el3_runtime/(aarch32/aarch64)`_ - Context library code directory.
+
+Source Files
+~~~~~~~~~~~~
+
+#. ``context_mgmt.c`` : consists of core functions that setup, save and restore
+   context for different security states alongside high level feature enablement
+   APIs for individual worlds.
+
+#. ``cpu_data_array.c`` : contains per_cpu_data structure instantiation.
+
+#. ``context.S`` : consists of functions that save and restore some of the context
+   structure members in assembly code.
+
+#. ``cpu_data.S`` : consists of helper functions to initialise per_cpu_data pointers.
+
+#. ``el3_common_macros.S`` : consists of macros to facilitate actions to be performed
+   during cold and warmboot and el3 registers initialisation in assembly code.
+
+Header Files
+~~~~~~~~~~~~
+
+#. ``context_mgmt.h`` :  contains the public interface to Context Management Library.
+
+#. ``context.h`` : contains the helper macros and definitions for context entries.
+
+#. ``cpu_data.h`` : contains the public interface to Per CPU data structure.
+
+#. ``context_debug.h`` : contains public interface to report context memory
+   utilisation across the security states.
+
+#. ``context_el2.h`` : internal header consisting of helper macros to access EL2
+   context entries. Used by ``context.h``.
+
+Apart from these files, we have some context related source files under ``BL1``
+and ``BL31`` directory. ``bl1_context_mgmt.c`` ``bl31_context_mgmt.c``
+
+Bootloader Images utilizing Context Management Library
+======================================================
+
++-------------------------------------------+-----------------------------+
+|   Bootloader                              | Context Management Library  |
++-------------------------------------------+-----------------------------+
+|   BL1                                     |       Yes                   |
++-------------------------------------------+-----------------------------+
+|   BL2                                     |       No                    |
++-------------------------------------------+-----------------------------+
+|   BL31 (Aarch64- EL3runtime firmware)     |       Yes                   |
++-------------------------------------------+-----------------------------+
+|   BL32 (Aarch32- EL3runtime firmware)     |       Yes                   |
++-------------------------------------------+-----------------------------+
+
+CPU Data Structure
+==================
+For a given system, depending on the CPU count, the platform statically
+allocates memory for the CPU data structure.
+
+.. code:: c
+
+	/* The per_cpu_ptr_cache_t space allocation */
+	cpu_data_t percpu_data[PLATFORM_CORE_COUNT];
+
+This CPU data structure has a member element with an array of pointers to hold
+the Non-Secure, Realm and Secure security state context structures as listed below.
+
+.. code:: c
+
+	typedef struct cpu_data {
+	#ifdef __aarch64__
+	void *cpu_context[CPU_DATA_CONTEXT_NUM];
+	#endif
+
+	....
+	....
+
+	}cpu_data_t;
+
+|CPU Data Structure|
+
+At runtime, ``cpu_context[CPU_DATA_CONTEXT_NUM]`` array will be intitialised with
+the Secure, Non-Secure and Realm context structure addresses to ensure proper
+handling of the register state.
+See :ref:`Library APIs` section for more details.
+
+CPU Context and Memory allocation
+=================================
+
+CPU Context
+~~~~~~~~~~~
+The members of the context structure used by the EL3 firmware to preserve the
+state of CPU across exception levels for a given security state are listed below.
+
+.. code:: c
+
+	typedef struct cpu_context {
+	gp_regs_t gpregs_ctx;
+	el3_state_t el3state_ctx;
+	el1_sysregs_t el1_sysregs_ctx;
+
+	#if CTX_INCLUDE_EL2_REGS
+	el2_sysregs_t el2_sysregs_ctx;
+	#endif
+
+	#if CTX_INCLUDE_FPREGS
+	fp_regs_t fpregs_ctx;
+	#endif
+
+	cve_2018_3639_t cve_2018_3639_ctx;
+	#if CTX_INCLUDE_PAUTH_REGS
+	pauth_t pauth_ctx;
+	#endif
+
+	#if CTX_INCLUDE_MPAM_REGS
+	mpam_t	mpam_ctx;
+	#endif
+
+	} cpu_context_t;
+
+Context Memory Allocation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+CPUs maintain their context per world. The individual context memory allocation
+for each CPU per world is allocated by the world-specific dispatcher components
+at compile time as shown below.
+
+|Context memory allocation|
+
+NS-Context Memory
+~~~~~~~~~~~~~~~~~
+It's important to note that the Normal world doesn't possess the dispatcher
+component found in the Secure and Realm worlds. Instead, the PSCI library at EL3
+handles memory allocation for ``Non-Secure`` world context for all CPUs.
+
+.. code:: c
+
+	static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT];
+
+Secure-Context Memory
+~~~~~~~~~~~~~~~~~~~~~
+Secure World dispatcher (such as SPMD) at EL3 allocates the memory for ``Secure``
+world context of all CPUs.
+
+.. code:: c
+
+	static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
+
+Realm-Context Memory
+~~~~~~~~~~~~~~~~~~~~
+Realm World dispatcher (RMMD) at EL3 allocates the memory for ``Realm`` world
+context of all CPUs.
+
+.. code:: c
+
+	rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT];
+
+To summarize, the world-specific context structures are synchronized with
+per-CPU data structures, which means that each CPU will have an array of pointers
+to individual worlds. The figure below illustrates the same.
+
+|CPU Context Memory Configuration|
+
+Context Setup/Initialization
+============================
+
+The CPU has been assigned context structures for every security state, which include
+Non-Secure, Secure and Realm. It is crucial to initialize each of these structures
+during the bootup of every CPU before they enter any security state for the
+first time. This section explains the specifics of how the initialization of
+every CPU context takes place during both cold and warm boot paths.
+
+Context Setup during Cold boot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The cold boot path is mainly executed by the primary CPU, other than essential
+CPU initialization executed by all CPUs. After executing BL1 and BL2, the Primary
+CPU jumps to the BL31 image for runtime services initialization.
+During this process, the per_cpu_data structure gets initialized with statically
+allocated world-specific context memory.
+
+Later in the cold boot sequence, the BL31 image at EL3 checks for the presence
+of a Secure world image at S-EL2. If detected, it invokes the secure context
+initialization sequence under SPMD. Additionally, based on RME enablement,
+the Realm context gets initialized from the RMMD at EL3. Finally, before exiting
+to the normal world, the Non-Secure context gets initialized via the context
+management library. At this stage, all Primary CPU contexts are initialized
+and the CPU exits EL3 to enter the Normal world.
+
+|Context Init ColdBoot|
+
+.. note::
+   The figure above illustrates a scenario on FVP for one of the build
+   configurations with TFTF component at NS-EL2.
+
+Context Setup during Warmboot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+During a warm boot sequence, the primary CPU is responsible for powering on the
+secondary CPUs. Refer to :ref:`CPU Reset` and :ref:`Firmware Design` sections for
+more details on the warm boot.
+
+|Context Init WarmBoot|
+
+The primary CPU initializes the Non-Secure context for the secondary CPU while
+restoring re-entry information for the Non-Secure world.
+It initialises via ``cm_init_context_by_index(target_idx, ep )``.
+
+``psci_warmboot_entrypoint()`` is the warm boot entrypoint procedure.
+During the warm bootup process, secondary CPUs have their secure context
+initialized through SPMD at EL3. Upon successful SP initialization, the SPD
+power management operations become shared with the PSCI library. During this
+process, the SPMD duly registers its handlers with the PSCI library.
+
+.. code:: c
+
+	file: psci_common.c
+	const spd_pm_ops_t *psci_spd_pm;
+
+	file: spmd_pm.c
+	const spd_pm_ops_t spmd_pm = {
+	.svc_on_finish = spmd_cpu_on_finish_handler,
+	.svc_off = spmd_cpu_off_handler
+	}
+
+Secondary CPUs during their bootup in the ``psci_cpu_on_finish()`` routine get
+their secure context initialised via the registered SPMD handler
+``spmd_cpu_on_finish_handler()`` at EL3.
+The figure above illustrates the same with reference of Primary CPU running at
+NS-EL2.
+
+.. _Library APIs:
+
+Library APIs
+============
+
+The public APIs and types can be found in ``include/lib/el3_runtime/context_management.h``
+and this section is intended to provide additional details and clarifications.
+
+Context Initialization for Individual Worlds
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The library implements high level APIs for the CPUs in setting up their individual
+context for each world (Non-Secure, Secure and Realm).
+
+.. c:function::	static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep);
+
+This function is responsible for the general context initialization that applies
+to all worlds. It will be invoked first, before calling the individual
+world-specific context setup APIs.
+
+.. c:function::	static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *ep);
+.. c:function::	static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_info *ep);
+.. c:function::	static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_info *ep);
+
+Depending on the security state that the CPU needs to enter, the respective
+world-specific context setup handlers listed above will be invoked once per-CPU
+to set up the context for their execution.
+
+.. c:function::	void cm_manage_extensions_el3(void)
+
+This function initializes all EL3 registers whose values do not change during the
+lifetime of EL3 runtime firmware. It is invoked from each CPU via the cold boot
+path ``bl31_main()`` and in the WarmBoot entry path ``void psci_warmboot_entrypoint()``.
+
+Runtime Save and Restore of Registers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+EL1 Registers
+-------------
+
+.. c:function::	void cm_el1_sysregs_context_save(uint32_t security_state);
+.. c:function::	void cm_el1_sysregs_context_restore(uint32_t security_state);
+
+These functions are utilized by the world-specific dispatcher components running
+at EL3 to facilitate the saving and restoration of the EL1 system registers
+during a world switch.
+
+EL2 Registers
+-------------
+
+.. c:function::	void cm_el2_sysregs_context_save(uint32_t security_state);
+.. c:function::	void cm_el2_sysregs_context_restore(uint32_t security_state);
+
+These functions are utilized by the world-specific dispatcher components running
+at EL3 to facilitate the saving and restoration of the EL2 system registers
+during a world switch.
+
+Pauth Registers
+---------------
+
+Pointer Authentication feature is enabled by default for Non-Secure world and
+disabled for Secure and Realm worlds. In this case, we don't need to explicitly
+save and restore the Pauth registers during world switch.
+However, ``CTX_INCLUDE_PAUTH_REGS`` flag is explicitly used to enable Pauth for
+lower exception levels of Secure and Realm worlds. In this scenario, we save the
+general purpose and Pauth registers while we enter EL3 from lower ELs via
+``prepare_el3_entry`` and restore them back while we exit EL3 to lower ELs
+via ``el3_exit``.
+
+.. code:: c
+
+	.macro save_gp_pmcr_pauth_regs
+	func restore_gp_pmcr_pauth_regs
+
+Feature Enablement for Individual Worlds
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function::	static void manage_extensions_nonsecure(cpu_context_t *ctx);
+.. c:function::	static void manage_extensions_secure(cpu_context_t *ctx);
+.. c:function::	static void manage_extensions_realm(cpu_context_t *ctx)
+
+Functions that allow the enabling and disabling of architectural features for
+each security state. These functions are invoked from the top-level setup APIs
+during context initialization.
+
+Further, a pattern is established for feature enablement code (AArch64).
+Each feature implements following APIs as applicable:
+Note: (``xxx`` is the name of the feature in the APIs)
+
+- ``is_feat_xxx_supported()`` and ``is_feat_xxx_present()`` - mandatory for all features.
+
+- ``xxx_enable(cpu_context * )`` and ``xxx_disable(cpu_context * )`` - optional
+  functions to enable the feature for the passed context only. To be called in
+  the respective world's setup_context to select behaviour.
+
+- ``xxx_init_el3()`` - optional function to enable the feature in-place in any EL3
+  registers that are never context switched. The values they write must never
+  change, otherwise the functions mentioned in previous point should be used.
+  Invoked from ``cm_manage_extensions_el3()``.
+
+- ``xxx_init_el2_unused()`` - optional function to enable the feature in-place
+  in any EL2 registers that are necessary for execution in EL1 with no EL2 present.
+
+The above mentioned rules, followed for ``FEAT_SME`` is shown below:
+
+.. code:: c
+
+	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);
+
+Per-world Context
+=================
+
+Apart from the CPU context structure, we have another structure to manage some
+of the EL3 system registers whose values are identical across all the CPUs
+referred to as ``per_world_context_t``.
+The Per-world context structure is intended for managing EL3 system registers with
+identical values across all CPUs, requiring only a singular context entry for each
+individual world. This structure operates independently of the CPU context
+structure and is intended to manage specific EL3 registers.
+
+.. code-block:: c
+
+	typedef struct per_world_context {
+		uint64_t ctx_cptr_el3;
+		uint64_t ctx_zcr_el3;
+		uint64_t ctx_mpam3_el3;
+	} per_world_context_t;
+
+These functions facilitate the activation of architectural extensions that possess
+identical values across all cores for the individual Non-secure, Secure, and
+Realm worlds.
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+
+.. |Context Memory Allocation| image:: ../resources/diagrams/context_memory_allocation.png
+.. |CPU Context Memory Configuration| image:: ../resources/diagrams/cpu_data_config_context_memory.png
+.. |CPU Data Structure| image:: ../resources/diagrams/percpu-data-struct.png
+.. |Context Init ColdBoot| image:: ../resources/diagrams/context_init_coldboot.png
+.. |Context Init WarmBoot| image:: ../resources/diagrams/context_init_warmboot.png
+.. _Trustzone for AArch64: https://developer.arm.com/documentation/102418/0101/TrustZone-in-the-processor/Switching-between-Security-states
+.. _Security States with RME: https://developer.arm.com/documentation/den0126/0100/Security-states
+.. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime
\ No newline at end of file
diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst
index 029f324..b8b4519 100644
--- a/docs/components/fconf/index.rst
+++ b/docs/components/fconf/index.rst
@@ -147,3 +147,4 @@
   fconf_properties
   amu-bindings
   mpmm-bindings
+  tb_fw_bindings
diff --git a/docs/components/fconf/tb_fw_bindings.rst b/docs/components/fconf/tb_fw_bindings.rst
new file mode 100644
index 0000000..aee3b8d
--- /dev/null
+++ b/docs/components/fconf/tb_fw_bindings.rst
@@ -0,0 +1,159 @@
+Trusted Boot Firmware Configuration bindings
+============================================
+
+This document defines the nodes and properties used to define the Trusted-Boot
+firmware configuration. Platform owners are advised to define shared bindings
+here. If a binding does not generalize, they should be documented
+alongside platform documentation. There is no guarantee of backward
+compatibility with the nodes and properties outlined in this context.
+
+Trusted Boot Firmware Configuration
+-----------------------------------
+
+- compatible [mandatory]
+   - value type: <string>
+   - Should be the string ``"<plat>,tb_fw"``, where ``<plat>`` is the name of the
+     platform (i.e. ``"arm,tb_fw"``).
+
+- disable_auth [mandatory]
+   - value type: <u32>
+   - Flag used to dynamically disable authentication for development purposes.
+     Has two possible values: 0 or 1. Setting the flag to 1 disables
+     authentication.
+
+- mbedtls_heap_addr [mandatory]
+   - value type: <u64>
+   - Base address of the dynamically allocated Mbed TLS heap. This is given as a placeholder.
+
+- mbedtls_heap_size [mandatory]
+   - value type: <u32>
+   - Size of the Mbed TLS heap.
+
+IO FIP Handles
+--------------
+
+- compatible [mandatory]
+   - value type: <string>
+   - Should be the string ``"<plat>,io-fip-handle"``, where ``<plat>`` is the name of the
+     platform (i.e. ``"arm,io-fip-handle"``).
+
+- scp_bl2_uuid [mandatory]
+   - value type: <string>
+   - SCP Firmware SCP_BL2 UUID
+
+- bl31_uuid [mandatory]
+   - value type: <string>
+   - EL3 Runtime Firmware BL31 UUID
+
+- bl32_uuid [mandatory]
+   - value type: <string>
+   - Secure Payload BL32 (Trusted OS) UUID
+
+- bl32_extra1_uuid [mandatory]
+   - value type: <string>
+   - Secure Payload BL32_EXTRA1 (Trusted OS Extra1) UUID
+
+- bl32_extra2_uuid [mandatory]
+   - value type: <string>
+   - Secure Payload BL32_EXTRA2 (Trusted OS Extra2) UUID
+
+- bl33_uuid [mandatory]
+   - value type: <string>
+   - Non-Trusted Firmware BL33 UUID
+
+- hw_cfg_uuid [mandatory]
+   - value type: <string>
+   - HW_CONFIG (e.g. Kernel DT) UUID
+
+- soc_fw_cfg_uuid [mandatory]
+   - value type: <string>
+   - SOC Firmware Configuration SOC_FW_CONFIG UUID
+
+- tos_fw_cfg_uuid [mandatory]
+   - value type: <string>
+   - Trusted OS Firmware Configuration TOS_FW_CONFIG UUID
+
+- nt_fw_cfg_uuid [mandatory]
+   - value type: <string>
+   - Non-Trusted Firmware Configuration NT_FW_CONFIG UUID
+
+- cca_cert_uuid [optional]
+   - value type: <string>
+   - CCA Content Certificate UUID
+
+- core_swd_cert_uuid [optional]
+   - value type: <string>
+   - Core SWD Key Certificate UUID
+
+- plat_cert_uuid [optional]
+   - value type: <string>
+   - Core SWD Key Certificate UUID
+
+- t_key_cert_uuid [optional]
+   - value type: <string>
+   - Trusted Key Certificate UUID
+
+- scp_fw_key_uuid [optional]
+   - value type: <string>
+   - SCP Firmware Key UUID
+
+- soc_fw_key_uuid [optional]
+   - value type: <string>
+   - SOC Firmware Key UUID
+
+- tos_fw_key_cert_uuid [optional]
+   - value type: <string>
+   - TOS Firmware Key UUID
+
+- nt_fw_key_cert_uuid [optional]
+   - value type: <string>
+   - Non-Trusted Firmware Key UUID
+
+- scp_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - SCP Firmware Content Certificate UUID
+
+- soc_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - SOC Firmware Content Certificate UUID
+
+- tos_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - TOS Firmware Content Certificate UUID
+
+- nt_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - Non-Trusted Firmware Content Certificate UUID
+
+- plat_sp_content_cert_uuid [optional]
+   - value type: <string>
+   - Platform Secure Partition Content Certificate UUID
+
+
+Secure Partitions
+-----------------
+
+- compatible [mandatory]
+   - value type: <string>
+   - Should be the string ``"<plat>,sp"``, where ``<plat>`` is the name of the
+     platform (i.e. ``"arm,sp"``).
+
+- uuid [mandatory]
+   - value type: <string>
+   - A string identifying the UUID of the service implemented by this partition.
+     The UUID format is described in RFC 4122.
+
+- load-address [mandatory]
+   - value type: <u32>
+   - Physical base address of the partition in memory. Absence of this field
+     indicates that the partition is position independent and can be loaded at
+     any address chosen at boot time.
+
+- owner [optional]
+   - value type: <string>
+   - A string property representing the name of the owner of the secure
+     partition, which may be the silicon or platform provider.
+
+--------------
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/firmware-update.rst b/docs/components/firmware-update.rst
index 1ba1e1c..eda7852 100644
--- a/docs/components/firmware-update.rst
+++ b/docs/components/firmware-update.rst
@@ -494,4 +494,4 @@
 .. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
 .. |Flow Diagram| image:: ../resources/diagrams/fwu_flow.png
 .. |FWU state machine| image:: ../resources/diagrams/fwu_states.png
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
index 9d85bef..78d2f12 100644
--- a/docs/components/granule-protection-tables-design.rst
+++ b/docs/components/granule-protection-tables-design.rst
@@ -1,17 +1,17 @@
 Granule Protection Tables Library
 =================================
 
-This document describes the design of the granule protection tables (GPT)
+This document describes the design of the Granule Protection Tables (GPT)
 library used by Trusted Firmware-A (TF-A). This library provides the APIs needed
 to initialize the GPTs based on a data structure containing information about
 the systems memory layout, configure the system registers to enable granule
 protection checks based on these tables, and transition granules between
 different PAS (physical address spaces) at runtime.
 
-Arm CCA adds two new security states for a total of four: root, realm, secure, and
-non-secure. In addition to new security states, corresponding physical address
-spaces have been added to control memory access for each state. The PAS access
-allowed to each security state can be seen in the table below.
+Arm CCA adds two new security states for a total of four: root, realm, secure,
+and non-secure. In addition to new security states, corresponding physical
+address spaces have been added to control memory access for each state. The PAS
+access allowed to each security state can be seen in the table below.
 
 .. list-table:: Security states and PAS access rights
    :widths: 25 25 25 25 25
@@ -45,12 +45,15 @@
 
 The GPT can function as either a 1 level or 2 level lookup depending on how a
 PAS region is configured. The first step is the level 0 table, each entry in the
-level 0 table controls access to a relatively large region in memory (block
+level 0 table controls access to a relatively large region in memory (GPT Block
 descriptor), and the entire region can belong to a single PAS when a one step
-mapping is used, or a level 0 entry can link to a level 1 table where relatively
-small regions (granules) of memory can be assigned to different PAS with a 2
-step mapping. The type of mapping used for each PAS is determined by the user
-when setting up the configuration structure.
+mapping is used. Level 0 entry can also link to a level 1 table (GPT Table
+descriptor) with a 2 step mapping. To change PAS of a region dynamically, the
+region must be mapped in Level 1 table.
+
+The Level 1 tables entries with the same PAS can be combined to form a
+contiguous block entry using GPT Contiguous descriptor. More details about this
+is explained in the following section.
 
 Design Concepts and Interfaces
 ------------------------------
@@ -73,7 +76,8 @@
 GPT setup is split into two parts: table creation and runtime initialization. In
 the table creation step, a data structure containing information about the
 desired PAS regions is passed into the library which validates the mappings,
-creates the tables in memory, and enables granule protection checks. In the
+creates the tables in memory, and enables granule protection checks. It also
+allocates memory for fine-grained locks adjacent to the L0 tables. In the
 runtime initialization step, the runtime firmware locates the existing tables in
 memory using the GPT register configuration and saves important data to a
 structure used by the granule transition service which will be covered more
@@ -85,6 +89,10 @@
 runtime initialization API calls can be seen in
 ``plat/arm/common/arm_bl31_setup.c``.
 
+During the table creation time, the GPT lib opportunistically fuses contiguous
+GPT L1 entries having the same PAS. The maximum size of
+supported contiguous blocks is defined by ``RME_GPT_MAX_BLOCK`` build option.
+
 Defining PAS regions
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -115,8 +123,13 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The GPT initialization APIs require memory to be passed in for the tables to be
-constructed, ``gpt_init_l0_tables`` takes a memory address and size for building
-the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for
+constructed. The ``gpt_init_l0_tables`` API takes a memory address and size for
+building the level 0 tables and also memory for allocating the fine-grained bitlock
+data structure. The amount of memory needed for bitlock structure is controlled via
+``RME_GPT_BITLOCK_BLOCK`` config which defines the block size for each bit of the
+the bitlock.
+
+The ``gpt_init_pas_l1_tables`` API takes an address and size for
 building the level 1 tables which are linked from level 0 descriptors. The
 tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place
 its level 0 table in SRAM and its level 1 table(s) in DRAM.
@@ -124,12 +137,28 @@
 Granule Transition Service
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE
-ownership to be changed using SMC calls. Non-secure granules can be transitioned
-to either realm or secure space, and realm and secure granules can be
-transitioned back to non-secure. This library only allows memory mapped as
-granules to be transitioned, memory mapped as blocks have their GPIs fixed after
-table creation.
+The Granule Transition Service allows memory mapped with
+``GPT_MAP_REGION_GRANULE`` ownership to be changed using SMC calls. Non-secure
+granules can be transitioned to either realm or secure space, and realm and
+secure granules can be transitioned back to non-secure. This library only
+allows Level 1 entries to be transitioned. The lib may either shatter
+contiguous blocks or fuse adjacent GPT entries to form a contiguous block
+opportunistically. Depending on the maximum block size, the fuse operation may
+propogate to higher block sizes as allowed by RME Architecture. Thus a higher
+maximum block size may have a higher runtime cost due to software operations
+that need to be performed for fuse to bigger block sizes. This cost may
+be offset by better TLB performance due to the higher block size and platforms
+need to make the trade-off decision based on their particular workload.
+
+Locking Scheme
+~~~~~~~~~~~~~~
+
+During Granule Transition access to L1 tables is controlled by a lock to ensure
+that no more than one CPU is allowed to make changes at any given time.
+The granularity of the lock is defined by ``RME_GPT_BITLOCK_BLOCK`` build option
+which defines the size of the memory block protected by one bit of ``bitlock``
+structure. Setting this option to 0 chooses a single spinlock for all GPT L1
+table entries.
 
 Library APIs
 ------------
@@ -196,7 +225,9 @@
   is greater. L0 table size is the total protected space (PPS) divided by the
   size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
   (8 bytes). ((PPS / L0GPTSZ) * 8)
-* The L0 memory size must be greater than or equal to the table size.
+* The L0 memory size must be greater than the table size and have enough space
+  to allocate array of ``bitlock`` structures at the end of L0 table if
+  required (``RME_GPT_BITLOCK_BLOCK`` is not 0).
 * The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
 
 The L1 memory also has some constraints.
@@ -223,6 +254,24 @@
 And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
 tables must be aligned to 4096 bytes.
 
+Sample calculation for bitlock array size
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let PGS=GPCCR_PPS_256TB and RME_GPT_BITLOCK_BLOCK=1
+
+The size of bit lock array in bits is the total protected space (PPS) divided
+by the size of memory block per bit. The size of memory block
+is ``RME_GPT_BITLOCK_BLOCK`` (number of 512MB blocks per bit) times
+512MB (0x20000000). This is then divided by the number of bits in ``bitlock``
+structure (8) to get the size of bit array in bytes.
+
+In other words, we can find the total size of ``bitlock`` array
+in bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 *  8).
+
+Substitute values to get this: 0x1000000000000 / (1 * 0x20000000 * 8)
+
+And solve to get 0x10000 bytes.
+
 Sample calculation for L1 table size and alignment
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/components/index.rst b/docs/components/index.rst
index 30d80fc..3697026 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -26,3 +26,6 @@
    realm-management-extension
    rmm-el3-comms-spec
    granule-protection-tables-design
+   ven-el3-service
+   ven-el3-debugfs
+   context-management-library
diff --git a/docs/components/platform-interrupt-controller-API.rst b/docs/components/platform-interrupt-controller-API.rst
index 4de39d1..8cd4bae 100644
--- a/docs/components/platform-interrupt-controller-API.rst
+++ b/docs/components/platform-interrupt-controller-API.rst
@@ -282,9 +282,28 @@
 that it's overwriting.
 
 In case of Arm standard platforms using GIC, the implementation of the API
-inserts to order memory updates before updating mask, then writes to the GIC
-*Priority Mask Register*, and make sure memory updates are visible before
-potential trigger due to mask update.
+inserts barriers to order memory updates before updating mask,
+then writes to the GIC *Priority Mask Register*, and make sure memory updates
+are visible before potential trigger due to mask update.
+
+Function: unsigned int plat_ic_deactivate_priority(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : unsigned int
+    Return   : int
+
+This API performs the operations of plat_ic_set_priority_mask along with
+calling the errata workaround gicv3_apply_errata_wa_2384374(). This is
+performed when priority mask is restored to it's older value. This API returns
+the current priority value that it's overwriting.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+inserts barriers to order memory updates before updating mask, then writes
+to the GIC *Priority Mask Register*, and make sure memory updates
+are visible before potential trigger due to mask update, and
+applies 2384374 GIC errata workaround to process pending interrupt packets.
 
 .. _plat_ic_get_interrupt_id:
 
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 5f0b5ab..5fbd7fd 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -53,7 +53,7 @@
     consistency with the versioning schemes used in other parts of RMM.
 
 This document specifies the 0.2 version of Boot Interface ABI and RMM-EL3
-services specification and the 0.2 version of the Boot Manifest.
+services specification and the 0.3 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
 
@@ -182,17 +182,20 @@
 
 This Boot Manifest is versioned independently of the Boot Interface, to help
 evolve the former independent of the latter.
-The current version for the Boot Manifest is ``v0.2`` and the rules explained
+The current version for the Boot Manifest is ``v0.3`` and the rules explained
 in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
 
-The Boot Manifest v0.2 has the following fields:
+The Boot Manifest v0.3 has the following fields:
 
-   - version : Version of the Manifest (v0.2)
+   - version : Version of the Manifest (v0.3)
    - plat_data : Pointer to the platform specific data and not specified by this
      document. These data are optional and can be NULL.
    - plat_dram : Structure encoding the NS DRAM information on the platform. This
-     field is also optional and platform can choose to zero out this structure if
+     field is optional and platform can choose to zero out this structure if
      RMM does not need EL3 to send this information during the boot.
+   - plat_console : Structure encoding the list of consoles for RMM use on the
+     platform. This field is optional and platform can choose to not populate
+     the console list if this is not needed by the RMM for this platform.
 
 For the current version of the Boot Manifest, the core manifest contains a pointer
 to the platform data. EL3 must ensure that the whole Boot Manifest, including
@@ -533,23 +536,25 @@
 RMM-EL3 Boot Manifest structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The RMM-EL3 Boot Manifest v0.2 structure contains platform boot information passed
-from EL3 to RMM. The size of the Boot Manifest is 40 bytes.
+The RMM-EL3 Boot Manifest v0.3 structure contains platform boot information passed
+from EL3 to RMM. The size of the Boot Manifest is 64 bytes.
 
 The members of the RMM-EL3 Boot Manifest structure are shown in the following
 table:
 
-+-----------+--------+----------------+----------------------------------------+
-|   Name    | Offset |     Type       |               Description              |
-+===========+========+================+========================================+
-| version   |   0    |   uint32_t     | Boot Manifest version                  |
-+-----------+--------+----------------+----------------------------------------+
-| padding   |   4    |   uint32_t     | Reserved, set to 0                     |
-+-----------+--------+----------------+----------------------------------------+
-| plat_data |   8    |   uintptr_t    | Pointer to Platform Data section       |
-+-----------+--------+----------------+----------------------------------------+
-| plat_dram |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
-+-----------+--------+----------------+----------------------------------------+
++--------------+--------+----------------+----------------------------------------+
+|   Name       | Offset |     Type       |               Description              |
++==============+========+================+========================================+
+| version      |   0    |   uint32_t     | Boot Manifest version                  |
++--------------+--------+----------------+----------------------------------------+
+| padding      |   4    |   uint32_t     | Reserved, set to 0                     |
++--------------+--------+----------------+----------------------------------------+
+| plat_data    |   8    |   uintptr_t    | Pointer to Platform Data section       |
++--------------+--------+----------------+----------------------------------------+
+| plat_dram    |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
++--------------+--------+----------------+----------------------------------------+
+| plat_console |   40   | console_list   | List of consoles available to RMM      |
++--------------+--------+----------------+----------------------------------------+
 
 .. _ns_dram_info_struct:
 
@@ -587,5 +592,47 @@
 |   size    |   8    |   uint64_t     | Size of bank in bytes                  |
 +-----------+--------+----------------+----------------------------------------+
 
+.. _console_list_struct:
+
+Console List structure
+~~~~~~~~~~~~~~~~~~~~~~
+
+Console List structure contains information about the available consoles for RMM.
+The members of this structure are shown in the table below:
+
++--------------+--------+----------------+----------------------------------------+
+|   Name       | Offset |     Type       |               Description              |
++==============+========+================+========================================+
+| num_consoles |   0    |   uint64_t     | Number of consoles                     |
++--------------+--------+----------------+----------------------------------------+
+| consoles     |   8    | console_info * | Pointer to 'console_info'[] array      |
++--------------+--------+----------------+----------------------------------------+
+| checksum     |   16   |   uint64_t     | Checksum                               |
++--------------+--------+----------------+----------------------------------------+
+
+Checksum is calculated as two's complement sum of 'num_consoles', 'consoles'
+pointer and the consoles array pointed by it.
+
+.. _console_info_struct:
+
+Console Info structure
+~~~~~~~~~~~~~~~~~~~~~~
+
+Console Info structure contains information about each Console available to RMM.
 
++-----------+--------+---------------+----------------------------------------+
+|   Name    | Offset |     Type      |               Description              |
++===========+========+===============+========================================+
+| base      |   0    |   uintptr_t   | Console Base address                   |
++-----------+--------+---------------+----------------------------------------+
+| map_pages |   8    |   uint64_t    | Num of pages to map for console MMIO   |
++-----------+--------+---------------+----------------------------------------+
+| name      |   16   |   char[]      | Name of console                        |
++-----------+--------+---------------+----------------------------------------+
+| clk_in_hz |   24   |   uint64_t    | UART clock (in hz) for console         |
++-----------+--------+---------------+----------------------------------------+
+| baud_rate |   32   |   uint64_t    | Baud rate                              |
++-----------+--------+---------------+----------------------------------------+
+| flags     |   40   |   uint64_t    | Additional flags (RES0)                |
++-----------+--------+---------------+----------------------------------------+
 
diff --git a/docs/components/romlib-design.rst b/docs/components/romlib-design.rst
index d34b3cc..62c173a 100644
--- a/docs/components/romlib-design.rst
+++ b/docs/components/romlib-design.rst
@@ -74,10 +74,10 @@
 Script
 ~~~~~~
 
-There is a ``romlib_generate.py`` Python script that generates the necessary
+There is a ``romlib_generator.py`` Python script that generates the necessary
 files for the "library at ROM" to work. It implements multiple functions:
 
-1. ``romlib_generate.py gentbl [args]`` - Generates the jump table by parsing
+1. ``romlib_generator.py gentbl [args]`` - Generates the jump table by parsing
    the index file.
 
 2. ``romlib_generator.py genvar [args]`` - Generates the jump table global
@@ -93,10 +93,10 @@
    generate a dependency file of the included index files which can be directly
    used in makefiles.
 
-Each ``romlib_generate.py`` function has its own manual which is accessible by
+Each ``romlib_generator.py`` function has its own manual which is accessible by
 runing ``romlib_generator.py [function] --help``.
 
-``romlib_generate.py`` requires Python 3 environment.
+``romlib_generator.py`` requires Python 3 environment.
 
 
 Patching of functions in library at ROM
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 4834d3a..b6f4219 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -215,7 +215,7 @@
     ARM_ARCH_MINOR=5 \
     BRANCH_PROTECTION=1 \
     CTX_INCLUDE_PAUTH_REGS=1 \
-    ENABLE_FEAT_MTE=1 \
+    ENABLE_FEAT_MTE2=1 \
     BL32=<path-to-hafnium-binary> \
     BL33=<path-to-bl33-binary> \
     SP_LAYOUT_FILE=sp_layout.json \
@@ -233,7 +233,7 @@
     ARM_ARCH_MINOR=5 \
     BRANCH_PROTECTION=1 \
     CTX_INCLUDE_PAUTH_REGS=1 \
-    ENABLE_FEAT_MTE=1 \
+    ENABLE_FEAT_MTE2=1 \
     BL32=<path-to-hafnium-binary> \
     BL33=<path-to-bl33-binary> \
     SP_LAYOUT_FILE=sp_layout.json \
diff --git a/docs/components/ven-el3-debugfs.rst b/docs/components/ven-el3-debugfs.rst
new file mode 100644
index 0000000..8629d70
--- /dev/null
+++ b/docs/components/ven-el3-debugfs.rst
@@ -0,0 +1,343 @@
+DebugFS interface
+=================
+
+The optional DebugFS interface is accessed through a Vendor specific EL3 service. Refer
+to the component documentation for details.
+
+String parameters are passed through a shared buffer using a specific union:
+
+.. code:: c
+
+    union debugfs_parms {
+        struct {
+            char fname[MAX_PATH_LEN];
+        } open;
+
+        struct mount {
+            char srv[MAX_PATH_LEN];
+            char where[MAX_PATH_LEN];
+            char spec[MAX_PATH_LEN];
+        } mount;
+
+        struct {
+            char path[MAX_PATH_LEN];
+            dir_t dir;
+        } stat;
+
+        struct {
+            char oldpath[MAX_PATH_LEN];
+            char newpath[MAX_PATH_LEN];
+        } bind;
+    };
+
+Format of the dir_t structure as such:
+
+.. code:: c
+
+    typedef struct {
+        char		name[NAMELEN];
+        long		length;
+        unsigned char	mode;
+        unsigned char	index;
+        unsigned char	dev;
+        qid_t		qid;
+    } dir_t;
+
+
+* Identifiers
+
+======================== =============================================
+SMC_OK                   0
+SMC_UNK                  -1
+DEBUGFS_E_INVALID_PARAMS -2
+======================== =============================================
+
+======================== =============================================
+MOUNT                    0
+CREATE                   1
+OPEN                     2
+CLOSE                    3
+READ                     4
+WRITE                    5
+SEEK                     6
+BIND                     7
+STAT                     8
+INIT                     10
+VERSION                  11
+======================== =============================================
+
+MOUNT
+~~~~~
+
+Description
+^^^^^^^^^^^
+This operation mounts a blob of data pointed to by path stored in `src`, at
+filesystem location pointed to by path stored in `where`, using driver pointed
+to by path in `spec`.
+
+Parameters
+^^^^^^^^^^
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``MOUNT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed
+=============== ==========================================================
+
+OPEN
+~~~~
+
+Description
+^^^^^^^^^^^
+This operation opens the file path pointed to by `fname`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``OPEN``
+uint32_t mode
+======== ============================================================
+
+mode can be one of:
+
+.. code:: c
+
+    enum mode {
+        O_READ   = 1 << 0,
+        O_WRITE  = 1 << 1,
+        O_RDWR   = 1 << 2,
+        O_BIND   = 1 << 3,
+        O_DIR    = 1 << 4,
+        O_STAT   = 1 << 5
+    };
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed
+
+uint32_t        w1: file descriptor id on success.
+=============== ==========================================================
+
+CLOSE
+~~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation closes a file described by a file descriptor obtained by a
+previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``CLOSE``
+uint32_t File descriptor id returned by OPEN
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed
+=============== ==========================================================
+
+READ
+~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation reads a number of bytes from a file descriptor obtained by
+a previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``READ``
+uint32_t File descriptor id returned by OPEN
+uint32_t Number of bytes to read
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+On success, the read data is retrieved from the shared buffer after the
+operation.
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed
+
+uint32_t        w1: number of bytes read on success.
+=============== ==========================================================
+
+SEEK
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Move file pointer for file described by given `file descriptor` of given
+`offset` related to `whence`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``SEEK``
+uint32_t File descriptor id returned by OPEN
+sint32_t offset in the file relative to whence
+uint32_t whence
+======== ============================================================
+
+whence can be one of:
+
+========= ============================================================
+KSEEK_SET 0
+KSEEK_CUR 1
+KSEEK_END 2
+========= ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed
+=============== ==========================================================
+
+BIND
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Create a link from `oldpath` to `newpath`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``BIND``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed
+=============== ==========================================================
+
+STAT
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Perform a stat operation on provided file `name` and returns the directory
+entry statistics into `dir`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``STAT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed
+=============== ==========================================================
+
+INIT
+~~~~
+
+Description
+^^^^^^^^^^^
+Initial call to setup the shared exchange buffer. Notice if successful once,
+subsequent calls fail after a first initialization. The caller maps the same
+page frame in its virtual space and uses this buffer to exchange string
+parameters with filesystem primitives.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``INIT``
+uint64_t Physical address of the shared buffer.
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if already initialized,
+                or internal error occurred.
+=============== ======================================================
+
+VERSION
+~~~~~~~
+
+Description
+^^^^^^^^^^^
+Returns the debugfs interface version if implemented in TF-A.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``VERSION``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == SMC_UNK if interface is not implemented
+
+uint32_t        w1: On success, debugfs interface version, 32 bits
+                value with major version number in upper 16 bits and
+                minor version in lower 16 bits.
+=============== ======================================================
+
+* CREATE(1) and WRITE (5) command identifiers are unimplemented and
+  return `SMC_UNK`.
+
+--------------
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ven-el3-service.rst b/docs/components/ven-el3-service.rst
new file mode 100644
index 0000000..13449ba
--- /dev/null
+++ b/docs/components/ven-el3-service.rst
@@ -0,0 +1,78 @@
+Vendor Specific EL3 Monitor Service Calls
+=========================================
+
+This document enumerates and describes the Vendor Specific EL3 Monitor Service
+Calls.
+
+These are Service Calls defined by the vendor of the EL3 Monitor.
+They are accessed via ``SMC`` ("SMC calls") instruction executed from Exception
+Levels below EL3. SMC calls for Vendor Specific EL3 Monitor Services:
+
+-  Follow `SMC Calling Convention`_;
+-  Use SMC function IDs that fall in the vendor-specific EL3 range, which are
+
++---------------------------+--------------------------------------------------+
+| SMC Function Identifier   | Service Type                                     |
++===========================+==================================================+
+| 0x87000000 - 0x8700FFFF   | SMC32: Vendor Specific EL3 Monitor Service Calls |
++---------------------------+--------------------------------------------------+
+| 0xC7000000 - 0xC700FFFF   | SMC64: Vendor Specific EL3 Monitor Service Calls |
++---------------------------+--------------------------------------------------+
+
+Vendor-specific EL3 monitor services are as follows:
+
++-----------------------------------+-----------------------+---------------------------------------------+
+| SMC Function Identifier           | Service Type          | FID's Usage                                 |
++===================================+=======================+=============================================+
+| 0x87000010 - 0x8700001F (SMC32)   | DebugFS Interface     | | 0 - 11 are in use.                        |
++-----------------------------------+                       | | 12 - 15 are reserved for future expansion.|
+| 0xC7000010 - 0xC700001F (SMC64)   |                       |                                             |
++-----------------------------------+-----------------------+---------------------------------------------+
+| 0x87000020 - 0x8700002F (SMC32)   | Performance           | | 0,1 is in use.                            |
++-----------------------------------+ Measurement Framework | | 2 - 15 are reserved for future expansion. |
+| 0xC7000020 - 0xC700002F (SMC64)   | (PMF)                 |                                             |
++-----------------------------------+-----------------------+---------------------------------------------+
+| 0x87000030 - 0x8700FFFF (SMC32)   | Reserved              | | reserved for future expansion             |
++-----------------------------------+                       |                                             |
+| 0xC7000030 - 0xC700FFFF (SMC64)   |                       |                                             |
++-----------------------------------+-----------------------+---------------------------------------------+
+
+Source definitions for vendor-specific EL3 Monitor Service Calls used by TF-A are located in
+the ``ven_el3_svc.h`` header file.
+
++----------------------------+----------------------------+--------------------------------+
+| VEN_EL3_SVC_VERSION_MAJOR  | VEN_EL3_SVC_VERSION_MINOR  | Changes                        |
++============================+============================+================================+
+|                          1 |                          0 | Added Debugfs and PMF services.|
++----------------------------+----------------------------+--------------------------------+
+
+*Table 1: Showing different versions of Vendor-specific service and changes done with each version*
+
+Each sub service will have its own version, one FID allocated for sub service version.
+
+Some ground rules when one should update top level version.
+ - VEN_EL3_SVC_VERSION_MAJOR is incremented when any of the sub service version discovery
+   FID changes or the FID that was allocated for discovery changes. So any breaking subfeature
+   discovery changes will lead to major version update.
+ - VEN_EL3_SVC_VERSION_MINOR is incremented when we add a new FID or a new sub service.
+   For example adding an new monitor service at 0x30, Debugfs starts at 0x10 and PMF
+   starts at 0x20 next one will start at 0x30, this will need a update to minor version.
+
+Performance Measurement Framework (PMF)
+---------------------------------------
+
+The :ref:`Performance Measurement Framework <firmware_design_pmf>`
+allows callers to retrieve timestamps captured at various paths in TF-A
+execution.
+
+DebugFS interface
+-----------------
+
+The optional DebugFS interface is accessed through Vendor specific EL3 service. Refer
+to :ref:`DebugFS interface` documentation for further details and usage.
+
+--------------
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+
+.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/conf.py b/docs/conf.py
index d4e5423..3f9655b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -14,8 +14,8 @@
 
 project = "Trusted Firmware-A"
 author = "Trusted Firmware-A contributors"
-version = "2.10.0"
-release = "2.10.0"
+version = "2.11.0"
+release = "2.11.0"
 
 # -- General configuration ---------------------------------------------------
 
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index abd9f87..6147c1f 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -787,14 +787,23 @@
   Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
   of the CPU, it is fixed in r1p1.
 
+- ``ERRATA_X3_2372204``: This applies errata 2372204 workaround to
+  Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
+  of the CPU, it is fixed in r1p1.
+
 - ``ERRATA_X3_2615812``: This applies errata 2615812 workaround to Cortex-X3
   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
-  CPU, it is still open.
+  CPU, it is fixed in r1p2.
 
 - ``ERRATA_X3_2641945``: This applies errata 2641945 workaround to Cortex-X3
   CPU. This needs to be enabled only for revisions r0p0 and r1p0 of the CPU.
   It is fixed in r1p1.
 
+- ``ERRATA_X3_2701951``: This applies erratum 2701951 workaround to Cortex-X3
+  CPU and affects system configurations that do not use an ARM interconnect
+  IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
+  in r1p2.
+
 - ``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.
@@ -807,6 +816,23 @@
   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
   CPU. It is fixed in r1p2.
 
+For Cortex-X4, the following errata build flags are defined :
+
+- ``ERRATA_X4_2701112``: This applies erratum 2701112 workaround to Cortex-X4
+  CPU and affects system configurations that do not use an Arm interconnect IP.
+  This needs to be enabled for revisions r0p0 and is fixed in r0p1.
+  The workaround for this erratum is not implemented in EL3, but the flag can
+  be enabled/disabled at the platform level. The flag is used when the errata ABI
+  feature is enabled and can assist the Kernel in the process of
+  mitigation of the erratum.
+
+-  ``ERRATA_X4_2740089``: This applies errata 2740089 workaround to Cortex-X4
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed
+   in r0p2.
+
+- ``ERRATA_X4_2763018``: This applies errata 2763018 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -872,14 +898,44 @@
 
 For Cortex-A715, the following errata build flags are defined :
 
+-  ``ERRATA_A715_2331818``: This applies errata 2331818 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0 and r1p0.
+   It is fixed in r1p1.
+
+- ``ERRATA_A715_2344187``: This applies errata 2344187 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0 and r1p0. It is
+   fixed in r1p1.
+
+-  ``ERRATA_A715_2413290``: This applies errata 2413290 workaround to
+   Cortex-A715 CPU. This needs to be enabled only for revision r1p0 and
+   when SPE(Statistical profiling extension)=True. The errata is fixed
+   in r1p1.
+
+-  ``ERRATA_A715_2420947``: This applies errata 2420947 workaround to
+   Cortex-A715 CPU. This needs to be enabled only for revision r1p0.
+   It is fixed in r1p1.
+
+-  ``ERRATA_A715_2429384``: This applies errata 2429384 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revision r1p0. There is no
+   workaround for revision r0p0. It is fixed in r1p1.
+
 -  ``ERRATA_A715_2561034``: This applies errata 2561034 workaround to
    Cortex-A715 CPU. This needs to be enabled only for revision r1p0.
    It is fixed in r1p1.
 
+-  ``ERRATA_A715_2728106``: This applies errata 2728106 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0
+   and r1p1. It is fixed in r1p2.
+
+For Cortex-A720, the following errata build flags are defined :
+
+-  ``ERRATA_A720_2926083``: This applies errata 2926083 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
--  ``ERRATA_A715_2701951``: This applies erratum 2701951 workaround to Cortex-A715
-   CPU and affects system configurations that do not use an ARM interconnect
-   IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
-   in r1p2.
+-  ``ERRATA_A720_2940794``: This applies errata 2940794 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
 
 DSU Errata Workarounds
 ----------------------
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index ba97264..2ba54ea 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -645,6 +645,35 @@
 Data structures used in the BL31 cold boot interface
 ''''''''''''''''''''''''''''''''''''''''''''''''''''
 
+In the cold boot flow, ``entry_point_info`` is used to represent the execution
+state of an image; that is, the state of general purpose registers, PC, and
+SPSR.
+
+There are two variants of this structure, for AArch64:
+
+.. code:: c
+
+   typedef struct entry_point_info {
+        param_header_t h;
+        uintptr_t pc;
+        uint32_t spsr;
+
+        aapcs64_params_t args;
+   }
+
+and, AArch32:
+
+.. code:: c
+
+   typedef struct entry_point_info {
+      param_header_t h;
+      uintptr_t pc;
+      uint32_t spsr;
+
+      uintptr_t lr_svc;
+      aapcs32_params_t args;
+   } entry_point_info_t;
+
 These structures are designed to support compatibility and independent
 evolution of the structures and the firmware images. For example, a version of
 BL31 that can interpret the BL3x image information from different versions of
@@ -662,13 +691,17 @@
         uint8_t type;       /* type of the structure */
         uint8_t version;    /* version of this structure */
         uint16_t size;      /* size of this structure in bytes */
-        uint32_t attr;      /* attributes: unused bits SBZ */
+        uint32_t attr;      /* attributes */
     } param_header_t;
 
-The structures using this format are ``entry_point_info``, ``image_info`` and
-``bl31_params``. The code that allocates and populates these structures must set
-the header fields appropriately, and the ``SET_PARAM_HEAD()`` a macro is defined
-to simplify this action.
+In `entry_point_info`, Bits 0 and 5 of ``attr`` field are used to encode the
+security state; in other words, whether the image is to be executed in Secure,
+Non-Secure, or Realm mode.
+
+Other structures using this format are ``image_info`` and ``bl31_params``. The
+code that allocates and populates these structures must set the header fields
+appropriately, the ``SET_PARAM_HEAD()`` macro is defined to simplify this
+action.
 
 Required CPU state for BL31 Warm boot initialization
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2767,9 +2800,11 @@
 -  Branch Target Identification feature is selected by ``BRANCH_PROTECTION``
    option set to 1. This option defaults to 0.
 
--  Memory Tagging Extension feature is unconditionally enabled for both worlds.
-   To enable MTE at EL0 use ``ENABLE_FEAT_MTE`` is required and to enable MTE at
-   ELX ``ENABLE_FEAT_MTE2`` is required.
+-  Memory Tagging Extension feature has few variants but not all of them require
+   enablement from EL3 to be used at lower EL. e.g. Memory tagging only at
+   EL0(MTE) does not require EL3 configuration however memory tagging at
+   EL2/EL1 (MTE2) does require EL3 enablement and we need to set this option
+   ``ENABLE_FEAT_MTE2`` to 1. This option defaults to 0.
 
 Armv7-A
 ~~~~~~~
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index 10fb7fb..f10d2e7 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -84,20 +84,20 @@
 
 -  **Root of trust key**
 
-   The private part of this key is used to sign the BL2 content certificate and
-   the trusted key certificate. The public part is the ROTPK.
+   The private part of this key is used to sign the trusted boot firmware
+   certificate and the trusted key certificate. The public part is the ROTPK.
 
 -  **Trusted world key**
 
    The private part is used to sign the key certificates corresponding to the
    secure world images (SCP_BL2, BL31 and BL32). The public part is stored in
-   one of the extension fields in the trusted world certificate.
+   one of the extension fields in the trusted key certificate.
 
 -  **Non-trusted world key**
 
    The private part is used to sign the key certificate corresponding to the
-   non secure world image (BL33). The public part is stored in one of the
-   extension fields in the trusted world certificate.
+   non-secure world image (BL33). The public part is stored in one of the
+   extension fields in the trusted key certificate.
 
 -  **BL3X keys**
 
@@ -116,10 +116,11 @@
 
 The following certificates are used to authenticate the images.
 
--  **BL2 content certificate**
+-  **Trusted boot firmware certificate**
 
-   It is self-signed with the private part of the ROT key. It contains a hash
-   of the BL2 image.
+   It is self-signed with the private part of the ROT key. It contains a hash of
+   the BL2 image and hashes of various firmware configuration files
+   (TB_FW_CONFIG, HW_CONFIG, FW_CONFIG).
 
 -  **Trusted key certificate**
 
@@ -127,45 +128,48 @@
    public part of the trusted world key and the public part of the non-trusted
    world key.
 
--  **SCP_BL2 key certificate**
+-  **SCP firmware key certificate**
 
    It is self-signed with the trusted world key. It contains the public part of
    the SCP_BL2 key.
 
--  **SCP_BL2 content certificate**
+-  **SCP firmware content certificate**
 
    It is self-signed with the SCP_BL2 key. It contains a hash of the SCP_BL2
    image.
 
--  **BL31 key certificate**
+-  **SoC firmware key certificate**
 
    It is self-signed with the trusted world key. It contains the public part of
    the BL31 key.
 
--  **BL31 content certificate**
+-  **SoC firmware content certificate**
 
-   It is self-signed with the BL31 key. It contains a hash of the BL31 image.
+   It is self-signed with the BL31 key. It contains hashes of the BL31 image and
+   its configuration file (SOC_FW_CONFIG).
 
--  **BL32 key certificate**
+-  **Trusted OS key certificate**
 
    It is self-signed with the trusted world key. It contains the public part of
    the BL32 key.
 
--  **BL32 content certificate**
+-  **Trusted OS content certificate**
 
-   It is self-signed with the BL32 key. It contains a hash of the BL32 image.
+   It is self-signed with the BL32 key. It contains hashes of the BL32 image(s)
+   and its configuration file(s) (TOS_FW_CONFIG).
 
--  **BL33 key certificate**
+-  **Non-trusted firmware key certificate**
 
    It is self-signed with the non-trusted world key. It contains the public
    part of the BL33 key.
 
--  **BL33 content certificate**
+-  **Non-trusted firmware content certificate**
 
-   It is self-signed with the BL33 key. It contains a hash of the BL33 image.
+   It is self-signed with the BL33 key. It contains hashes of the BL33 image and
+   its configuration file (NT_FW_CONFIG).
 
-The SCP_BL2 and BL32 certificates are optional, but they must be present if the
-corresponding SCP_BL2 or BL32 images are present.
+The SCP firmware and Trusted OS certificates are optional, but they must be
+present if the corresponding SCP_BL2 or BL32 images are present.
 
 The following diagram summarizes the part of the TBBR CoT enforced by BL2. Some
 images (SCP, debug certificates, secure partitions, configuration files) are not
diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst
index d88942e..f946b2e 100644
--- a/docs/design_documents/cmake_framework.rst
+++ b/docs/design_documents/cmake_framework.rst
@@ -11,11 +11,7 @@
 Abstract
 --------
 This document presents a proposal for a new buildsystem for TF-A using CMake,
-and as part of this a reusable CMake framework for embedded projects. For a
-summary about the proposal, please see the `Phabricator wiki page
-<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As
-mentioned there, the proposal consists of two phases. The subject of this
-document is the first phase only.
+and as part of this a reusable CMake framework for embedded projects.
 
 Introduction
 ------------
@@ -162,4 +158,4 @@
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/context_mgmt_rework.rst b/docs/design_documents/context_mgmt_rework.rst
index 59f9d4e..b086e3c 100644
--- a/docs/design_documents/context_mgmt_rework.rst
+++ b/docs/design_documents/context_mgmt_rework.rst
@@ -4,7 +4,7 @@
 :Authors: Soby Mathew & Zelalem Aweke
 :Organization: Arm Limited
 :Contact: Soby Mathew <soby.mathew@arm.com> & Zelalem Aweke <zelalem.aweke@arm.com>
-:Status: RFC
+:Status: Implementation is ongoing. Refer to :ref:`Context Management Library` for more details.
 
 .. contents:: Table of Contents
 
@@ -194,4 +194,4 @@
 
 --------------
 
-*Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index ecc68b2..ac982e0 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -9,7 +9,7 @@
    context_mgmt_rework
    measured_boot_poc
    drtm_poc
-   rss
+   rse
    psci_osi_mode
    measured_boot
 
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
index 8a2ab2d..9dfe494 100644
--- a/docs/design_documents/measured_boot.rst
+++ b/docs/design_documents/measured_boot.rst
@@ -91,10 +91,10 @@
    and the variable length crypto agile structure called TCG_PCR_EVENT2. Event
    Log driver implemented in TF-A covers later part.
 
-#. RSS
+#. RSE
 
    It is one of physical backend to extend the measurements. Please refer this
-   document :ref:`Runtime Security Subsystem (RSS)` for more details.
+   document :ref:`Runtime Security Engine (RSE)` for more details.
 
 Platform Interface
 ------------------
@@ -121,7 +121,7 @@
       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,
+   (e.g. Event Log buffer, RSE). 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.
 
@@ -147,7 +147,7 @@
 
      - 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
+     - If it is a secure crypto-processor (like RSE), then extend the designated
        PCR (or slot) with the given measurement.
    - This function must return 0 on success, a signed integer error code
      otherwise.
@@ -223,7 +223,7 @@
    - This function must return 0 on success, a signed integer error code
      otherwise.
    - In TC2 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
+     key and forward this hash to RSE alongside the measurement of the image
      which the key signs.
 
 --------------
diff --git a/docs/design_documents/rse.rst b/docs/design_documents/rse.rst
new file mode 100644
index 0000000..e0e0fb3
--- /dev/null
+++ b/docs/design_documents/rse.rst
@@ -0,0 +1,742 @@
+Runtime Security Engine (RSE)
+=============================
+
+This document focuses on the relationship between the Runtime Security Engine
+(RSE) and the application processor (AP). According to the ARM reference design
+the RSE is an independent core next to the AP and the SCP on the same die. It
+provides fundamental security guarantees and runtime services for the rest of
+the system (e.g.: trusted boot, measured boot, platform attestation,
+key management, and key derivation).
+
+At power up RSE boots first from its private ROM code. It validates and loads
+its own images and the initial images of SCP and AP. When AP and SCP are
+released from reset and their initial code is loaded then they continue their
+own boot process, which is the same as on non-RSE systems. Please refer to the
+``RSE documentation`` [1]_ for more details about the RSE boot flow.
+
+The last stage of the RSE firmware is a persistent, runtime component. Much
+like AP_BL31, this is a passive entity which has no periodical task to do and
+just waits for external requests from other subsystems. RSE and other
+subsystems can communicate with each other over message exchange. RSE waits
+in idle for the incoming request, handles them, and sends a response then goes
+back to idle.
+
+RSE communication layer
+-----------------------
+
+The communication between RSE and other subsystems are primarily relying on the
+Message Handling Unit (MHU) module. The number of MHU interfaces between RSE
+and other cores is IMPDEF. Besides MHU other modules also could take part in
+the communication. RSE is capable of mapping the AP memory to its address space.
+Thereby either RSE core itself or a DMA engine if it is present, can move the
+data between memory belonging to RSE or AP. In this way, a bigger amount of data
+can be transferred in a short time.
+
+The MHU comes in pairs. There is a sender and receiver side. They are connected
+to each other. An MHU interface consists of two pairs of MHUs, one sender and
+one receiver on both sides. Bidirectional communication is possible over an
+interface. One pair provides message sending from AP to RSE and the other pair
+from RSE to AP. The sender and receiver are connected via channels. There is an
+IMPDEF number of channels (e.g: 4-16) between a sender and a receiver module.
+
+The RSE communication layer provides two ways for message exchange:
+
+- ``Embedded messaging``: The full message, including header and payload, are
+  exchanged over the MHU channels. A channel is capable of delivering a single
+  word. The sender writes the data to the channel register on its side and the
+  receiver can read the data from the channel on the other side. One dedicated
+  channel is used for signalling. It does not deliver any payload it is just
+  meant for signalling that the sender loaded the data to the channel registers
+  so the receiver can read them. The receiver uses the same channel to signal
+  that data was read. Signalling happens via IRQ. If the message is longer than
+  the data fit to the channel registers then the message is sent over in
+  multiple rounds. Both, sender and receiver allocate a local buffer for the
+  messages. Data is copied from/to these buffers to/from the channel registers.
+- ``Pointer-access messaging``: The message header and the payload are
+  separated and they are conveyed in different ways. The header is sent
+  over the channels, similar to the embedded messaging but the payload is
+  copied over by RSE core (or by DMA) between the sender and the receiver. This
+  could be useful in the case of long messages because transaction time is less
+  compared to the embedded messaging mode. Small payloads are copied by the RSE
+  core because setting up DMA would require more CPU cycles. The payload is
+  either copied into an internal buffer or directly read-written by RSE. Actual
+  behavior depends on RSE setup, whether the partition supports memory-mapped
+  ``iovec``. Therefore, the sender must handle both cases and prevent access to
+  the memory, where payload data lives, while the RSE handles the request.
+
+The RSE communication layer supports both ways of messaging in parallel. It is
+decided at runtime based on the message size which way to transfer the message.
+
+.. code-block:: bash
+
+    +----------------------------------------------+       +-------------------+
+    |                                              |       |                   |
+    |                      AP                      |       |                   |
+    |                                              |  +--->|       SRAM        |
+    +----------------------------------------------|  |    |                   |
+    |              BL1 / BL2 / BL31                |  |    |                   |
+    +----------------------------------------------+  |    +-------------------+
+             |                           ^            |        ^           ^
+             |  send                 IRQ | receive    |direct  |           |
+             V                           |            |access  |           |
+    +--------------------+    +--------------------+  |        |           |
+    |      MHU sender    |    |    MHU receiver    |  |        | Copy data |
+    +--------------------+    +--------------------+  |        |           |
+       | |           | |          | |           | |   |        |           |
+       | | channels  | |          | | channels  | |   |        |           |
+       | | e.g: 4-16 | |          | | e.g: 4-16 | |   |        V           |
+    +--------------------+    +--------------------+  |    +-------+       |
+    |     MHU receiver   |    |     MHU sender     |  | +->|  DMA  |       |
+    +--------------------+    +--------------------+  | |  +-------+       |
+             |                           ^            | |      ^           |
+        IRQ  |  receive                  | send       | |      | Copy data |
+             V                           |            | |      V           V
+    +----------------------------------------------+  | |  +-------------------+
+    |                                              |--+-+  |                   |
+    |                  RSE                         |       |      SRAM         |
+    |                                              |       |                   |
+    +----------------------------------------------+       +-------------------+
+
+.. Note::
+
+    The RSE communication layer is not prepared for concurrent execution. The
+    current use case only requires message exchange during the boot phase. In
+    the boot phase, only a single core is running and the rest of the cores are
+    in reset.
+
+Message structure
+^^^^^^^^^^^^^^^^^
+A description of the message format can be found in the ``RSE communication
+design`` [2]_ document.
+
+Source files
+^^^^^^^^^^^^
+- RSE comms:  ``drivers/arm/rse``
+- MHU driver: ``drivers/arm/mhu``
+
+
+API for communication over MHU
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The API is defined in these header files:
+
+- ``include/drivers/arm/rse_comms.h``
+- ``include/drivers/arm/mhu.h``
+
+RSE provided runtime services
+-----------------------------
+
+RSE provides the following runtime services:
+
+- ``Measured boot``: Securely store the firmware measurements which were
+  computed during the boot process and the associated metadata (image
+  description, measurement algorithm, etc.). More info on measured boot service
+  in RSE can be found in the ``measured_boot_integration_guide`` [3]_ .
+- ``Delegated attestation``: Query the platform attestation token and derive a
+  delegated attestation key. More info on the delegated attestation service
+  in RSE can be found in the ``delegated_attestation_integration_guide`` [4]_ .
+- ``OTP assets management``: Public keys used by AP during the trusted boot
+  process can be requested from RSE. Furthermore, AP can request RSE to
+  increase a non-volatile counter. Please refer to the
+  ``RSE key management`` [5]_ document for more details.
+
+Runtime service API
+^^^^^^^^^^^^^^^^^^^
+The RSE provided runtime services implement a PSA aligned API. The parameter
+encoding follows the PSA client protocol described in the
+``Firmware Framework for M`` [6]_ document in chapter 4.4. The implementation is
+restricted to the static handle use case therefore only the ``psa_call`` API is
+implemented.
+
+
+Software and API layers
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    +----------------+         +---------------------+
+    |   BL1 / BL2    |         |       BL31          |
+    +----------------+         +---------------------+
+      |                         |
+      | extend_measurement()    | get_delegated_key()
+      |                         | get_platform_token()
+      V                         V
+    +----------------+         +---------------------+
+    |  PSA protocol  |         |    PSA protocol     |
+    +----------------+         +---------------------+
+         |                               |
+         | psa_call()                    | psa_call()
+         |                               |
+         V                               V
+    +------------------------------------------------+
+    |         RSE communication protocol             |
+    +------------------------------------------------+
+         |                     ^
+         | mhu_send_data()     | mhu_receive_data()
+         |                     |
+         V                     |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+               |                      ^
+               | Register access      | IRQ
+               V                      |
+    +------------------------------------------------+
+    |             MHU HW on AP side                  |
+    +------------------------------------------------+
+                         ^
+                         | Physical wires
+                         |
+                         V
+    +------------------------------------------------+
+    |             MHU HW on RSE side                 |
+    +------------------------------------------------+
+             |                        ^
+             | IRQ                    | Register access
+             V                        |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+             |                        |
+             V                        V
+    +---------------+       +------------------------+
+    | Measured boot |       | Delegated attestation  |
+    | service       |       | service                |
+    +---------------+       +------------------------+
+
+
+RSE based Measured Boot
+-----------------------
+
+Measured Boot is the process of cryptographically measuring (computing the hash
+value of a binary) the code and critical data used at boot time. The
+measurement must be stored in a tamper-resistant way, so the security state
+of the device can be attested later to an external party. RSE provides a runtime
+service which is meant to store measurements and associated metadata alongside.
+
+Data is stored in internal SRAM which is only accessible by the secure runtime
+firmware of RSE. Data is stored in so-called measurement slots. A platform has
+IMPDEF number of measurement slots. The measurement storage follows extend
+semantics. This means that measurements are not stored directly (as it was
+taken) instead they contribute to the current value of the measurement slot.
+The extension implements this logic, where ``||`` stands for concatenation:
+
+.. code-block:: bash
+
+    new_value_of_measurement_slot = Hash(old_value_of_measurement_slot || measurement)
+
+Supported hash algorithms: sha-256, sha-512
+
+Measured Boot API
+^^^^^^^^^^^^^^^^^
+
+Defined here:
+
+- ``include/lib/psa/measured_boot.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rse_measured_boot_extend_measurement(uint8_t        index,
+                                         const uint8_t *signer_id,
+                                         size_t         signer_id_size,
+                                         const uint8_t *version,
+                                         size_t         version_size,
+                                         uint32_t       measurement_algo,
+                                         const uint8_t *sw_type,
+                                         size_t         sw_type_size,
+                                         const uint8_t *measurement_value,
+                                         size_t         measurement_value_size,
+                                         bool           lock_measurement);
+
+Measured Boot Metadata
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following metadata can be stored alongside the measurement:
+
+- ``Signer-id``: Mandatory. The hash of the firmware image signing public key.
+- ``Measurement algorithm``: Optional. The hash algorithm which was used to
+  compute the measurement (e.g.: sha-256, etc.).
+- ``Version info``: Optional. The firmware version info (e.g.: 2.7).
+- ``SW type``: Optional. Short text description (e.g.: BL1, BL2, BL31, etc.)
+
+.. Note::
+    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
+measurements. The default value is IMPDEF. All measurement slot is cleared at
+reset, there is no other way to clear them. In the reference implementation,
+the measurement slots are initialized to 0. At the first call to extend the
+measurement in a slot, the extend operation uses the default value of the
+measurement slot. All upcoming extend operation on the same slot contributes
+to the previous value of that measurement slot.
+
+The following rules are kept when a slot is extended multiple times:
+
+- ``Signer-id`` must be the same as the previous call(s), otherwise a
+  PSA_ERROR_NOT_PERMITTED error code is returned.
+
+- ``Measurement algorithm``: must be the same as the previous call(s),
+  otherwise, a PSA_ERROR_NOT_PERMITTED error code is returned.
+
+In case of error no further action is taken (slot is not locked). If there is
+a valid data in a sub-sequent call then measurement slot will be extended. The
+rest of the metadata is handled as follows when a measurement slot is extended
+multiple times:
+
+- ``SW type``: Cleared.
+- ``Version info``: Cleared.
+
+.. Note::
+
+    Extending multiple measurements in the same slot leads to some metadata
+    information loss. Since RSE is not constrained on special HW resources to
+    store the measurements and metadata, therefore it is worth considering to
+    store all of them one by one in distinct slots. However, they are one-by-one
+    included in the platform attestation token. So, the number of distinct
+    firmware image measurements has an impact on the size of the attestation
+    token.
+
+The allocation of the measurement slot among RSE, Root and Realm worlds is
+platform dependent. The platform must provide an allocation of the measurement
+slot at build time. An example can be found in
+``tf-a/plat/arm/board/tc/tc_bl1_measured_boot.c``
+Furthermore, the memory, which holds the metadata is also statically allocated
+in RSE memory. Some of the fields have a static value (measurement algorithm),
+and some of the values have a dynamic value (measurement value) which is updated
+by the bootloaders when the firmware image is loaded and measured. The metadata
+structure is defined in
+``include/drivers/measured_boot/rse/rse_measured_boot.h``.
+
+.. code-block:: c
+
+    struct rse_mboot_metadata {
+            unsigned int id;
+            uint8_t slot;
+            uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+            size_t  signer_id_size;
+            uint8_t version[VERSION_MAX_SIZE];
+            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 ``rse_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/rse/rse_measured_boot.h``
+
+.. code-block:: c
+
+   int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr,
+                               const void *pk_oid,
+                               const void *pk_ptr,
+                               size_t pk_len)
+
+
+- First parameter is the pointer to the ``rse_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
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
+  implementation whether RSE or TPM (or both) backend based measured boot is
+  enabled.
+- ``MBOOT_RSE_HASH_ALG``: Determine the hash algorithm to measure the images.
+  The default value is sha-256.
+
+Measured boot flow
+^^^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rse_measured_boot_flow.svg
+  :align: center
+
+Sample console log
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 6
+    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:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : FW_CONFIG
+    INFO:     - sw_type_size: 10
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : aa ea d3 a7 a8 e2 ab 7d 13 a6 cb 34 99 10 b9 a1
+    INFO:                   : 1b 9f a0 52 c5 a8 b1 d7 76 f2 c1 c1 ef ca 1a df
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:31 loaded at address = 0x4001010
+    INFO:    Loading image id=24 at address 0x4001300
+    INFO:    Image id=24 loaded: 0x4001300 - 0x400153a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 7
+    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
+    INFO:     - sw_type_size: 13
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 05 b9 dc 98 62 26 a7 1c 2d e5 bb af f0 90 52 28
+    INFO:                   : f2 24 15 8a 3a 56 60 95 d6 51 3a 7a 1a 50 9b b7
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:24 loaded at address = 0x4001300
+    INFO:    BL1: Loading BL2
+    INFO:    Loading image id=1 at address 0x404d000
+    INFO:    Image id=1 loaded: 0x404d000 - 0x406412a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 8
+    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
+    INFO:     - sw_type_size: 5
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 53 a1 51 75 25 90 fb a1 d9 b8 c8 34 32 3a 01 16
+    INFO:                   : c9 9e 74 91 7d 28 02 56 3f 5c 40 94 37 58 50 68
+    INFO:     - locking     : true
+
+Delegated Attestation
+---------------------
+
+Delegated Attestation Service was mainly developed to support the attestation
+flow on the ``ARM Confidential Compute Architecture`` (ARM CCA) [7]_.
+The detailed description of the delegated attestation service can be found in
+the ``Delegated Attestation Service Integration Guide`` [4]_ document.
+
+In the CCA use case, the Realm Management Monitor (RMM) relies on the delegated
+attestation service of the RSE to get a realm attestation key and the CCA
+platform token. BL31 does not use the service for its own purpose, only calls
+it on behalf of RMM. The access to MHU interface and thereby to RSE is
+restricted to BL31 only. Therefore, RMM does not have direct access, all calls
+need to go through BL31. The RMM dispatcher module of the BL31 is responsible
+for delivering the calls between the two parties.
+
+.. Note::
+     Currently the connection between the RMM dispatcher and the PSA/RSE layer
+     is not yet implemented. RMM dispatcher just returns hard coded data.
+
+Delegated Attestation API
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Defined here:
+
+- ``include/lib/psa/delegated_attestation.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rse_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+                                           uint32_t  key_bits,
+                                           uint8_t  *key_buf,
+                                           size_t    key_buf_size,
+                                           size_t   *key_size,
+                                           uint32_t  hash_algo);
+
+    psa_status_t
+    rse_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+                                   size_t         dak_pub_hash_size,
+                                   uint8_t       *token_buf,
+                                   size_t         token_buf_size,
+                                   size_t        *token_size);
+
+Attestation flow
+^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rse_attestation_flow.svg
+  :align: center
+
+Sample attestation token
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Binary format:
+
+.. code-block:: bash
+
+    INFO:    DELEGATED ATTEST TEST START
+    INFO:    Get delegated attestation key start
+    INFO:    Get delegated attest key succeeds, len: 48
+    INFO:    Delegated attest key:
+    INFO:            0d 2a 66 61 d4 89 17 e1 70 c6 73 56 df f4 11 fd
+    INFO:            7d 1f 3b 8a a3 30 3d 70 4c d9 06 c3 c7 ef 29 43
+    INFO:            0f ee b5 e7 56 e0 71 74 1b c4 39 39 fd 85 f6 7b
+    INFO:    Get platform token start
+    INFO:    Get platform token succeeds, len: 1086
+    INFO:    Platform attestation token:
+    INFO:            d2 84 44 a1 01 38 22 a0 59 05 7a a9 19 01 09 78
+    INFO:            1c 68 74 74 70 3a 2f 2f 61 72 6d 2e 63 6f 6d 2f
+    INFO:            43 43 41 2d 53 53 44 2f 31 2e 30 2e 30 0a 58 20
+    INFO:            b5 97 3c b6 8b aa 9f c5 55 58 78 6b 7e c6 7f 69
+    INFO:            e4 0d f5 ba 5a a9 21 cd 0c 27 f4 05 87 a0 11 ea
+    INFO:            19 09 5c 58 20 7f 45 4c 46 02 01 01 00 00 00 00
+    INFO:            00 00 00 00 00 03 00 3e 00 01 00 00 00 50 58 00
+    INFO:            00 00 00 00 00 19 01 00 58 21 01 07 06 05 04 03
+    INFO:            02 01 00 0f 0e 0d 0c 0b 0a 09 08 17 16 15 14 13
+    INFO:            12 11 10 1f 1e 1d 1c 1b 1a 19 18 19 09 61 44 cf
+    INFO:            cf cf cf 19 09 5b 19 30 03 19 09 62 67 73 68 61
+    INFO:            2d 32 35 36 19 09 60 78 3a 68 74 74 70 73 3a 2f
+    INFO:            2f 76 65 72 61 69 73 6f 6e 2e 65 78 61 6d 70 6c
+    INFO:            65 2f 2e 77 65 6c 6c 2d 6b 6e 6f 77 6e 2f 76 65
+    INFO:            72 61 69 73 6f 6e 2f 76 65 72 69 66 69 63 61 74
+    INFO:            69 6f 6e 19 09 5f 8d a4 01 69 52 53 45 5f 42 4c
+    INFO:            31 5f 32 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 9a 27 1f 2a 91 6b 0b
+    INFO:            6e e6 ce cb 24 26 f0 b3 20 6e f0 74 57 8b e5 5d
+    INFO:            9b c9 4f 6f 3f e3 ab 86 aa 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 67 52 53 45 5f 42 4c 32 05 58 20 53
+    INFO:            78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41
+    INFO:            41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02
+    INFO:            58 20 53 c2 34 e5 e8 47 2b 6a c5 1c 1a e1 ca b3
+    INFO:            fe 06 fa d0 53 be b8 eb fd 89 77 b0 10 65 5b fd
+    INFO:            d3 c3 06 67 73 68 61 2d 32 35 36 a4 01 65 52 53
+    INFO:            45 5f 53 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 11 21 cf cc d5 91 3f
+    INFO:            0a 63 fe c4 0a 6f fd 44 ea 64 f9 dc 13 5c 66 63
+    INFO:            4b a0 01 d1 0b cf 43 02 a2 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 66 41 50 5f 42 4c 31 05 58 20 53 78
+    INFO:            79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41
+    INFO:            9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58
+    INFO:            20 15 71 b5 ec 78 bd 68 51 2b f7 83 0b b6 a2 a4
+    INFO:            4b 20 47 c7 df 57 bc e7 9e b8 a1 c0 e5 be a0 a5
+    INFO:            01 06 67 73 68 61 2d 32 35 36 a4 01 66 41 50 5f
+    INFO:            42 4c 32 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 10 15 9b af 26 2b 43
+    INFO:            a9 2d 95 db 59 da e1 f7 2c 64 51 27 30 16 61 e0
+    INFO:            a3 ce 4e 38 b2 95 a9 7c 58 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 67 53 43 50 5f 42 4c 31 05 58 20 53
+    INFO:            78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41
+    INFO:            41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02
+    INFO:            58 20 10 12 2e 85 6b 3f cd 49 f0 63 63 63 17 47
+    INFO:            61 49 cb 73 0a 1a a1 cf aa d8 18 55 2b 72 f5 6d
+    INFO:            6f 68 06 67 73 68 61 2d 32 35 36 a4 01 67 53 43
+    INFO:            50 5f 42 4c 32 05 58 20 f1 4b 49 87 90 4b cb 58
+    INFO:            14 e4 45 9a 05 7e d4 d2 0f 58 a6 33 15 22 88 a7
+    INFO:            61 21 4d cd 28 78 0b 56 02 58 20 aa 67 a1 69 b0
+    INFO:            bb a2 17 aa 0a a8 8a 65 34 69 20 c8 4c 42 44 7c
+    INFO:            36 ba 5f 7e a6 5f 42 2c 1f e5 d8 06 67 73 68 61
+    INFO:            2d 32 35 36 a4 01 67 41 50 5f 42 4c 33 31 05 58
+    INFO:            20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc
+    INFO:            56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a
+    INFO:            a3 02 58 20 2e 6d 31 a5 98 3a 91 25 1b fa e5 ae
+    INFO:            fa 1c 0a 19 d8 ba 3c f6 01 d0 e8 a7 06 b4 cf a9
+    INFO:            66 1a 6b 8a 06 67 73 68 61 2d 32 35 36 a4 01 63
+    INFO:            52 4d 4d 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 a1 fb 50 e6 c8 6f ae
+    INFO:            16 79 ef 33 51 29 6f d6 71 34 11 a0 8c f8 dd 17
+    INFO:            90 a4 fd 05 fa e8 68 81 64 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 69 48 57 5f 43 4f 4e 46 49 47 05 58
+    INFO:            20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc
+    INFO:            56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a
+    INFO:            a3 02 58 20 1a 25 24 02 97 2f 60 57 fa 53 cc 17
+    INFO:            2b 52 b9 ff ca 69 8e 18 31 1f ac d0 f3 b0 6e ca
+    INFO:            ae f7 9e 17 06 67 73 68 61 2d 32 35 36 a4 01 69
+    INFO:            46 57 5f 43 4f 4e 46 49 47 05 58 20 53 78 79 63
+    INFO:            07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d
+    INFO:            30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20 9a
+    INFO:            92 ad bc 0c ee 38 ef 65 8c 71 ce 1b 1b f8 c6 56
+    INFO:            68 f1 66 bf b2 13 64 4c 89 5c cb 1a d0 7a 25 06
+    INFO:            67 73 68 61 2d 32 35 36 a4 01 6c 54 42 5f 46 57
+    INFO:            5f 43 4f 4e 46 49 47 05 58 20 53 78 79 63 07 53
+    INFO:            5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60
+    INFO:            cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20 23 89 03
+    INFO:            18 0c c1 04 ec 2c 5d 8b 3f 20 c5 bc 61 b3 89 ec
+    INFO:            0a 96 7d f8 cc 20 8c dc 7c d4 54 17 4f 06 67 73
+    INFO:            68 61 2d 32 35 36 a4 01 6d 53 4f 43 5f 46 57 5f
+    INFO:            43 4f 4e 46 49 47 05 58 20 53 78 79 63 07 53 5d
+    INFO:            f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf
+    INFO:            e3 22 38 c0 fa 97 3f 7a a3 02 58 20 e6 c2 1e 8d
+    INFO:            26 0f e7 18 82 de bd b3 39 d2 40 2a 2c a7 64 85
+    INFO:            29 bc 23 03 f4 86 49 bc e0 38 00 17 06 67 73 68
+    INFO:            61 2d 32 35 36 58 60 21 51 20 92 d6 d0 2a e6 be
+    INFO:            2f e3 93 0e a5 1f d6 98 96 32 24 56 e9 df c7 32
+    INFO:            5e 0b 78 68 b6 90 73 2a 0c 0f 07 77 c1 15 40 4b
+    INFO:            e1 fc 83 9b 7d 30 4f 4f e6 fa 46 ae 12 a3 08 3a
+    INFO:            cf 24 06 67 91 06 bf ae 50 31 79 dd 50 33 49 12
+    INFO:            bf c6 da 33 6d d6 18 25 43 54 4d b5 88 d6 ae 67
+    INFO:            35 7a fd b0 5f 95 b7
+    INFO:    DELEGATED ATTEST TEST END
+
+JSON format:
+
+.. code-block:: JSON
+
+    {
+        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
+        "CCA_PLATFORM_CHALLENGE": "b'B5973CB68BAA9FC55558786B7EC67F69E40DF5BA5AA921CD0C27F40587A011EA'",
+        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'7F454C4602010100000000000000000003003E00010000005058000000000000'",
+        "CCA_PLATFORM_INSTANCE_ID": "b'0107060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
+        "CCA_PLATFORM_CONFIG": "b'CFCFCFCF'",
+        "CCA_PLATFORM_LIFECYCLE": "secured_3003",
+        "CCA_PLATFORM_HASH_ALGO_ID": "sha-256",
+        "CCA_PLATFORM_VERIFICATION_SERVICE": "https://veraison.example/.well-known/veraison/verification",
+        "CCA_PLATFORM_SW_COMPONENTS": [
+            {
+                "SW_COMPONENT_TYPE": "RSE_BL1_2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'9A271F2A916B0B6EE6CECB2426F0B3206EF074578BE55D9BC94F6F3FE3AB86AA'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "RSE_BL2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'53C234E5E8472B6AC51C1AE1CAB3FE06FAD053BEB8EBFD8977B010655BFDD3C3'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "RSE_S",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1121CFCCD5913F0A63FEC40A6FFD44EA64F9DC135C66634BA001D10BCF4302A2'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "AP_BL1",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1571B5EC78BD68512BF7830BB6A2A44B2047C7DF57BCE79EB8A1C0E5BEA0A501'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "AP_BL2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'10159BAF262B43A92D95DB59DAE1F72C645127301661E0A3CE4E38B295A97C58'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "SCP_BL1",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'10122E856B3FCD49F063636317476149CB730A1AA1CFAAD818552B72F56D6F68'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "SCP_BL2",
+                "SIGNER_ID": "b'F14B4987904BCB5814E4459A057ED4D20F58A633152288A761214DCD28780B56'",
+                "MEASUREMENT_VALUE": "b'AA67A169B0BBA217AA0AA88A65346920C84C42447C36BA5F7EA65F422C1FE5D8'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "AP_BL31",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'2E6D31A5983A91251BFAE5AEFA1C0A19D8BA3CF601D0E8A706B4CFA9661A6B8A'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "RMM",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'A1FB50E6C86FAE1679EF3351296FD6713411A08CF8DD1790A4FD05FAE8688164'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "HW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1A252402972F6057FA53CC172B52B9FFCA698E18311FACD0F3B06ECAAEF79E17'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'9A92ADBC0CEE38EF658C71CE1B1BF8C65668F166BFB213644C895CCB1AD07A25'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "TB_FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'238903180CC104EC2C5D8B3F20C5BC61B389EC0A967DF8CC208CDC7CD454174F'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "SOC_FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'E6C21E8D260FE71882DEBDB339D2402A2CA7648529BC2303F48649BCE0380017'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            }
+        ]
+    }
+
+RSE OTP Assets Management
+-------------------------
+
+RSE 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/RSE interface for retrieving and incrementing non-volatile counters API is
+as follows.
+
+Defined here:
+
+- ``include/lib/psa/rse_platform_api.h``
+
+.. code-block:: c
+
+    psa_status_t rse_platform_nv_counter_increment(uint32_t counter_id)
+
+    psa_status_t rse_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/RSE interface for reading the ROTPK is as follows.
+
+Defined here:
+
+- ``include/lib/psa/rse_platform_api.h``
+
+.. code-block:: c
+
+    psa_status_t rse_platform_key_read(enum rse_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
+----------
+
+.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/readme.html
+.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/rse_comms.html
+.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
+.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
+.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/rse_key_management.html
+.. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
+.. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2024, Linaro Limited. All rights reserved.*
diff --git a/docs/design_documents/rss.rst b/docs/design_documents/rss.rst
deleted file mode 100644
index 18d5436..0000000
--- a/docs/design_documents/rss.rst
+++ /dev/null
@@ -1,690 +0,0 @@
-Runtime Security Subsystem (RSS)
-================================
-
-This document focuses on the relationship between the Runtime Security Subsystem
-(RSS) and the application processor (AP). According to the ARM reference design
-the RSS is an independent core next to the AP and the SCP on the same die. It
-provides fundamental security guarantees and runtime services for the rest of
-the system (e.g.: trusted boot, measured boot, platform attestation,
-key management, and key derivation).
-
-At power up RSS boots first from its private ROM code. It validates and loads
-its own images and the initial images of SCP and AP. When AP and SCP are
-released from reset and their initial code is loaded then they continue their
-own boot process, which is the same as on non-RSS systems. Please refer to the
-``RSS documentation`` [1]_ for more details about the RSS boot flow.
-
-The last stage of the RSS firmware is a persistent, runtime component. Much
-like AP_BL31, this is a passive entity which has no periodical task to do and
-just waits for external requests from other subsystems. RSS and other
-subsystems can communicate with each other over message exchange. RSS waits
-in idle for the incoming request, handles them, and sends a response then goes
-back to idle.
-
-RSS communication layer
------------------------
-
-The communication between RSS and other subsystems are primarily relying on the
-Message Handling Unit (MHU) module. The number of MHU interfaces between RSS
-and other cores is IMPDEF. Besides MHU other modules also could take part in
-the communication. RSS is capable of mapping the AP memory to its address space.
-Thereby either RSS core itself or a DMA engine if it is present, can move the
-data between memory belonging to RSS or AP. In this way, a bigger amount of data
-can be transferred in a short time.
-
-The MHU comes in pairs. There is a sender and receiver side. They are connected
-to each other. An MHU interface consists of two pairs of MHUs, one sender and
-one receiver on both sides. Bidirectional communication is possible over an
-interface. One pair provides message sending from AP to RSS and the other pair
-from RSS to AP. The sender and receiver are connected via channels. There is an
-IMPDEF number of channels (e.g: 4-16) between a sender and a receiver module.
-
-The RSS communication layer provides two ways for message exchange:
-
-- ``Embedded messaging``: The full message, including header and payload, are
-  exchanged over the MHU channels. A channel is capable of delivering a single
-  word. The sender writes the data to the channel register on its side and the
-  receiver can read the data from the channel on the other side. One dedicated
-  channel is used for signalling. It does not deliver any payload it is just
-  meant for signalling that the sender loaded the data to the channel registers
-  so the receiver can read them. The receiver uses the same channel to signal
-  that data was read. Signalling happens via IRQ. If the message is longer than
-  the data fit to the channel registers then the message is sent over in
-  multiple rounds. Both, sender and receiver allocate a local buffer for the
-  messages. Data is copied from/to these buffers to/from the channel registers.
-- ``Pointer-access messaging``: The message header and the payload are
-  separated and they are conveyed in different ways. The header is sent
-  over the channels, similar to the embedded messaging but the payload is
-  copied over by RSS core (or by DMA) between the sender and the receiver. This
-  could be useful in the case of long messages because transaction time is less
-  compared to the embedded messaging mode. Small payloads are copied by the RSS
-  core because setting up DMA would require more CPU cycles. The payload is
-  either copied into an internal buffer or directly read-written by RSS. Actual
-  behavior depends on RSS setup, whether the partition supports memory-mapped
-  ``iovec``. Therefore, the sender must handle both cases and prevent access to
-  the memory, where payload data lives, while the RSS handles the request.
-
-The RSS communication layer supports both ways of messaging in parallel. It is
-decided at runtime based on the message size which way to transfer the message.
-
-.. code-block:: bash
-
-    +----------------------------------------------+       +-------------------+
-    |                                              |       |                   |
-    |                      AP                      |       |                   |
-    |                                              |  +--->|       SRAM        |
-    +----------------------------------------------|  |    |                   |
-    |              BL1 / BL2 / BL31                |  |    |                   |
-    +----------------------------------------------+  |    +-------------------+
-             |                           ^            |        ^           ^
-             |  send                 IRQ | receive    |direct  |           |
-             V                           |            |access  |           |
-    +--------------------+    +--------------------+  |        |           |
-    |      MHU sender    |    |    MHU receiver    |  |        | Copy data |
-    +--------------------+    +--------------------+  |        |           |
-       | |           | |          | |           | |   |        |           |
-       | | channels  | |          | | channels  | |   |        |           |
-       | | e.g: 4-16 | |          | | e.g: 4-16 | |   |        V           |
-    +--------------------+    +--------------------+  |    +-------+       |
-    |     MHU receiver   |    |     MHU sender     |  | +->|  DMA  |       |
-    +--------------------+    +--------------------+  | |  +-------+       |
-             |                           ^            | |      ^           |
-        IRQ  |  receive                  | send       | |      | Copy data |
-             V                           |            | |      V           V
-    +----------------------------------------------+  | |  +-------------------+
-    |                                              |--+-+  |                   |
-    |                  RSS                         |       |      SRAM         |
-    |                                              |       |                   |
-    +----------------------------------------------+       +-------------------+
-
-.. Note::
-
-    The RSS communication layer is not prepared for concurrent execution. The
-    current use case only requires message exchange during the boot phase. In
-    the boot phase, only a single core is running and the rest of the cores are
-    in reset.
-
-Message structure
-^^^^^^^^^^^^^^^^^
-A description of the message format can be found in the ``RSS communication
-design`` [2]_ document.
-
-Source files
-^^^^^^^^^^^^
-- RSS comms:  ``drivers/arm/rss``
-- MHU driver: ``drivers/arm/mhu``
-
-
-API for communication over MHU
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The API is defined in these header files:
-
-- ``include/drivers/arm/rss_comms.h``
-- ``include/drivers/arm/mhu.h``
-
-RSS provided runtime services
------------------------------
-
-RSS provides the following runtime services:
-
-- ``Measured boot``: Securely store the firmware measurements which were
-  computed during the boot process and the associated metadata (image
-  description, measurement algorithm, etc.). More info on measured boot service
-  in RSS can be found in the ``measured_boot_integration_guide`` [3]_ .
-- ``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``: 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
-^^^^^^^^^^^^^^^^^^^
-The RSS provided runtime services implement a PSA aligned API. The parameter
-encoding follows the PSA client protocol described in the
-``Firmware Framework for M`` [6]_ document in chapter 4.4. The implementation is
-restricted to the static handle use case therefore only the ``psa_call`` API is
-implemented.
-
-
-Software and API layers
-^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: bash
-
-    +----------------+         +---------------------+
-    |   BL1 / BL2    |         |       BL31          |
-    +----------------+         +---------------------+
-      |                         |
-      | extend_measurement()    | get_delegated_key()
-      |                         | get_platform_token()
-      V                         V
-    +----------------+         +---------------------+
-    |  PSA protocol  |         |    PSA protocol     |
-    +----------------+         +---------------------+
-         |                               |
-         | psa_call()                    | psa_call()
-         |                               |
-         V                               V
-    +------------------------------------------------+
-    |         RSS communication protocol             |
-    +------------------------------------------------+
-         |                     ^
-         | mhu_send_data()     | mhu_receive_data()
-         |                     |
-         V                     |
-    +------------------------------------------------+
-    |                 MHU driver                     |
-    +------------------------------------------------+
-               |                      ^
-               | Register access      | IRQ
-               V                      |
-    +------------------------------------------------+
-    |             MHU HW on AP side                  |
-    +------------------------------------------------+
-                         ^
-                         | Physical wires
-                         |
-                         V
-    +------------------------------------------------+
-    |             MHU HW on RSS side                 |
-    +------------------------------------------------+
-             |                        ^
-             | IRQ                    | Register access
-             V                        |
-    +------------------------------------------------+
-    |                 MHU driver                     |
-    +------------------------------------------------+
-             |                        |
-             V                        V
-    +---------------+       +------------------------+
-    | Measured boot |       | Delegated attestation  |
-    | service       |       | service                |
-    +---------------+       +------------------------+
-
-
-RSS based Measured Boot
------------------------
-
-Measured Boot is the process of cryptographically measuring (computing the hash
-value of a binary) the code and critical data used at boot time. The
-measurement must be stored in a tamper-resistant way, so the security state
-of the device can be attested later to an external party. RSS provides a runtime
-service which is meant to store measurements and associated metadata alongside.
-
-Data is stored in internal SRAM which is only accessible by the secure runtime
-firmware of RSS. Data is stored in so-called measurement slots. A platform has
-IMPDEF number of measurement slots. The measurement storage follows extend
-semantics. This means that measurements are not stored directly (as it was
-taken) instead they contribute to the current value of the measurement slot.
-The extension implements this logic, where ``||`` stands for concatenation:
-
-.. code-block:: bash
-
-    new_value_of_measurement_slot = Hash(old_value_of_measurement_slot || measurement)
-
-Supported hash algorithms: sha-256, sha-512
-
-Measured Boot API
-^^^^^^^^^^^^^^^^^
-
-Defined here:
-
-- ``include/lib/psa/measured_boot.h``
-
-.. code-block:: c
-
-    psa_status_t
-    rss_measured_boot_extend_measurement(uint8_t        index,
-                                         const uint8_t *signer_id,
-                                         size_t         signer_id_size,
-                                         const uint8_t *version,
-                                         size_t         version_size,
-                                         uint32_t       measurement_algo,
-                                         const uint8_t *sw_type,
-                                         size_t         sw_type_size,
-                                         const uint8_t *measurement_value,
-                                         size_t         measurement_value_size,
-                                         bool           lock_measurement);
-
-Measured Boot Metadata
-^^^^^^^^^^^^^^^^^^^^^^
-
-The following metadata can be stored alongside the measurement:
-
-- ``Signer-id``: Mandatory. The hash of the firmware image signing public key.
-- ``Measurement algorithm``: Optional. The hash algorithm which was used to
-  compute the measurement (e.g.: sha-256, etc.).
-- ``Version info``: Optional. The firmware version info (e.g.: 2.7).
-- ``SW type``: Optional. Short text description (e.g.: BL1, BL2, BL31, etc.)
-
-.. Note::
-    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
-measurements. The default value is IMPDEF. All measurement slot is cleared at
-reset, there is no other way to clear them. In the reference implementation,
-the measurement slots are initialized to 0. At the first call to extend the
-measurement in a slot, the extend operation uses the default value of the
-measurement slot. All upcoming extend operation on the same slot contributes
-to the previous value of that measurement slot.
-
-The following rules are kept when a slot is extended multiple times:
-
-- ``Signer-id`` must be the same as the previous call(s), otherwise a
-  PSA_ERROR_NOT_PERMITTED error code is returned.
-
-- ``Measurement algorithm``: must be the same as the previous call(s),
-  otherwise, a PSA_ERROR_NOT_PERMITTED error code is returned.
-
-In case of error no further action is taken (slot is not locked). If there is
-a valid data in a sub-sequent call then measurement slot will be extended. The
-rest of the metadata is handled as follows when a measurement slot is extended
-multiple times:
-
-- ``SW type``: Cleared.
-- ``Version info``: Cleared.
-
-.. Note::
-
-    Extending multiple measurements in the same slot leads to some metadata
-    information loss. Since RSS is not constrained on special HW resources to
-    store the measurements and metadata, therefore it is worth considering to
-    store all of them one by one in distinct slots. However, they are one-by-one
-    included in the platform attestation token. So, the number of distinct
-    firmware image measurements has an impact on the size of the attestation
-    token.
-
-The allocation of the measurement slot among RSS, Root and Realm worlds is
-platform dependent. The platform must provide an allocation of the measurement
-slot at build time. An example can be found in
-``tf-a/plat/arm/board/tc/tc_bl1_measured_boot.c``
-Furthermore, the memory, which holds the metadata is also statically allocated
-in RSS memory. Some of the fields have a static value (measurement algorithm),
-and some of the values have a dynamic value (measurement value) which is updated
-by the bootloaders when the firmware image is loaded and measured. The metadata
-structure is defined in
-``include/drivers/measured_boot/rss/rss_measured_boot.h``.
-
-.. code-block:: c
-
-    struct rss_mboot_metadata {
-            unsigned int id;
-            uint8_t slot;
-            uint8_t signer_id[SIGNER_ID_MAX_SIZE];
-            size_t  signer_id_size;
-            uint8_t version[VERSION_MAX_SIZE];
-            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
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
-  implementation whether RSS or TPM (or both) backend based measured boot is
-  enabled.
-- ``MBOOT_RSS_HASH_ALG``: Determine the hash algorithm to measure the images.
-  The default value is sha-256.
-
-Measured boot flow
-^^^^^^^^^^^^^^^^^^
-
-.. figure:: ../resources/diagrams/rss_measured_boot_flow.svg
-  :align: center
-
-Sample console log
-^^^^^^^^^^^^^^^^^^
-
-.. code-block:: bash
-
-    INFO:    Measured boot extend measurement:
-    INFO:     - slot        : 6
-    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:     - version     :
-    INFO:     - version_size: 0
-    INFO:     - sw_type     : FW_CONFIG
-    INFO:     - sw_type_size: 10
-    INFO:     - algorithm   : 2000009
-    INFO:     - measurement : aa ea d3 a7 a8 e2 ab 7d 13 a6 cb 34 99 10 b9 a1
-    INFO:                   : 1b 9f a0 52 c5 a8 b1 d7 76 f2 c1 c1 ef ca 1a df
-    INFO:     - locking     : true
-    INFO:    FCONF: Config file with image ID:31 loaded at address = 0x4001010
-    INFO:    Loading image id=24 at address 0x4001300
-    INFO:    Image id=24 loaded: 0x4001300 - 0x400153a
-    INFO:    Measured boot extend measurement:
-    INFO:     - slot        : 7
-    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
-    INFO:     - sw_type_size: 13
-    INFO:     - algorithm   : 2000009
-    INFO:     - measurement : 05 b9 dc 98 62 26 a7 1c 2d e5 bb af f0 90 52 28
-    INFO:                   : f2 24 15 8a 3a 56 60 95 d6 51 3a 7a 1a 50 9b b7
-    INFO:     - locking     : true
-    INFO:    FCONF: Config file with image ID:24 loaded at address = 0x4001300
-    INFO:    BL1: Loading BL2
-    INFO:    Loading image id=1 at address 0x404d000
-    INFO:    Image id=1 loaded: 0x404d000 - 0x406412a
-    INFO:    Measured boot extend measurement:
-    INFO:     - slot        : 8
-    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
-    INFO:     - sw_type_size: 5
-    INFO:     - algorithm   : 2000009
-    INFO:     - measurement : 53 a1 51 75 25 90 fb a1 d9 b8 c8 34 32 3a 01 16
-    INFO:                   : c9 9e 74 91 7d 28 02 56 3f 5c 40 94 37 58 50 68
-    INFO:     - locking     : true
-
-Delegated Attestation
----------------------
-
-Delegated Attestation Service was mainly developed to support the attestation
-flow on the ``ARM Confidential Compute Architecture`` (ARM CCA) [7]_.
-The detailed description of the delegated attestation service can be found in
-the ``Delegated Attestation Service Integration Guide`` [4]_ document.
-
-In the CCA use case, the Realm Management Monitor (RMM) relies on the delegated
-attestation service of the RSS to get a realm attestation key and the CCA
-platform token. BL31 does not use the service for its own purpose, only calls
-it on behalf of RMM. The access to MHU interface and thereby to RSS is
-restricted to BL31 only. Therefore, RMM does not have direct access, all calls
-need to go through BL31. The RMM dispatcher module of the BL31 is responsible
-for delivering the calls between the two parties.
-
-.. Note::
-     Currently the connection between the RMM dispatcher and the PSA/RSS layer
-     is not yet implemented. RMM dispatcher just returns hard coded data.
-
-Delegated Attestation API
-^^^^^^^^^^^^^^^^^^^^^^^^^
-Defined here:
-
-- ``include/lib/psa/delegated_attestation.h``
-
-.. code-block:: c
-
-    psa_status_t
-    rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
-                                           uint32_t  key_bits,
-                                           uint8_t  *key_buf,
-                                           size_t    key_buf_size,
-                                           size_t   *key_size,
-                                           uint32_t  hash_algo);
-
-    psa_status_t
-    rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
-                                   size_t         dak_pub_hash_size,
-                                   uint8_t       *token_buf,
-                                   size_t         token_buf_size,
-                                   size_t        *token_size);
-
-Attestation flow
-^^^^^^^^^^^^^^^^
-
-.. figure:: ../resources/diagrams/rss_attestation_flow.svg
-  :align: center
-
-Sample attestation token
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Binary format:
-
-.. code-block:: bash
-
-    INFO:    DELEGATED ATTEST TEST START
-    INFO:    Get delegated attestation key start
-    INFO:    Get delegated attest key succeeds, len: 48
-    INFO:    Delegated attest key:
-    INFO:            0d 2a 66 61 d4 89 17 e1 70 c6 73 56 df f4 11 fd
-    INFO:            7d 1f 3b 8a a3 30 3d 70 4c d9 06 c3 c7 ef 29 43
-    INFO:            0f ee b5 e7 56 e0 71 74 1b c4 39 39 fd 85 f6 7b
-    INFO:    Get platform token start
-    INFO:    Get platform token succeeds, len: 1086
-    INFO:    Platform attestation token:
-    INFO:            d2 84 44 a1 01 38 22 a0 59 03 d1 a9 0a 58 20 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 00 00 00 19
-    INFO:            01 00 58 21 01 cb 8c 79 f7 a0 0a 6c ce 12 66 f8
-    INFO:            64 45 48 42 0e c5 10 bf 84 ee 22 18 b9 8f 11 04
-    INFO:            c7 22 31 9d fb 19 09 5c 58 20 aa aa aa aa aa aa
-    INFO:            aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc
-    INFO:            cc cc dd dd dd dd dd dd dd dd 19 09 5b 19 30 00
-    INFO:            19 09 5f 89 a4 05 58 20 bf e6 d8 6f 88 26 f4 ff
-    INFO:            97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d a2 6a
-    INFO:            df 34 c3 29 48 9a dc 38 04 67 31 2e 36 2e 30 2b
-    INFO:            30 01 64 52 54 5f 30 02 58 20 90 27 f2 46 ab 31
-    INFO:            85 36 46 c4 d7 c6 60 ed 31 0d 3c f0 14 de f0 6c
-    INFO:            24 0b de b6 7a 84 fc 3f 5b b7 a4 05 58 20 b3 60
-    INFO:            ca f5 c9 8c 6b 94 2a 48 82 fa 9d 48 23 ef b1 66
-    INFO:            a9 ef 6a 6e 4a a3 7c 19 19 ed 1f cc c0 49 04 67
-    INFO:            30 2e 30 2e 30 2b 30 01 64 52 54 5f 31 02 58 20
-    INFO:            52 13 15 d4 9d b2 cf 54 e4 99 37 44 40 68 f0 70
-    INFO:            7d 73 64 ae f7 08 14 b0 f7 82 ad c6 17 db a3 91
-    INFO:            a4 05 58 20 bf e6 d8 6f 88 26 f4 ff 97 fb 96 c4
-    INFO:            e6 fb c4 99 3e 46 19 fc 56 5d a2 6a df 34 c3 29
-    INFO:            48 9a dc 38 04 67 31 2e 35 2e 30 2b 30 01 64 52
-    INFO:            54 5f 32 02 58 20 8e 5d 64 7e 6f 6c c6 6f d4 4f
-    INFO:            54 b6 06 e5 47 9a cc 1b f3 7f ce 87 38 49 c5 92
-    INFO:            d8 2f 85 2e 85 42 a4 05 58 20 bf e6 d8 6f 88 26
-    INFO:            f4 ff 97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d
-    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 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 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 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 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 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
-    INFO:            72 6d 2e 63 6f 6d 2f 43 43 41 2d 53 53 44 2f 31
-    INFO:            2e 30 2e 30 19 09 62 71 6e 6f 74 2d 68 61 73 68
-    INFO:            2d 65 78 74 65 6e 64 65 64 19 09 61 44 ef be ad
-    INFO:            de 19 09 60 77 77 77 77 2e 74 72 75 73 74 65 64
-    INFO:            66 69 72 6d 77 61 72 65 2e 6f 72 67 58 60 29 4e
-    INFO:            4a d3 98 1e 3b 70 9f b6 66 ed 47 33 0e 99 f0 b1
-    INFO:            c3 f2 bc b2 1d b0 ae 90 0c c4 82 ff a2 6f ae 45
-    INFO:            f6 87 09 4a 09 21 77 ec 36 1c 53 b8 a7 9b 8e f7
-    INFO:            27 eb 7a 09 da 6f fb bf cb fd b3 e5 e9 36 91 b1
-    INFO:            92 13 c1 30 16 b4 5c 49 5e c0 c1 b9 01 5c 88 2c
-    INFO:            f8 2f 3e a4 a2 6d e4 9d 31 6a 06 f7 a7 73
-    INFO:    DELEGATED ATTEST TEST END
-
-JSON format:
-
-.. code-block:: JSON
-
-    {
-        "CCA_PLATFORM_CHALLENGE": "b'0000000000000000000000000000000000000000000000000000000000000000'",
-        "CCA_PLATFORM_INSTANCE_ID": "b'01CB8C79F7A00A6CCE1266F8644548420EC510BF84EE2218B98F1104C722319DFB'",
-        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD'",
-        "CCA_PLATFORM_LIFECYCLE": "secured_3000",
-        "CCA_PLATFORM_SW_COMPONENTS": [
-            {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.6.0+0",
-                "SW_COMPONENT_TYPE": "RT_0",
-                "MEASUREMENT_VALUE": "b'9027F246AB31853646C4D7C660ED310D3CF014DEF06C240BDEB67A84FC3F5BB7'"
-            },
-            {
-                "SIGNER_ID": "b'B360CAF5C98C6B942A4882FA9D4823EFB166A9EF6A6E4AA37C1919ED1FCCC049'",
-                "SW_COMPONENT_VERSION": "0.0.0+0",
-                "SW_COMPONENT_TYPE": "RT_1",
-                "MEASUREMENT_VALUE": "b'521315D49DB2CF54E49937444068F0707D7364AEF70814B0F782ADC617DBA391'"
-            },
-            {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.5.0+0",
-                "SW_COMPONENT_TYPE": "RT_2",
-                "MEASUREMENT_VALUE": "b'8E5D647E6F6CC66FD44F54B606E5479ACC1BF37FCE873849C592D82F852E8542'"
-            },
-            {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.5.0+0",
-                "SW_COMPONENT_TYPE": "",
-                "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
-            },
-            {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
-            },
-            {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
-            },
-            {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "BL_2\u0000",
-                "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
-            },
-            {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
-                "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
-            },
-            {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
-            }
-        ],
-        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
-        "CCA_PLATFORM_HASH_ALGO_ID": "not-hash-extended",
-        "CCA_PLATFORM_CONFIG": "b'EFBEADDE'",
-        "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
-----------
-
-.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/readme.html
-.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_comms.html
-.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
-.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
-.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_key_management.html
-.. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
-.. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
-
---------------
-
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 37545ce..52a9317 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -230,6 +230,13 @@
    contributions are still expected to build with ``W=0`` and ``E=1`` (the
    default).
 
+-  ``EARLY_CONSOLE``: This option is used to enable early traces before default
+   console is properly setup. It introduces EARLY_* traces macros, that will
+   use the non-EARLY traces macros if the flag is enabled, or do nothing
+   otherwise. To use this feature, platforms will have to create the function
+   plat_setup_early_console().
+   Default is 0 (disabled)
+
 -  ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
    the normal boot flow. It must specify the entry point address of the EL3
    payload. Please refer to the "Booting an EL3 payload" section for more
@@ -340,23 +347,11 @@
    flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
--  ``ENABLE_FEAT_MTE``: Numeric value to enable Memory Tagging Extension
-   if the platform wants to use this feature at EL0 ``ENABLE_FEAT_MTE`` is
-   required. This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
-   feature detection mechanism. Default value is ``0``.
-
 -  ``ENABLE_FEAT_MTE2``: Numeric value to enable Memory Tagging Extension2
    if the platform wants to use this feature and MTE2 is enabled at ELX.
    This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
    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 ``ENABLE_FEAT`` 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
@@ -766,6 +761,11 @@
    ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
    over ``PRELOADED_BL33_BASE``.
 
+-  ``PRESERVE_DSU_PMU_REGS``: This options when enabled allows the platform to
+   save/restore the DynamIQ Shared Unit's(DSU) Performance Monitoring Unit(PMU)
+   registers when the cluster goes through a power cycle. This is disabled by
+   default and platforms that require this feature have to enable them.
+
 -  ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
    vector address can be programmed or is fixed on the platform. It can take
    either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
@@ -805,6 +805,21 @@
    instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
    entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
 
+-  ``RME_GPT_BITLOCK_BLOCK``: This defines the block size (in number of 512MB
+-  blocks) covered by a single bit of the bitlock structure during RME GPT
+-  operations. The lower the block size, the better opportunity for
+-  parallelising GPT operations but at the cost of more bits being needed
+-  for the bitlock structure. This numeric parameter can take the values
+-  from 0 to 512 and must be a power of 2. The value of 0 is special and
+-  and it chooses a single spinlock for all GPT L1 table entries. Default
+-  value is 1 which corresponds to block size of 512MB per bit of bitlock
+-  structure.
+
+-  ``RME_GPT_MAX_BLOCK``: Numeric value in MB to define the maximum size of
+   supported contiguous blocks in GPT Library. This parameter can take the
+   values 0, 2, 32 and 512. Setting this value to 0 disables use of Contigious
+   descriptors. Default value is 2.
+
 -  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
    file that contains the ROT private key in PEM format or a PKCS11 URI and
    enforces public key hash generation. If ``SAVE_KEYS=1``, only a file is
@@ -1250,6 +1265,13 @@
 Common build options
 ~~~~~~~~~~~~~~~~~~~~
 
+-  ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
+   backend when ``MEASURED_BOOT`` is enabled. The default value is ``0``. When
+   set to ``1`` then measurements and additional metadata collected during the
+   measured boot process are sent to the DICE Protection Environment for storage
+   and processing. A certificate chain, which represents the boot state of the
+   device, can be queried from the DPE.
+
 -  ``DRTM_SUPPORT``: Boolean flag to enable support for Dynamic Root of Trust
    for Measurement (DRTM). This feature has trust dependency on BL31 for taking
    the measurements and recording them as per `PSA DRTM specification`_. For
@@ -1340,12 +1362,21 @@
    This flag is used in defining the firmware update metadata structure. This
    flag is by default set to '1'.
 
+- ``PSA_FWU_METADATA_FW_STORE_DESC``: To be enabled when the FWU
+   metadata contains image description. The default value is 1.
+
+   The version 2 of the FWU metadata allows for an opaque metadata
+   structure where a platform can choose to not include the firmware
+   store description in the metadata structure. This option indicates
+   if the firmware store description, which provides information on
+   the updatable images is part of the structure.
+
 --------------
 
 *Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
 .. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
 .. _GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
 .. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 573abdf..6a0241f 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -8,33 +8,53 @@
 different from those listed below, however only the software described in this
 document can be officially supported.
 
-Build Host
-----------
+Getting the TF-A Source
+-----------------------
+
+Source code for |TF-A| is maintained in a Git repository hosted on
+`TrustedFirmware.org`_. To clone this repository from the server, run the following
+in your shell:
 
-|TF-A| can be built using either a Linux or a Windows machine as the build host.
+.. code:: shell
 
-A relatively recent Linux distribution is recommended for building |TF-A|. We
-have performed tests using Ubuntu 22.04 LTS (64-bit) but other distributions
-should also work fine as a base, provided that the necessary tools and libraries
-can be installed.
+    git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a"
 
-.. _prerequisites_toolchain:
 
-Toolchain
----------
+Requirements
+------------
 
-|TF-A| can be built with any of the following *cross-compiler* toolchains that
-target the Armv7-A or Armv8-A architectures:
+======================== =====================
+        Program          Min supported version
+======================== =====================
+Arm Compiler             6.18
+Arm GNU Compiler         13.2
+Clang/LLVM               11.0.0
+Device Tree Compiler     1.4.7
+GNU make                 3.81
+mbed TLS\ [#f1]_         3.6.0
+Node.js [#f2]_           16
+OpenSSL                  1.0.0
+Poetry [#f2]_            1.3.2
+QCBOR\ [#f3]_            1.2
+Sphinx\ [#f2]_           2.4.4
+======================== =====================
 
-- TF-A has been tested with version 12.3.Rel1 (gcc 12.3) from the `Arm Developer website`_
+.. [#f1] Required for Trusted Board Boot and Measured Boot.
+.. [#f2] Required only for building TF-A documentation.
+.. [#f3] Required only when enabling DICE Protection Environment support.
 
-   You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
-   AArch32 and AArch64 builds respectively.
+Toolchain
+^^^^^^^^^
+
+|TF-A| can be compiled using any cross-compiler toolchain specified in the
+preceding table that target Armv7-A or Armv8-A. For AArch32 and
+AArch64 builds, the respective targets required are ``arm-none-eabi`` and
+``aarch64-none-elf``.
 
-- Clang == 14.0.0
-- Arm Compiler == 6.18
+Testing has been performed with version 13.2.Rel1 (gcc 13.2) of the Arm
+GNU compiler, which can be installed from the `Arm Developer website`_.
 
-In addition, a native compiler is required to build the supporting tools.
+In addition, a native compiler is required to build supporting tools.
 
 .. note::
    Versions greater than the ones specified are likely but not guaranteed to
@@ -43,77 +63,66 @@
    reports are always welcome.
 
 .. note::
-   The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
-   Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
-
-.. note::
    For instructions on how to select the cross compiler refer to
    :ref:`Performing an Initial Build`.
 
-.. _prerequisites_software_and_libraries:
-
-Software and Libraries
-----------------------
-
-The following tools are required to obtain and build |TF-A|:
-
-- An appropriate toolchain (see :ref:`prerequisites_toolchain`)
-- GNU Make
-- Git
+OpenSSL
+^^^^^^^
 
-The following libraries must be available to build one or more components or
-supporting tools:
+OpenSSL is required to build the cert_create, encrypt_fw, and fiptool tools.
 
-- OpenSSL >= 1.1.1 (v3.0.0 to v3.0.6 highly discouraged due to security issues)
+If using OpenSSL 3, older Linux versions may require it to be built from
+source code, as it may not be available in the default package repositories.
+Please refer to the OpenSSL project documentation for more information.
 
-   Required to build the cert_create, encrypt_fw, and fiptool tools.
+.. warning::
+    Versions 1.0.x and from v3.0.0 up to v3.0.6 are strongly advised against due
+    to concerns regarding security vulnerabilities!
 
-   .. note::
+Device Tree Compiler (DTC)
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-    If using OpenSSL 3, older Linux versions may require it to be built from
-    source code, as it may not be available in the default package repositories.
-    Please refer to the OpenSSL project documentation for more information.
+Needed if you want to rebuild the provided Flattened Device Tree (FDT)
+source files (``.dts`` files). DTC is available for Linux through the package
+repositories of most distributions.
 
-The following libraries are required for Trusted Board Boot and Measured Boot
-support:
+Arm Development Studio (`Arm-DS`_)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- mbed TLS == 3.4.1 (tag: ``mbedtls-3.4.1``)
+The standard software package used for debugging software on Arm development
+platforms and |FVP| models.
 
-These tools are optional:
+Node.js
+^^^^^^^
 
-- Device Tree Compiler (DTC) >= 1.4.7
+Highly recommended, and necessary in order to install and use the packaged
+Git hooks and helper tools. Without these tools you will need to rely on the
+CI for feedback on commit message conformance.
 
-   Needed if you want to rebuild the provided Flattened Device Tree (FDT)
-   source files (``.dts`` files). DTC is available for Linux through the package
-   repositories of most distributions.
+Poetry
+^^^^^^
 
-- Arm `Development Studio (Arm-DS)`_
+Required for managing Python dependencies, this will allow you to reliably
+reproduce a Python environment to build documentation and run analysis tools.
+Most importantly, it ensures your system environment will not be affected by
+dependencies in the Python scripts.
 
-   The standard software package used for debugging software on Arm development
-   platforms and |FVP| models.
-
-- Node.js >= 16
-
-   Highly recommended, and necessary in order to install and use the packaged
-   Git hooks and helper tools. Without these tools you will need to rely on the
-   CI for feedback on commit message conformance.
+.. _prerequisites_software_and_libraries:
 
-- Poetry >= 1.3.2
+Package Installation (Linux)
+----------------------------
 
-   Required for managing Python dependencies, this will allow you to reliably
-   reproduce a Python environment to build documentation and run analysis tools.
-   Most importantly, it ensures your system environment will not be affected by
-   dependencies in the Python scripts.
+|TF-A| can be compiled on both Linux and Windows-based machines.
+However, we strongly recommend using a UNIX-compatible build environment.
 
-Package Installation (Linux)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Testing is performed using Ubuntu 22.04 LTS (64-bit), but other distributions
+should also work, provided the necessary tools and libraries are installed.
 
-If you are using the recommended Ubuntu distribution then you can install the
-required packages with the following command:
+The following are steps to install the required packages:
 
 .. code:: shell
 
-    sudo apt install build-essential git
+    sudo apt install build-essential
 
 The optional packages can be installed using:
 
@@ -142,17 +151,6 @@
 
 .. _prerequisites_get_source:
 
-Getting the TF-A Source
------------------------
-
-Source code for |TF-A| is maintained in a Git repository hosted on
-TrustedFirmware.org. To clone this repository from the server, run the following
-in your shell:
-
-.. code:: shell
-
-    git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a"
-
 Additional Steps for Contributors
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -184,11 +182,12 @@
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
 
 .. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
 .. _Gerrit Code Review: https://www.gerritcodereview.com/
 .. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
 .. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
-.. _Development Studio (Arm-DS): https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio
+.. _Arm-DS: https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio
 .. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
+.. _TrustedFirmware.org: https://www.trustedfirmware.org/
diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst
index fe64558..4d4ec22 100644
--- a/docs/getting_started/rt-svc-writers-guide.rst
+++ b/docs/getting_started/rt-svc-writers-guide.rst
@@ -49,8 +49,11 @@
     Fast        1      CPU Service calls
     Fast        2      SiP Service calls
     Fast        3      OEM Service calls
-    Fast        4      Standard Service calls
-    Fast       5-47    Reserved for future use
+    Fast        4      Standard Secure Service calls
+    Fast        5      Standard Hypervisor Service Calls
+    Fast        6      Vendor Specific Hypervisor Service Calls
+    Fast        7      Vendor Specific EL3 Monitor Calls
+    Fast       8-47    Reserved for future use
     Fast      48-49    Trusted Application calls
     Fast      50-63    Trusted OS calls
 
@@ -312,9 +315,17 @@
 the BL31 support for these services. Or a reference to the document that will
 provide this information....
 
+Additional References:
+----------------------
+
+#. :ref:`ARM SiP Services <arm sip services>`
+#. :ref:`Vendor Specific EL3 Monitor Service Calls`
+
 --------------
 
-*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
 .. _PSCI: https://developer.arm.com/documentation/den0022/latest/
+.. _ARM SiP Services: arm-sip-service.rst
+.. _Vendor Specific EL3 Monitor Service Calls: ven-el3-service.rst
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 679de2b..c02e938 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -40,6 +40,9 @@
       Common Vulnerabilities and Exposures. A CVE document is commonly used to
       describe a publicly-known security vulnerability.
 
+   DICE
+      Device Identifier Composition Engine
+
    DCE
       DRTM Configuration Environment
 
@@ -52,6 +55,9 @@
    DRTM
       Dynamic Root of Trust for Measurement
 
+   DPE
+      DICE Protection Environment
+
    DS-5
       Arm Development Studio 5
 
diff --git a/docs/index.rst b/docs/index.rst
index cdb237a..c05c0a5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -95,4 +95,4 @@
 .. _System Control and Management Interface (SCMI): http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
 .. _Software Delegated Exception Interface (SDEI): http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
diff --git a/docs/license.rst b/docs/license.rst
index 80f1118..8996105 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -85,6 +85,17 @@
 
    See the original `Linux MIT license`_.
 
+-  Some source files originating from the `Open Profile for DICE`_ project.
+   These files are licensed under the Apache License, Version 2.0, which is a
+   permissive license compatible with BSD-3-Clause. Any contributions to this
+   code must also be made under the terms of `Apache License 2.0`_.
+   These files are:
+
+   -  ``include/lib/dice/dice.h``
+
 .. _FreeBSD: http://www.freebsd.org
 .. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
 .. _SCC: http://www.simple-cc.org/
+.. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
+.. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt
+
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index bab1086..43a7d59 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -31,8 +31,8 @@
 
 The following source trees and binaries were used:
 
-- TF-A [`v2.9-rc0`_]
-- TFTF [`v2.9-rc0`_]
+- `TF-A v2.11-rc0`_
+- `TFTF v2.11-rc0`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
 <Runtime Instrumentation Methodology>`
@@ -73,23 +73,23 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.9)
+        parallel (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   104.58  | 241.20 |     5.26    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   384.24  | 22.50  |    138.76   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   244.56  | 22.18  |     5.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   670.56  | 18.58  |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   809.36  | 269.28 |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   984.96  | 219.70 |    79.62    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-------------------+--------------------+-------------+
+    | Cluster | Core |     Powerdown     |       Wakeup       | Cache Flush |
+    +---------+------+-------------------+--------------------+-------------+
+    |    0    |  0   |  112.98 (-53.44%) |  26.16 (-89.33%)   |     5.48    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    0    |  1   |       411.18      | 438.88 (+1572.56%) |    138.54   |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  0   | 261.82 (+150.88%) | 474.06 (+1649.30%) |     5.6     |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  1   |  714.76 (+86.84%) |       26.44        |     4.48    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  2   |       862.66      |  149.34 (-45.00%)  |     4.38    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  3   |      1045.12      |  98.12 (-55.76%)   |    79.74    |
+    +---------+------+-------------------+--------------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
         parallel (v2.10)
@@ -111,22 +111,22 @@
     +---------+------+-------------------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.9)
+        serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.56  | 23.24  |    138.18   |
+    |    0    |  0   |   244.42  | 27.42  |    138.12   |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   236.86  | 23.28  |    138.10   |
+    |    0    |  1   |   245.02  | 27.34  |    138.08   |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   281.04  | 22.80  |    77.24    |
+    |    1    |  0   |   297.66  |  26.2  |    77.68    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.28  | 18.52  |     4.54    |
+    |    1    |  1   |   108.02  | 21.94  |     4.52    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.12  | 18.78  |     4.50    |
+    |    1    |  2   |   107.48  | 21.88  |     4.46    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.36  | 18.94  |     4.44    |
+    |    1    |  3   |   107.52  | 21.86  |     4.46    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
@@ -152,23 +152,23 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.9)
+        parallel (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   662.34  | 15.22  |     8.08    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   802.00  | 15.50  |     8.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   385.22  | 15.74  |     7.88    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   106.16  | 16.06  |     7.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   524.38  | 15.64  |     7.34    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   246.00  | 15.78  |     7.72    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-------------------+--------+-------------+
+    | Cluster | Core |     Powerdown     | Wakeup | Cache Flush |
+    +---------+------+-------------------+--------+-------------+
+    |    0    |  0   |       704.46      | 19.28  |     7.86    |
+    +---------+------+-------------------+--------+-------------+
+    |    0    |  1   |       853.66      | 18.78  |     7.82    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  0   | 556.52 (+425.51%) | 19.06  |     7.82    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  1   |  113.28 (-70.47%) | 19.28  |     7.48    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  2   |  260.62 (-50.22%) |  19.8  |     7.26    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  3   |  408.16 (+66.94%) | 19.82  |     7.38    |
+    +---------+------+-------------------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
         parallel (v2.10)
@@ -189,22 +189,22 @@
     |    1    |  3   |       244.5       | 20.16  |     7.56    |
     +---------+------+-------------------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   99.80   | 15.94  |     5.42    |
+    |    0    |  0   |   106.78  |  19.2  |     5.32    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   99.76   | 15.80  |     5.24    |
+    |    0    |  1   |   107.44  | 19.64  |     5.44    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   278.26  | 16.16  |     4.58    |
+    |    1    |  0   |   295.82  | 19.14  |     4.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   96.88   | 16.00  |     4.52    |
+    |    1    |  1   |   104.34  | 19.18  |     4.28    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   96.80   | 16.12  |     4.54    |
+    |    1    |  2   |   103.96  | 19.34  |     4.4     |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   96.88   | 16.12  |     4.54    |
+    |    1    |  3   |   104.32  | 19.18  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
@@ -231,22 +231,22 @@
 ``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
 core to the deepest power level.
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.9)
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   235.76  | 26.14  |    137.80   |
+    |    0    |  0   |   243.62  | 29.84  |    137.66   |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   235.40  | 25.72  |    137.62   |
+    |    0    |  1   |   243.88  | 29.54  |    137.8    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   174.70  | 22.40  |    77.26    |
+    |    1    |  0   |   183.26  | 26.22  |    77.76    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.92  | 24.04  |     4.52    |
+    |    1    |  1   |   107.64  | 26.74  |     4.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.68  | 22.44  |     4.36    |
+    |    1    |  2   |   107.52  |  25.9  |     4.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   101.36  | 22.70  |     4.52    |
+    |    1    |  3   |   107.74  |  25.8  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
@@ -272,23 +272,23 @@
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.9)
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.11)
 
-    +-------------+--------+-------------+
-    |   Cluster   |  Core  |   Latency   |
-    +-------------+--------+-------------+
-    |      0      |   0    |     1.48    |
-    +-------------+--------+-------------+
-    |      0      |   1    |     1.04    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.56    |
-    +-------------+--------+-------------+
-    |      1      |   1    |     0.92    |
-    +-------------+--------+-------------+
-    |      1      |   2    |     0.96    |
-    +-------------+--------+-------------+
-    |      1      |   3    |     0.96    |
-    +-------------+--------+-------------+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     1.26     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     0.96     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.54     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     0.92     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     1.02     |
+    +-------------+--------+--------------+
 
 .. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.10)
 
@@ -526,8 +526,9 @@
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _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
+.. _TF-A v2.11-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.11-rc0
+.. _TFTF v2.11-rc0: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/?h=v2.11-rc0
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
index fd3c9c9..c1c4dd6 100644
--- a/docs/perf/psci-performance-n1sdp.rst
+++ b/docs/perf/psci-performance-n1sdp.rst
@@ -6,8 +6,8 @@
 
 The following source trees and binaries were used:
 
-- TF-A [`v2.9-rc0-16-g666aec401`_]
-- TFTF [`v2.9-rc0`_]
+- `TF-A v2.11-rc0`_
+- `TFTF v2.11-rc0`_
 - SCP/MCP `Prebuilt Images`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
@@ -92,20 +92,19 @@
 ``CPU_SUSPEND`` to deepest power level
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in parallel (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.80   | 10.08  |     0.80    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    4.14   | 15.92  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    3.68   | 12.96  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    3.36   | 18.58  |     0.18    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+----------------+--------+----------------+
+    | Cluster | Core |   Powerdown    | Wakeup |  Cache Flush   |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   | 3.0 (+41.51%)  | 23.14  | 1.2 (+185.71%) |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   |      4.6       | 35.86  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   | 3.68 (+33.33%) | 33.36  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   | 3.7 (+40.15%)  |  38.1  |      0.28      |
+    +---------+------+----------------+--------+----------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
         parallel (v2.10)
@@ -122,19 +121,18 @@
     |    1    |  0   |      2.64      | 44.56 (+139.83%) | 0.36 (+100.00%) |
     +---------+------+----------------+------------------+-----------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.86   |  9.92  |     0.32    |
+    |    0    |  0   |    1.7    | 22.46  |     0.3     |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.70   | 10.48  |     0.36    |
+    |    0    |  0   |    2.28   |  22.5  |     0.3     |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.78   |  9.72  |     0.16    |
+    |    1    |  0   |    2.14   |  21.5  |     0.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.94   | 10.44  |     0.16    |
+    |    1    |  0   |    2.24   | 22.66  |     0.3     |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
@@ -155,22 +153,19 @@
 ``CPU_SUSPEND`` to power level 0
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in parallel (v2.11)
 
-    +---------------------------------------------------+
-    |          test_rt_instr_cpu_susp_parallel          |
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    0.88   | 12.32  |     0.26    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.12   | 14.62  |     0.26    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.86   | 14.14  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.92   |  9.44  |     0.18    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+----------------+--------+-------------+
+    | Cluster | Core |   Powerdown    | Wakeup | Cache Flush |
+    +---------+------+----------------+--------+-------------+
+    |    0    |  0   | 0.94 (-37.33%) | 30.36  |     0.3     |
+    +---------+------+----------------+--------+-------------+
+    |    0    |  0   |      2.12      | 33.12  |     0.28    |
+    +---------+------+----------------+--------+-------------+
+    |    1    |  0   |      2.08      | 32.56  |     0.3     |
+    +---------+------+----------------+--------+-------------+
+    |    1    |  0   |      2.14      | 21.92  |     0.28    |
+    +---------+------+----------------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
         parallel (v2.10)
@@ -187,20 +182,18 @@
     |    1    |  0   |      2.04     | 23.1 (+144.70%)  |      0.24      |
     +---------+------+---------------+------------------+----------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
-    +---------------------------------------------------+
-    |           test_rt_instr_cpu_susp_serial           |
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.52   |  9.40  |     0.30    |
+    |    0    |  0   |    1.64   | 21.88  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.92   |  9.80  |     0.18    |
+    |    0    |  0   |    2.42   | 21.76  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    2.20   |  9.60  |     0.14    |
+    |    1    |  0   |    2.02   | 21.14  |     0.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.82   |  9.78  |     0.18    |
+    |    1    |  0   |    2.18   |  22.3  |     0.34    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
@@ -223,19 +216,19 @@
 ``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
 core to the deepest power level.
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.9)
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.84   |  9.94  |     0.32    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   14.20   | 13.10  |     0.50    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   13.88   | 12.36  |     0.42    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   14.40   | 13.26  |     0.52    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.96   | 22.44  |      0.38      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |   13.76   | 30.34  |      0.26      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.46   | 28.28  |      0.24      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.84   | 30.06  | 0.28 (-60.00%) |
+    +---------+------+-----------+--------+----------------+
 
 .. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
 
@@ -254,21 +247,19 @@
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.9)
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.11)
 
-    +------------------------------------+
-    | test_rt_instr_psci_version_parallel|
-    +-------------+--------+-------------+
-    |   Cluster   |  Core  |   Latency   |
-    +-------------+--------+-------------+
-    |      0      |   0    |     0.08    |
-    +-------------+--------+-------------+
-    |      0      |   0    |     0.26    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.20    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.26    |
-    +-------------+--------+-------------+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     0.12     |
+    +-------------+--------+--------------+
+    |      0      |   0    |     0.24     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.2      |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.26     |
+    +-------------+--------+--------------+
 
 .. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.10)
 
@@ -288,10 +279,10 @@
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
 
-.. _v2.9-rc0-16-g666aec401: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/v2.9-rc0-16-g666aec401
-.. _v2.9-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.9-rc0
+.. _TF-A v2.11-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.11-rc0
+.. _TFTF v2.11-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.11-rc0
 .. _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
diff --git a/docs/plat/amd-versal2.rst b/docs/plat/amd-versal2.rst
new file mode 100644
index 0000000..876ab3c
--- /dev/null
+++ b/docs/plat/amd-versal2.rst
@@ -0,0 +1,87 @@
+AMD Versal Gen 2
+================
+
+Trusted Firmware-A implements the EL3 firmware layer for AMD Versal Gen 2.
+The platform only uses the runtime part of TF-A as AMD Versal Gen 2 already
+has a BootROM (BL1) and PMC FW (BL2).
+
+BL31 is TF-A.
+BL32 is an optional Secure Payload.
+BL33 is the non-secure world software (U-Boot, Linux etc).
+
+To build:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31
+```
+
+To build TF-A for JTAG DCC console:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 CONSOLE=dcc bl31
+```
+
+To build TF-A with Errata management interface
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31 ERRATA_ABI_SUPPORT=1
+```
+
+To build TF-A with IPI CRC check:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31 IPI_CRC_CHECK=1
+```
+
+AMD Versal Gen 2 platform specific build options
+-------------------------------------------------
+
+*   `MEM_BASE`: Specifies the base address of the bl31 binary.
+*   `MEM_SIZE`: Specifies the size of the memory region of the bl31 binary.
+*   `BL32_MEM_BASE`: Specifies the base address of the bl32 binary.
+*   `BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
+
+*   `CONSOLE`: Select the console driver. Options:
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0 (default)
+    -   `pl011_1`         : ARM pl011 UART 1
+    -   `dcc`             : JTAG Debug Communication Channel(DCC)
+
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+------------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+| SMC Function Identifier   |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 3301067..e1b3ef0 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -121,17 +121,6 @@
    management operations and for SCP RAM Firmware transfer. If this option
    is set to 1, then SCMI/SDS drivers will be used. Default is 0.
 
- - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform
-   which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any
-   valid value greater than 1, the platform code performs required configuration
-   to support multi-chip operation.
-
-- ``CSS_SGI_PLATFORM_VARIANT``: Selects the variant of a SGI/RD platform. A
-    particular SGI/RD platform may have multiple variants which may differ in
-    core count, cluster count or other peripherals. This build option is used
-    to select the appropriate platform variant for the build. The range of
-    valid values is platform specific.
-
 - ``CSS_SYSTEM_GRACEFUL_RESET``: Build option to enable graceful powerdown of
    CPU core on reset. This build option can be used on CSS platforms that
    require all the CPUs to execute the CPU specific power down sequence to
@@ -152,8 +141,22 @@
    AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
    images.
 
+Arm Neoverse RD Platform Build Options
+--------------------------------------
+
+ - ``NRD_CHIP_COUNT``: Configures the number of chips on a Neoverse RD platform
+   which supports multi-chip operation. If ``NRD_CHIP_COUNT`` is set to any
+   valid value greater than 1, the platform code performs required configuration
+   to support multi-chip operation.
+
+- ``NRD_PLATFORM_VARIANT``: Selects the variant of a Neoverse RD platform. A
+  particular Neoverse RD platform may have multiple variants which may differ in
+  core count, cluster count or other peripherals. This build option is used to
+  select the appropriate platform variant for the build. The range of valid
+  values is platform specific.
+
 --------------
 
 .. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-aemv8-base.rst b/docs/plat/arm/fvp/fvp-aemv8-base.rst
new file mode 100644
index 0000000..6dd35e5
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-aemv8-base.rst
@@ -0,0 +1,154 @@
+Running on the AEMv8 Base FVP
+=============================
+
+AArch64 with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_RevC-2xAEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+.. note::
+   The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires
+   a specific DTS for all the CPUs to be loaded.
+
+AArch32 with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.CONFIG64=0                                 \
+    -C cluster0.cpu1.CONFIG64=0                                 \
+    -C cluster0.cpu2.CONFIG64=0                                 \
+    -C cluster0.cpu3.CONFIG64=0                                 \
+    -C cluster1.cpu0.CONFIG64=0                                 \
+    -C cluster1.cpu1.CONFIG64=0                                 \
+    -C cluster1.cpu2.CONFIG64=0                                 \
+    -C cluster1.cpu3.CONFIG64=0                                 \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+AArch64 with reset to BL31 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_RevC-2xAEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBAR=0x04010000                            \
+    -C cluster0.cpu1.RVBAR=0x04010000                            \
+    -C cluster0.cpu2.RVBAR=0x04010000                            \
+    -C cluster0.cpu3.RVBAR=0x04010000                            \
+    -C cluster1.cpu0.RVBAR=0x04010000                            \
+    -C cluster1.cpu1.RVBAR=0x04010000                            \
+    -C cluster1.cpu2.RVBAR=0x04010000                            \
+    -C cluster1.cpu3.RVBAR=0x04010000                            \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Notes:
+
+-  Position Independent Executable (PIE) support is enabled in this
+   config allowing BL31 to be loaded at any valid address for execution.
+
+-  Since a FIP is not loaded when using BL31 as reset entrypoint, the
+   ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
+   parameter is needed to load the individual bootloader images in memory.
+   BL32 image is only needed if BL31 has been built to expect a Secure-EL1
+   Payload. For the same reason, the FDT needs to be compiled from the DT source
+   and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
+   parameter.
+
+-  The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
+   specific DTS for all the CPUs to be loaded.
+
+-  The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
+   X and Y are the cluster and CPU numbers respectively, is used to set the
+   reset vector for each core.
+
+-  Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
+   changing the value of
+   ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
+   ``BL32_BASE``.
+
+AArch32 with reset to SP_MIN entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.CONFIG64=0                                  \
+    -C cluster0.cpu1.CONFIG64=0                                  \
+    -C cluster0.cpu2.CONFIG64=0                                  \
+    -C cluster0.cpu3.CONFIG64=0                                  \
+    -C cluster1.cpu0.CONFIG64=0                                  \
+    -C cluster1.cpu1.CONFIG64=0                                  \
+    -C cluster1.cpu2.CONFIG64=0                                  \
+    -C cluster1.cpu3.CONFIG64=0                                  \
+    -C cluster0.cpu0.RVBAR=0x04002000                            \
+    -C cluster0.cpu1.RVBAR=0x04002000                            \
+    -C cluster0.cpu2.RVBAR=0x04002000                            \
+    -C cluster0.cpu3.RVBAR=0x04002000                            \
+    -C cluster1.cpu0.RVBAR=0x04002000                            \
+    -C cluster1.cpu1.RVBAR=0x04002000                            \
+    -C cluster1.cpu2.RVBAR=0x04002000                            \
+    -C cluster1.cpu3.RVBAR=0x04002000                            \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+.. note::
+   Position Independent Executable (PIE) support is enabled in this
+   config allowing SP_MIN to be loaded at any valid address for execution.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-build-options.rst b/docs/plat/arm/fvp/fvp-build-options.rst
new file mode 100644
index 0000000..b0359fa
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-build-options.rst
@@ -0,0 +1,51 @@
+.. _build_options_arm_fvp_platform:
+
+Arm FVP Platform Specific Build Options
+---------------------------------------
+
+-  ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
+   build the topology tree within TF-A. By default TF-A is configured for dual
+   cluster topology and this option can be used to override the default value.
+
+-  ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
+   default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
+   explained in the options below:
+
+   -  ``FVP_CCI`` : The CCI driver is selected. This is the default
+      if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
+   -  ``FVP_CCN`` : The CCN driver is selected. This is the default
+      if ``FVP_CLUSTER_COUNT`` > 2.
+
+-  ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
+   a single cluster.  This option defaults to 4.
+
+-  ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
+   in the system. This option defaults to 1. Note that the build option
+   ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
+
+-  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
+
+   -  ``FVP_GICV2`` : The GICv2 only driver is selected
+   -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
+
+-  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
+   to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
+   details on HW_CONFIG. By default, this is initialized to a sensible DTS
+   file in ``fdts/`` folder depending on other build options. But some cases,
+   like shifted affinity format for MPIDR, cannot be detected at build time
+   and this option is needed to specify the appropriate DTS file.
+
+-  ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
+   FIP. See :ref:`Firmware Design` for details on HW_CONFIG. This option is
+   similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
+   HW_CONFIG blob instead of the DTS file. This option is useful to override
+   the default HW_CONFIG selected by the build system.
+
+-  ``FVP_GICR_REGION_PROTECTION``: Mark the redistributor pages of
+   inactive/fused CPU cores as read-only. The default value of this option
+   is ``0``, which means the redistributor pages of all CPU cores are marked
+   as read and write.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-cortex-a32.rst b/docs/plat/arm/fvp/fvp-cortex-a32.rst
new file mode 100644
index 0000000..df17eed
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-cortex-a32.rst
@@ -0,0 +1,47 @@
+Running on the Cortex-A32 Base FVP (AArch32)
+============================================
+
+With reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+With reset to SP_MIN entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu1.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu2.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu3.RVBARADDR=0x04002000                       \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000   \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-cortex-a57-a53.rst b/docs/plat/arm/fvp/fvp-cortex-a57-a53.rst
new file mode 100644
index 0000000..8f54114
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-cortex-a57-a53.rst
@@ -0,0 +1,52 @@
+Running on the Cortex-A57-A53 Base FVP
+======================================
+
+With reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+With reset to BL31 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu1.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu2.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu3.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu0.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu1.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu2.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu3.RVBARADDR=0x04010000                        \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-foundation.rst b/docs/plat/arm/fvp/fvp-foundation.rst
new file mode 100644
index 0000000..dd6f9dc
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-foundation.rst
@@ -0,0 +1,42 @@
+Running on the Foundation FVP
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``Foundation_Platform`` parameters should be used to boot Linux with
+4 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/Foundation_Platform                   \
+    --cores=4                                       \
+    --arm-v8.0                                      \
+    --secure-memory                                 \
+    --visualization                                 \
+    --gicv3                                         \
+    --data="<path-to>/<bl1-binary>"@0x0             \
+    --data="<path-to>/<FIP-binary>"@0x08000000      \
+    --data="<path-to>/<kernel-binary>"@0x80080000   \
+    --data="<path-to>/<ramdisk-binary>"@0x84000000
+
+Notes:
+
+-  BL1 is loaded at the start of the Trusted ROM.
+-  The Firmware Image Package is loaded at the start of NOR FLASH0.
+-  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
+   is specified via the ``load-address`` property in the ``hw-config`` node of
+   `FW_CONFIG for FVP`_.
+-  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
+   and enable the GICv3 device in the model. Note that without this option,
+   the Foundation FVP defaults to legacy (Versatile Express) memory map which
+   is not supported by TF-A.
+-  In order for TF-A to run correctly on the Foundation FVP, the architecture
+   versions must match. The Foundation FVP defaults to the highest v8.x
+   version it supports but the default build for TF-A is for v8.0. To avoid
+   issues either start the Foundation FVP to use v8.0 architecture using the
+   ``--arm-v8.0`` option, or build TF-A with an appropriate value for
+   ``ARM_ARCH_MINOR``.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
+
+.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
diff --git a/docs/plat/arm/fvp/fvp-specific-configs.rst b/docs/plat/arm/fvp/fvp-specific-configs.rst
new file mode 100644
index 0000000..63b3c31
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-specific-configs.rst
@@ -0,0 +1,209 @@
+Booting Firmware Update images
+------------------------------
+
+When Firmware Update (FWU) is enabled there are at least 2 new images
+that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
+FWU FIP.
+
+The additional fip images must be loaded with:
+
+::
+
+    --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000	[ns_bl1u_base_address]
+    --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000	[ns_bl2u_base_address]
+
+The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
+In the same way, the address ns_bl2u_base_address is the value of
+NS_BL2U_BASE.
+
+Booting an EL3 payload
+----------------------
+
+The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
+the secondary CPUs holding pen to work properly. Unfortunately, its reset value
+is undefined on the FVP platform and the FVP platform code doesn't clear it.
+Therefore, one must modify the way the model is normally invoked in order to
+clear the mailbox at start-up.
+
+One way to do that is to create an 8-byte file containing all zero bytes using
+the following command:
+
+.. code:: shell
+
+    dd if=/dev/zero of=mailbox.dat bs=1 count=8
+
+and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
+using the following model parameters:
+
+::
+
+    --data cluster0.cpu0=mailbox.dat@0x04000000   [Base FVPs]
+    --data=mailbox.dat@0x04000000                 [Foundation FVP]
+
+To provide the model with the EL3 payload image, the following methods may be
+used:
+
+#. If the EL3 payload is able to execute in place, it may be programmed into
+   flash memory. On Base Cortex and AEM FVPs, the following model parameter
+   loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
+   used for the FIP):
+
+   ::
+
+       -C bp.flashloader1.fname="<path-to>/<el3-payload>"
+
+   On Foundation FVP, there is no flash loader component and the EL3 payload
+   may be programmed anywhere in flash using method 3 below.
+
+#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
+   command may be used to load the EL3 payload ELF image over JTAG:
+
+   ::
+
+       load <path-to>/el3-payload.elf
+
+#. The EL3 payload may be pre-loaded in volatile memory using the following
+   model parameters:
+
+   ::
+
+       --data cluster0.cpu0="<path-to>/el3-payload>"@address   [Base FVPs]
+       --data="<path-to>/<el3-payload>"@address                [Foundation FVP]
+
+   The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
+   used when building TF-A.
+
+Booting a preloaded kernel image (Base FVP)
+-------------------------------------------
+
+The following example uses a simplified boot flow by directly jumping from the
+TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
+useful if both the kernel and the device tree blob (DTB) are already present in
+memory (like in FVP).
+
+For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
+address ``0x82000000``, the firmware can be built like this:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-none-elf-  \
+    make PLAT=fvp DEBUG=1             \
+    RESET_TO_BL31=1                   \
+    ARM_LINUX_KERNEL_AS_BL33=1        \
+    PRELOADED_BL33_BASE=0x80080000    \
+    ARM_PRELOADED_DTB_BASE=0x82000000 \
+    all fip
+
+Now, it is needed to modify the DTB so that the kernel knows the address of the
+ramdisk. The following script generates a patched DTB from the provided one,
+assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
+script assumes that the user is using a ramdisk image prepared for U-Boot, like
+the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
+offset in ``INITRD_START`` has to be removed.
+
+.. code:: bash
+
+    #!/bin/bash
+
+    # Path to the input DTB
+    KERNEL_DTB=<path-to>/<fdt>
+    # Path to the output DTB
+    PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
+    # Base address of the ramdisk
+    INITRD_BASE=0x84000000
+    # Path to the ramdisk
+    INITRD=<path-to>/<ramdisk.img>
+
+    # Skip uboot header (64 bytes)
+    INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
+    INITRD_SIZE=$(stat -Lc %s ${INITRD})
+    INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
+
+    CHOSEN_NODE=$(echo                                        \
+    "/ {                                                      \
+            chosen {                                          \
+                    linux,initrd-start = <${INITRD_START}>;   \
+                    linux,initrd-end = <${INITRD_END}>;       \
+            };                                                \
+    };")
+
+    echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} |  \
+            dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
+
+And the FVP binary can be run with the following command:
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBAR=0x04001000                           \
+    -C cluster0.cpu1.RVBAR=0x04001000                           \
+    -C cluster0.cpu2.RVBAR=0x04001000                           \
+    -C cluster0.cpu3.RVBAR=0x04001000                           \
+    -C cluster1.cpu0.RVBAR=0x04001000                           \
+    -C cluster1.cpu1.RVBAR=0x04001000                           \
+    -C cluster1.cpu2.RVBAR=0x04001000                           \
+    -C cluster1.cpu3.RVBAR=0x04001000                           \
+    --data cluster0.cpu0="<path-to>/bl31.bin"@0x04001000        \
+    --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000   \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
+
+Obtaining the Flattened Device Trees
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Depending on the FVP configuration and Linux configuration used, different
+FDT files are required. FDT source files for the Foundation and Base FVPs can
+be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
+a subset of the Base FVP components. For example, the Foundation FVP lacks
+CLCD and MMC support, and has only one CPU cluster.
+
+.. note::
+   It is not recommended to use the FDTs built along the kernel because not
+   all FDTs are available from there.
+
+The dynamic configuration capability is enabled in the firmware for FVPs.
+This means that the firmware can authenticate and load the FDT if present in
+FIP. A default FDT is packaged into FIP during the build based on
+the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
+or ``FVP_HW_CONFIG_DTS`` build options (refer to
+:ref:`build_options_arm_fvp_platform` for details on the options).
+
+-  ``fvp-base-gicv2-psci.dts``
+
+   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
+   without shifted affinities and with Base memory map configuration.
+
+-  ``fvp-base-gicv3-psci.dts``
+
+   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
+   without shifted affinities and with Base memory map configuration and
+   Linux GICv3 support.
+
+-  ``fvp-base-gicv3-psci-1t.dts``
+
+   For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
+   single threaded CPUs, Base memory map configuration and Linux GICv3 support.
+
+-  ``fvp-base-gicv3-psci-dynamiq.dts``
+
+   For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
+   single cluster, single threaded CPUs, Base memory map configuration and Linux
+   GICv3 support.
+
+-  ``fvp-foundation-gicv2-psci.dts``
+
+   For use with Foundation FVP with Base memory map configuration.
+
+-  ``fvp-foundation-gicv3-psci.dts``
+
+   (Default) For use with Foundation FVP with Base memory map configuration
+   and Linux GICv3 support.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-support.rst b/docs/plat/arm/fvp/fvp-support.rst
new file mode 100644
index 0000000..5292d68
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-support.rst
@@ -0,0 +1,101 @@
+Fixed Virtual Platform (FVP) Support
+------------------------------------
+
+This section lists the supported Arm |FVP| platforms. Please refer to the FVP
+documentation for a detailed description of the model parameter options.
+
+The latest version of the AArch64 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+.. note::
+   The FVP models used are Version 11.26 Build 11, unless otherwise stated.
+
+-  ``FVP_Base_AEMvA``
+-  ``FVP_Base_AEMvA-AEMvA``
+-  ``FVP_Base_Cortex-A32x4``
+-  ``FVP_Base_Cortex-A35x4``
+-  ``FVP_Base_Cortex-A53x4``
+-  ``FVP_Base_Cortex-A55``
+-  ``FVP_Base_Cortex-A57x1-A53x1``
+-  ``FVP_Base_Cortex-A57x2-A53x4``
+-  ``FVP_Base_Cortex-A57x4``
+-  ``FVP_Base_Cortex-A57x4-A53x4``
+-  ``FVP_Base_Cortex-A65`` (Version 11.24/24)
+-  ``FVP_Base_Cortex-A65AE`` (Version 11.24/24)
+-  ``FVP_Base_Cortex-A710``
+-  ``FVP_Base_Cortex-A72x4``
+-  ``FVP_Base_Cortex-A72x4-A53x4``
+-  ``FVP_Base_Cortex-A73x4``
+-  ``FVP_Base_Cortex-A73x4-A53x4``
+-  ``FVP_Base_Cortex-A75``
+-  ``FVP_Base_Cortex-A76``
+-  ``FVP_Base_Cortex-A76AE``
+-  ``FVP_Base_Cortex-A77``
+-  ``FVP_Base_Cortex-A78``
+-  ``FVP_Base_Cortex-A78AE``
+-  ``FVP_Base_Cortex-A78C``
+-  ``FVP_Base_Cortex-X2``
+-  ``FVP_Base_Neoverse-E1`` (Version 11.24/24)
+-  ``FVP_Base_Neoverse-N1``
+-  ``FVP_Base_Neoverse-N2``
+-  ``FVP_Base_Neoverse-V1``
+-  ``FVP_Base_RevC-2xAEMv8A``
+-  ``FVP_BaseR_AEMv8R``
+-  ``FVP_Morello`` (Version 0.11/33)
+-  ``FVP_RD_V1``
+-  ``FVP_TC2`` (Version 11.23/17)
+
+The latest version of the AArch32 build of TF-A has been tested on the
+following Arm FVPs without shifted affinities, and that do not support threaded
+CPU cores (64-bit host machine only).
+
+-  ``FVP_Base_AEMvA``
+-  ``FVP_Base_AEMvA-AEMvA``
+-  ``FVP_Base_Cortex-A32x4``
+
+.. note::
+   The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
+   is not compatible with legacy GIC configurations. Therefore this FVP does not
+   support these legacy GIC configurations.
+
+The *Foundation* and *Base* FVPs can be downloaded free of charge. See the `Arm
+FVP website`_. The Cortex-A models listed above are also available to download
+from `Arm's website`_.
+
+.. note::
+   The build numbers quoted above are those reported by launching the FVP
+   with the ``--version`` parameter.
+
+.. note::
+   Linaro provides a ramdisk image in prebuilt FVP configurations and full
+   file systems that can be downloaded separately. To run an FVP with a virtio
+   file system image an additional FVP configuration option
+   ``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
+   used.
+
+.. note::
+   The software will not work on Version 1.0 of the Foundation FVP.
+   The commands below would report an ``unhandled argument`` error in this case.
+
+.. note::
+   FVPs can be launched with ``--cadi-server`` option such that a
+   CADI-compliant debugger (for example, Arm DS-5) can connect to and control
+   its execution.
+
+.. warning::
+   Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
+   the internal synchronisation timings changed compared to older versions of
+   the models. The models can be launched with ``-Q 100`` option if they are
+   required to match the run time characteristics of the older versions.
+
+All the above platforms have been tested with `Linaro Release 20.01`_.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
+
+.. _Arm's website: `FVP models`_
+.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
+.. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 55cefe1..088beec 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -1,638 +1,31 @@
 Arm Fixed Virtual Platforms (FVP)
 =================================
 
-Fixed Virtual Platform (FVP) Support
-------------------------------------
+Arm |FVP|\s are complete simulations of an Arm system, including processor,
+memory and peripherals. They enable software development without the need for
+real hardware.
 
-This section lists the supported Arm |FVP| platforms. Please refer to the FVP
-documentation for a detailed description of the model parameter options.
+There exists many types of FVPs. This page provides details on how to build and
+run TF-A on some of these FVPs.
 
-The latest version of the AArch64 build of TF-A has been tested on the following
-Arm FVPs without shifted affinities, and that do not support threaded CPU cores
-(64-bit host machine only).
+Please also refer to the TF-A CI scripts under the `model/`_ directory for an
+exhaustive list of |FVP|\s which TF-A is regularly tested on as part of our
+continuous integration strategy.
 
-.. note::
-   The FVP models used are Version 11.22 Build 14, unless otherwise stated.
+.. toctree::
+  :maxdepth: 1
+  :caption: Contents
 
--  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` (Version 11.17/21)
--  ``FVP_Base_AEMv8A-GIC600AE`` (Version 11.17/21)
--  ``FVP_Base_AEMvA``
--  ``FVP_Base_AEMvA-AEMvA``
--  ``FVP_Base_Cortex-A32x4`` (Version 11.12/38)
--  ``FVP_Base_Cortex-A35x4``
--  ``FVP_Base_Cortex-A53x4``
--  ``FVP_Base_Cortex-A55``
--  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
--  ``FVP_Base_Cortex-A55x4+Cortex-A76x2``
--  ``FVP_Base_Cortex-A57x1-A53x1``
--  ``FVP_Base_Cortex-A57x2-A53x4``
--  ``FVP_Base_Cortex-A57x4``
--  ``FVP_Base_Cortex-A57x4-A53x4``
--  ``FVP_Base_Cortex-A65``
--  ``FVP_Base_Cortex-A65AE``
--  ``FVP_Base_Cortex-A710x4`` (Version 11.17/21)
--  ``FVP_Base_Cortex-A72x4``
--  ``FVP_Base_Cortex-A72x4-A53x4``
--  ``FVP_Base_Cortex-A73x4``
--  ``FVP_Base_Cortex-A73x4-A53x4``
--  ``FVP_Base_Cortex-A75``
--  ``FVP_Base_Cortex-A76``
--  ``FVP_Base_Cortex-A76AE``
--  ``FVP_Base_Cortex-A77``
--  ``FVP_Base_Cortex-A78``
--  ``FVP_Base_Cortex-A78AE``
--  ``FVP_Base_Cortex-A78C``
--  ``FVP_Base_Cortex-X2x4`` (Version 11.17/21)
--  ``FVP_Base_Neoverse-E1``
--  ``FVP_Base_Neoverse-N1``
--  ``FVP_Base_Neoverse-V1``
--  ``FVP_Base_RevC-2xAEMvA``
--  ``FVP_BaseR_AEMv8R``
--  ``FVP_Morello`` (Version 0.11/33)
--  ``FVP_RD_V1``
--  ``FVP_TC1``
--  ``FVP_TC2`` (Version 11.23/17)
-
-The latest version of the AArch32 build of TF-A has been tested on the
-following Arm FVPs without shifted affinities, and that do not support threaded
-CPU cores (64-bit host machine only).
-
--  ``FVP_Base_AEMvA``
--  ``FVP_Base_AEMvA-AEMvA``
--  ``FVP_Base_Cortex-A32x4``
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMvA`` FVP only supports shifted affinities, which
-   is not compatible with legacy GIC configurations. Therefore this FVP does not
-   support these legacy GIC configurations.
-
-The *Foundation* and *Base* FVPs can be downloaded free of charge. See the `Arm
-FVP website`_. The Cortex-A models listed above are also available to download
-from `Arm's website`_.
-
-.. note::
-   The build numbers quoted above are those reported by launching the FVP
-   with the ``--version`` parameter.
-
-.. note::
-   Linaro provides a ramdisk image in prebuilt FVP configurations and full
-   file systems that can be downloaded separately. To run an FVP with a virtio
-   file system image an additional FVP configuration option
-   ``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
-   used.
-
-.. note::
-   The software will not work on Version 1.0 of the Foundation FVP.
-   The commands below would report an ``unhandled argument`` error in this case.
-
-.. note::
-   FVPs can be launched with ``--cadi-server`` option such that a
-   CADI-compliant debugger (for example, Arm DS-5) can connect to and control
-   its execution.
-
-.. warning::
-   Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
-   the internal synchronisation timings changed compared to older versions of
-   the models. The models can be launched with ``-Q 100`` option if they are
-   required to match the run time characteristics of the older versions.
-
-All the above platforms have been tested with `Linaro Release 20.01`_.
-
-.. _build_options_arm_fvp_platform:
-
-Arm FVP Platform Specific Build Options
----------------------------------------
-
--  ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
-   build the topology tree within TF-A. By default TF-A is configured for dual
-   cluster topology and this option can be used to override the default value.
-
--  ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
-   default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
-   explained in the options below:
-
-   -  ``FVP_CCI`` : The CCI driver is selected. This is the default
-      if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
-   -  ``FVP_CCN`` : The CCN driver is selected. This is the default
-      if ``FVP_CLUSTER_COUNT`` > 2.
-
--  ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
-   a single cluster.  This option defaults to 4.
-
--  ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
-   in the system. This option defaults to 1. Note that the build option
-   ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
-
--  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
-
-   -  ``FVP_GICV2`` : The GICv2 only driver is selected
-   -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
-
--  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
-   to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
-   details on HW_CONFIG. By default, this is initialized to a sensible DTS
-   file in ``fdts/`` folder depending on other build options. But some cases,
-   like shifted affinity format for MPIDR, cannot be detected at build time
-   and this option is needed to specify the appropriate DTS file.
-
--  ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
-   FIP. See :ref:`Firmware Design` for details on HW_CONFIG. This option is
-   similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
-   HW_CONFIG blob instead of the DTS file. This option is useful to override
-   the default HW_CONFIG selected by the build system.
-
--  ``FVP_GICR_REGION_PROTECTION``: Mark the redistributor pages of
-   inactive/fused CPU cores as read-only. The default value of this option
-   is ``0``, which means the redistributor pages of all CPU cores are marked
-   as read and write.
-
-Booting Firmware Update images
-------------------------------
-
-When Firmware Update (FWU) is enabled there are at least 2 new images
-that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
-FWU FIP.
-
-The additional fip images must be loaded with:
-
-::
-
-    --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000	[ns_bl1u_base_address]
-    --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000	[ns_bl2u_base_address]
-
-The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
-In the same way, the address ns_bl2u_base_address is the value of
-NS_BL2U_BASE.
-
-Booting an EL3 payload
-----------------------
-
-The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
-the secondary CPUs holding pen to work properly. Unfortunately, its reset value
-is undefined on the FVP platform and the FVP platform code doesn't clear it.
-Therefore, one must modify the way the model is normally invoked in order to
-clear the mailbox at start-up.
-
-One way to do that is to create an 8-byte file containing all zero bytes using
-the following command:
-
-.. code:: shell
-
-    dd if=/dev/zero of=mailbox.dat bs=1 count=8
-
-and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
-using the following model parameters:
-
-::
-
-    --data cluster0.cpu0=mailbox.dat@0x04000000   [Base FVPs]
-    --data=mailbox.dat@0x04000000                 [Foundation FVP]
-
-To provide the model with the EL3 payload image, the following methods may be
-used:
-
-#. If the EL3 payload is able to execute in place, it may be programmed into
-   flash memory. On Base Cortex and AEM FVPs, the following model parameter
-   loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
-   used for the FIP):
-
-   ::
-
-       -C bp.flashloader1.fname="<path-to>/<el3-payload>"
-
-   On Foundation FVP, there is no flash loader component and the EL3 payload
-   may be programmed anywhere in flash using method 3 below.
-
-#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
-   command may be used to load the EL3 payload ELF image over JTAG:
-
-   ::
-
-       load <path-to>/el3-payload.elf
-
-#. The EL3 payload may be pre-loaded in volatile memory using the following
-   model parameters:
-
-   ::
-
-       --data cluster0.cpu0="<path-to>/el3-payload>"@address   [Base FVPs]
-       --data="<path-to>/<el3-payload>"@address                [Foundation FVP]
-
-   The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
-   used when building TF-A.
-
-Booting a preloaded kernel image (Base FVP)
--------------------------------------------
-
-The following example uses a simplified boot flow by directly jumping from the
-TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
-useful if both the kernel and the device tree blob (DTB) are already present in
-memory (like in FVP).
-
-For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
-address ``0x82000000``, the firmware can be built like this:
-
-.. code:: shell
-
-    CROSS_COMPILE=aarch64-none-elf-  \
-    make PLAT=fvp DEBUG=1             \
-    RESET_TO_BL31=1                   \
-    ARM_LINUX_KERNEL_AS_BL33=1        \
-    PRELOADED_BL33_BASE=0x80080000    \
-    ARM_PRELOADED_DTB_BASE=0x82000000 \
-    all fip
-
-Now, it is needed to modify the DTB so that the kernel knows the address of the
-ramdisk. The following script generates a patched DTB from the provided one,
-assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
-script assumes that the user is using a ramdisk image prepared for U-Boot, like
-the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
-offset in ``INITRD_START`` has to be removed.
-
-.. code:: bash
-
-    #!/bin/bash
-
-    # Path to the input DTB
-    KERNEL_DTB=<path-to>/<fdt>
-    # Path to the output DTB
-    PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
-    # Base address of the ramdisk
-    INITRD_BASE=0x84000000
-    # Path to the ramdisk
-    INITRD=<path-to>/<ramdisk.img>
-
-    # Skip uboot header (64 bytes)
-    INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
-    INITRD_SIZE=$(stat -Lc %s ${INITRD})
-    INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
-
-    CHOSEN_NODE=$(echo                                        \
-    "/ {                                                      \
-            chosen {                                          \
-                    linux,initrd-start = <${INITRD_START}>;   \
-                    linux,initrd-end = <${INITRD_END}>;       \
-            };                                                \
-    };")
-
-    echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} |  \
-            dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
-
-And the FVP binary can be run with the following command:
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.RVBAR=0x04001000                           \
-    -C cluster0.cpu1.RVBAR=0x04001000                           \
-    -C cluster0.cpu2.RVBAR=0x04001000                           \
-    -C cluster0.cpu3.RVBAR=0x04001000                           \
-    -C cluster1.cpu0.RVBAR=0x04001000                           \
-    -C cluster1.cpu1.RVBAR=0x04001000                           \
-    -C cluster1.cpu2.RVBAR=0x04001000                           \
-    -C cluster1.cpu3.RVBAR=0x04001000                           \
-    --data cluster0.cpu0="<path-to>/bl31.bin"@0x04001000        \
-    --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000   \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
-
-Obtaining the Flattened Device Trees
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Depending on the FVP configuration and Linux configuration used, different
-FDT files are required. FDT source files for the Foundation and Base FVPs can
-be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
-a subset of the Base FVP components. For example, the Foundation FVP lacks
-CLCD and MMC support, and has only one CPU cluster.
-
-.. note::
-   It is not recommended to use the FDTs built along the kernel because not
-   all FDTs are available from there.
-
-The dynamic configuration capability is enabled in the firmware for FVPs.
-This means that the firmware can authenticate and load the FDT if present in
-FIP. A default FDT is packaged into FIP during the build based on
-the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
-or ``FVP_HW_CONFIG_DTS`` build options (refer to
-:ref:`build_options_arm_fvp_platform` for details on the options).
-
--  ``fvp-base-gicv2-psci.dts``
-
-   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
-   without shifted affinities and with Base memory map configuration.
-
--  ``fvp-base-gicv3-psci.dts``
-
-   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
-   without shifted affinities and with Base memory map configuration and
-   Linux GICv3 support.
-
--  ``fvp-base-gicv3-psci-1t.dts``
-
-   For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
-   single threaded CPUs, Base memory map configuration and Linux GICv3 support.
-
--  ``fvp-base-gicv3-psci-dynamiq.dts``
-
-   For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
-   single cluster, single threaded CPUs, Base memory map configuration and Linux
-   GICv3 support.
-
--  ``fvp-foundation-gicv2-psci.dts``
-
-   For use with Foundation FVP with Base memory map configuration.
-
--  ``fvp-foundation-gicv3-psci.dts``
-
-   (Default) For use with Foundation FVP with Base memory map configuration
-   and Linux GICv3 support.
-
-
-Running on the Foundation FVP with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``Foundation_Platform`` parameters should be used to boot Linux with
-4 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/Foundation_Platform                   \
-    --cores=4                                       \
-    --arm-v8.0                                      \
-    --secure-memory                                 \
-    --visualization                                 \
-    --gicv3                                         \
-    --data="<path-to>/<bl1-binary>"@0x0             \
-    --data="<path-to>/<FIP-binary>"@0x08000000      \
-    --data="<path-to>/<kernel-binary>"@0x80080000   \
-    --data="<path-to>/<ramdisk-binary>"@0x84000000
-
-Notes:
-
--  BL1 is loaded at the start of the Trusted ROM.
--  The Firmware Image Package is loaded at the start of NOR FLASH0.
--  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
-   is specified via the ``load-address`` property in the ``hw-config`` node of
-   `FW_CONFIG for FVP`_.
--  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
-   and enable the GICv3 device in the model. Note that without this option,
-   the Foundation FVP defaults to legacy (Versatile Express) memory map which
-   is not supported by TF-A.
--  In order for TF-A to run correctly on the Foundation FVP, the architecture
-   versions must match. The Foundation FVP defaults to the highest v8.x
-   version it supports but the default build for TF-A is for v8.0. To avoid
-   issues either start the Foundation FVP to use v8.0 architecture using the
-   ``--arm-v8.0`` option, or build TF-A with an appropriate value for
-   ``ARM_ARCH_MINOR``.
-
-Running on the AEMv8 Base FVP with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_RevC-2xAEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires
-   a specific DTS for all the CPUs to be loaded.
-
-Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.CONFIG64=0                                 \
-    -C cluster0.cpu1.CONFIG64=0                                 \
-    -C cluster0.cpu2.CONFIG64=0                                 \
-    -C cluster0.cpu3.CONFIG64=0                                 \
-    -C cluster1.cpu0.CONFIG64=0                                 \
-    -C cluster1.cpu1.CONFIG64=0                                 \
-    -C cluster1.cpu2.CONFIG64=0                                 \
-    -C cluster1.cpu3.CONFIG64=0                                 \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A32x4                             \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-
-Running on the AEMv8 Base FVP with reset to BL31 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_RevC-2xAEMv8A                             \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cluster0.NUM_CORES=4                                      \
-    -C cluster1.NUM_CORES=4                                      \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.RVBAR=0x04010000                            \
-    -C cluster0.cpu1.RVBAR=0x04010000                            \
-    -C cluster0.cpu2.RVBAR=0x04010000                            \
-    -C cluster0.cpu3.RVBAR=0x04010000                            \
-    -C cluster1.cpu0.RVBAR=0x04010000                            \
-    -C cluster1.cpu1.RVBAR=0x04010000                            \
-    -C cluster1.cpu2.RVBAR=0x04010000                            \
-    -C cluster1.cpu3.RVBAR=0x04010000                            \
-    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Notes:
-
--  Position Independent Executable (PIE) support is enabled in this
-   config allowing BL31 to be loaded at any valid address for execution.
-
--  Since a FIP is not loaded when using BL31 as reset entrypoint, the
-   ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
-   parameter is needed to load the individual bootloader images in memory.
-   BL32 image is only needed if BL31 has been built to expect a Secure-EL1
-   Payload. For the same reason, the FDT needs to be compiled from the DT source
-   and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
-   parameter.
-
--  The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
-   specific DTS for all the CPUs to be loaded.
-
--  The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
-   X and Y are the cluster and CPU numbers respectively, is used to set the
-   reset vector for each core.
-
--  Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
-   changing the value of
-   ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
-   ``BL32_BASE``.
-
-
-Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cluster0.NUM_CORES=4                                      \
-    -C cluster1.NUM_CORES=4                                      \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.CONFIG64=0                                  \
-    -C cluster0.cpu1.CONFIG64=0                                  \
-    -C cluster0.cpu2.CONFIG64=0                                  \
-    -C cluster0.cpu3.CONFIG64=0                                  \
-    -C cluster1.cpu0.CONFIG64=0                                  \
-    -C cluster1.cpu1.CONFIG64=0                                  \
-    -C cluster1.cpu2.CONFIG64=0                                  \
-    -C cluster1.cpu3.CONFIG64=0                                  \
-    -C cluster0.cpu0.RVBAR=0x04002000                            \
-    -C cluster0.cpu1.RVBAR=0x04002000                            \
-    -C cluster0.cpu2.RVBAR=0x04002000                            \
-    -C cluster0.cpu3.RVBAR=0x04002000                            \
-    -C cluster1.cpu0.RVBAR=0x04002000                            \
-    -C cluster1.cpu1.RVBAR=0x04002000                            \
-    -C cluster1.cpu2.RVBAR=0x04002000                            \
-    -C cluster1.cpu3.RVBAR=0x04002000                            \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-.. note::
-   Position Independent Executable (PIE) support is enabled in this
-   config allowing SP_MIN to be loaded at any valid address for execution.
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu1.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu2.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu3.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu0.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu1.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu2.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu3.RVBARADDR=0x04010000                        \
-    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A32x4                             \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu1.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu2.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu3.RVBARADDR=0x04002000                       \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000   \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+  fvp-support
+  fvp-build-options
+  fvp-foundation
+  fvp-aemv8-base
+  fvp-cortex-a57-a53
+  fvp-cortex-a32
+  fvp-specific-configs
 
 --------------
 
 *Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
-.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
-.. _Arm's website: `FVP models`_
-.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
-.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
-.. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _model/: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/model
diff --git a/docs/plat/imx8ulp.rst b/docs/plat/imx8ulp.rst
new file mode 100644
index 0000000..b6b13e2
--- /dev/null
+++ b/docs/plat/imx8ulp.rst
@@ -0,0 +1,69 @@
+NXP i.MX 8ULP
+==================
+
+i.MX 8ULP is part of the ULP family with emphasis on extreme low-power techniques
+using the 28 nm fully depleted silicon on insulator process. Like i.MX 7ULP,
+i.MX 8ULP continues to be based on asymmetric architecture.
+
+The i.MX 8ULP family of processors features NXP’s advanced implementation of the
+dual Arm Cortex-A35 cores alongside an Arm Cortex-M33. This combined architecture
+enables the device to run a rich operating system (such as Linux) on the Cortex-A35
+core and an RTOS (such as FreeRTOS) on the Cortex-M33 core. It also includes a Cadence
+Tensilica Fusion DSP for low-power audio and a HiFi4 DSP for advanced audio and machine
+learning applications.
+
+The design enables clean separation between two processing domains, where each has
+separate power, clocking and peripheral islands, but the bus fabric of each domain
+is tightly integrated for efficient communication. The part is streamlined to minimize
+pin count, enabling small packages and simple system integration. This microprocessor
+is intended for applications where efficiency and simple system integration is important.
+`i.MX8ULP Applications Processors`_.
+
+Boot Sequence
+-------------
+
+BootROM --> SPL --> BL31 --> BL33(u-boot) --> Linux kernel
+
+How to build
+------------
+
+Build Procedure
+~~~~~~~~~~~~~~~
+
+-  Prepare AARCH64 toolchain.
+
+- Get the ELE FW image from NXP linux SDK package
+
+-  Build SPL and u-boot firstly, and get binary images: u-boot-spl.bin,
+   u-boot.bin and dtb
+
+-  Build TF-A
+
+   Build bl31:
+
+   .. code:: shell
+
+       CROSS_COMPILE=aarch64-linux-gnu- make PLAT=<Target_SoC> bl31
+
+   Target_SoC should be "imx8ulp" for i.MX8ULP SoC.
+
+Deploy TF-A Images
+~~~~~~~~~~~~~~~~~~
+
+TF-A binary(bl31.bin), u-boot-spl.bin u-boot.bin, ELE FW image are combined
+together to generate a binary file called flash.bin, the imx-mkimage tool is
+used to generate flash.bin, and flash.bin needs to be flashed into SD card
+with certain offset for BOOT ROM.
+
+Reference Documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Details on how to prepare, generate & deploy the boot image be found in following documents:
+
+- i.MX Linux User's Guide
+  `link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
+- i.MX Linux Reference Manual
+  `link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
+
+.. _i.MX8ULP Applications Processors: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8ulp-applications-processor-family:i.MX8ULP
+
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 795fb09..85c97e5 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -7,6 +7,7 @@
    :hidden:
 
    allwinner
+   amd-versal2
    arm/index
    ast2700
    meson-axg
@@ -27,7 +28,9 @@
    warp7
    imx8
    imx8m
+   imx8ulp
    imx9
+   s32g274a
    npcm845x
    nxp/index
    poplar
@@ -60,7 +63,6 @@
 
    - Arm Neoverse N1 System Development Platform (N1SDP)
    - Arm Neoverse Reference Design N1 Edge (RD-N1-Edge) FVP
-   - Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP
    - Arm SGI-575
    - MediaTek MT8173 SoCs
 
@@ -70,21 +72,10 @@
 +----------------+----------------+--------------------+--------------------+
 |    Platform    |     Vendor     | Deprecated version |  Deleted version   |
 +================+================+====================+====================+
-|    sgm775      |      Arm       |        2.5         |       2.7          |
-+----------------+----------------+--------------------+--------------------+
-|    mt6795      |      MTK       |        2.5         |       2.7          |
-+----------------+----------------+--------------------+--------------------+
-|    sgi575      |      Arm       |        2.8         |       TBD          |
-+----------------+----------------+--------------------+--------------------+
-|    rdn1edge    |      Arm       |        2.8         |       TBD          |
-+----------------+----------------+--------------------+--------------------+
-|    tc0         |      Arm       |        2.8         |       2.10         |
-+----------------+----------------+--------------------+--------------------+
-|    tc1         |      Arm       |        2.10        |       TBD          |
-+----------------+----------------+--------------------+--------------------+
-|    rde1edge    |      Arm       |        2.9         |       3.0          |
+| None at this   |                |                    |                    |
+| time.          |                |                    |                    |
 +----------------+----------------+--------------------+--------------------+
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index 01cf176..53f63b5 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -10,6 +10,7 @@
 -  rk3328: Quad-Core Cortex-A53
 -  rk3368: Octa-Core Cortex-A53
 -  rk3399: Hexa-Core Cortex-A53/A72
+-  rk3566/rk3568: Quad-Core Cortex-A55
 
 
 Boot Sequence
diff --git a/docs/plat/s32g274a.rst b/docs/plat/s32g274a.rst
new file mode 100644
index 0000000..3aa858e
--- /dev/null
+++ b/docs/plat/s32g274a.rst
@@ -0,0 +1,99 @@
+NXP S32G274A
+============
+
+S32G2 is an NXP vehicle network processor combining ASIL D safety, hardware
+security, high-performance real-time and application processing and network
+acceleration. S32G2 supports the needs of new vehicle architectures:
+service-oriented gateways, domain controllers, zonal processors, safety
+processors and more. It is equipped with 4 Cortex-A53 cores operating at
+1.0GHz.
+
+The TF-A includes support for one single S32G2-based board called S32G274ARDB2.
+The S32G-VNP-RDB2 is a compact, highly optimized and integrated board
+engineering for vehicle service-oriented gateway (SoG), domain control
+applications, high-performance processing, safety and security applications.
+More details about this board can be found at `s32g274ardb2`_.
+
+Boot Flow
+---------
+
+::
+
+   BootROM -> BL2 (SRAM) -> BL31 (SRAM) -> BL33 (DDR - TODO)
+
+.. warning::
+   This boot flow is a preliminary version that will serve as a foundation for
+   upcoming S32G2 contributions. The execution will hang after the BL31 stage
+   due to U-Boot being deployed in SRAM instead of DDR. This issue will be
+   resolved with the addition of the DDR driver.
+
+Code Locations
+--------------
+
+- Downstream TF-A:
+  `link: <https://github.com/nxp-auto-linux/arm-trusted-firmware>`__
+
+- Downstream U-Boot:
+  `link <https://github.com/nxp-auto-linux/u-boot>`__
+
+- Downstream Linux:
+  `link <https://github.com/nxp-auto-linux/linux>`__
+
+How to build
+------------
+
+The port currently available on the S32G274ARDB2 platform is in its initial
+stage. This means that important drivers like DDR and storage are not yet
+available. Consequently, the boot process depends on BootROM to load all TF-A
+stages in SRAM. To create a bootable image, the script below should be used.
+This script makes use of the ``mkimage`` tool, which is part of the U-Boot drop
+for S32G274A SoCs.
+
+.. code:: bash
+
+        #!/bin/bash -xe
+        TF_A="${TF_A:-`pwd`}"
+        UBOOT="${UBOOT:-${TF_A}/../u-boot}"
+        DEBUG="${DEBUG:-1}"
+
+        FIP_BASE="0x34100000"
+
+        if [ "${DEBUG}" -eq "1" ]; then
+                BUILD="debug"
+        else
+                BUILD="release"
+        fi
+
+        BOOT_IMAGE="build/s32g274ardb2/${BUILD}/BOOT_IMAGE.bin"
+        BL2_BIN="build/s32g274ardb2/${BUILD}/bl2.bin"
+        FIP_BIN="build/s32g274ardb2/${BUILD}/fip.bin"
+
+        # Generate bl2, bl31 and fip image
+        make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
+                BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" clean
+        make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
+                BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" bl2
+        make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
+                BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" fip
+
+        # Extract BL2 entry
+        BL2_START="0x$(poetry run memory -p s32g274ardb2 -b debug -f | \
+                                grep BL2 | awk -F'|' '{print $3}' | xargs)"
+        # BL2 bin file size in bytes
+        BL2_SIZE="$(stat -c "%s" "${BL2_BIN}")"
+
+        # Pack bl2.bin and fip.bin by ensuring that the FIP image will start at FIP_BASE
+        cp -vf "${BL2_BIN}" "${BOOT_IMAGE}"
+        dd if="${FIP_BIN}" of="${BOOT_IMAGE}" seek="$((FIP_BASE - BL2_START))" bs=1
+
+        # Build a bootable image by appending the IVT
+        "${UBOOT}/tools/mkimage" \
+                -a "${BL2_START}" \
+                -e "${BL2_START}" \
+                -T s32ccimage \
+                -n "${UBOOT}/u-boot-s32.cfgout" \
+                -d "${BOOT_IMAGE}" \
+                fip.s32
+
+.. _s32g2: https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32g-vehicle-network-processors/s32g2-processors-for-vehicle-networking:S32G2
+.. _s32g274ardb2: https://www.nxp.com/design/design-center/designs/s32g2-vehicle-networking-reference-design:S32G-VNP-RDB2
diff --git a/docs/plat/st/stm32mp1.rst b/docs/plat/st/stm32mp1.rst
index b6e4b0d..39a43ee 100644
--- a/docs/plat/st/stm32mp1.rst
+++ b/docs/plat/st/stm32mp1.rst
@@ -115,8 +115,9 @@
     make stm32mp15_trusted_defconfig
     make DEVICE_TREE=stm32mp157c-ev1 all
 
-OP-TEE (optional)
-_________________
+OP-TEE (recommended)
+____________________
+OP-TEE is the default BL32 supported for STMicroelectronics platforms.
 
 .. code:: bash
 
@@ -125,9 +126,10 @@
         CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
 
 
-TF-A BL32 (SP_min)
-__________________
+TF-A BL32 (SP_min) (not recommended)
+____________________________________
 If you choose not to use OP-TEE, you can use TF-A SP_min.
+This is not the recommended BL32 to use, and will have very limited support.
 To build TF-A BL32, and its device tree file:
 
 .. code:: bash
@@ -217,4 +219,4 @@
 .. _STM32MP1 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html
 .. _STM32MP1 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP15_microprocessor#Part_number_codification
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst
index 43e131d..5d4ab4e 100644
--- a/docs/plat/st/stm32mp2.rst
+++ b/docs/plat/st/stm32mp2.rst
@@ -4,6 +4,8 @@
 STM32MP2 is a microprocessor designed by STMicroelectronics
 based on Arm Cortex-A35.
 
+More information can be found on `STM32MP2 Series`_ page.
+
 For TF-A common configuration of STM32 MPUs, please check
 :ref:`STM32 MPUs` page.
 
@@ -19,11 +21,13 @@
 
 Each line comes with a security option (cryptography & secure boot) and a Cortex-A frequency option:
 
-- A      Basic + Cortex-A35 @ 1GHz
-- C      Secure Boot + HW Crypto + Cortex-A35 @ 1GHz
+- A      Basic + Cortex-A35 @ 1.2GHz
+- C      Secure Boot + HW Crypto + Cortex-A35 @ 1.2GHz
 - D      Basic + Cortex-A35 @ 1.5GHz
 - F      Secure Boot + HW Crypto + Cortex-A35 @ 1.5GHz
 
+The `STM32MP2 part number codification`_ page gives more information about part numbers.
+
 Memory mapping
 --------------
 
@@ -130,4 +134,7 @@
         BL32_EXTRA1=<optee_directory>/tee-pager_v2.bin
         fip
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+.. _STM32MP2 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html
+.. _STM32MP2 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP25_microprocessor#Part_number_codification
+
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/st/stm32mpus.rst b/docs/plat/st/stm32mpus.rst
index 931dd57..7b47112 100644
--- a/docs/plat/st/stm32mpus.rst
+++ b/docs/plat/st/stm32mpus.rst
@@ -45,6 +45,8 @@
 - ``STM32MP_UART_PROGRAMMER``
 - ``STM32MP_USB_PROGRAMMER``
 
+Only one storage or serial device should be selected in the build command line,
+to save space and not overflow SYSRAM size, or else the platform won't build or boot.
 
 Other configuration flags:
 
@@ -52,8 +54,6 @@
   | Default: stm32mp157c-ev1.dtb
 - | ``DWL_BUFFER_BASE``: the 'serial boot' load address of FIP,
   | default location (end of the first 128MB) is used when absent
-- | ``STM32MP_EARLY_CONSOLE``: to enable early traces before clock driver is setup.
-  | Default: 0 (disabled)
 - | ``STM32MP_RECONFIGURE_CONSOLE``: to re-configure crash console (especially after BL2).
   | Default: 0 (disabled)
 - | ``STM32MP_UART_BAUDRATE``: to select UART baud rate.
@@ -75,4 +75,4 @@
 
 --------------
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 3f31d40..e9dd772 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -53,3 +53,46 @@
     -   `5`   : SGI 5
     -   `6`   : SGI 6 (Default)
     -   `7`   : SGI 7
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+-----------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+------------------------------+------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------------------------------------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index aa094f7..072329a 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -76,3 +76,46 @@
 data structure is passed in the ```PMC_GLOBAL_GLOB_GEN_STORAGE4``` register.
 The register is free to be used by other software once the TF-A is bringing up
 further firmware images.
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+----------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 4fe0d2f..c8ba27f 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -166,3 +166,55 @@
 - TF-A build command:
   make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1
   bl31 CUSTOM_PKG_PATH=<...>
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+------------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+| SMC Function Identifier   |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
+
+CUSTOM SIP service support
+--------------------------
+
++-------------+------------+------------+
+| Service     | 32-bit     | 64-bit     |
++-------------+------------+------------+
+| SiP Service | 0x82002000 | 0xC2002000 |
++-------------+------------+------------+
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 7c66d11..5643ea1 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -256,10 +256,10 @@
 
    Defines the maximum address in secure RAM that the BL31 image can occupy.
 
--  **#define : PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE**
+-  **#define : PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE**
 
-   Defines the maximum message size between AP and RSS. Need to define if
-   platform supports RSS.
+   Defines the maximum message size between AP and RSE. Need to define if
+   platform supports RSE.
 
 For every image, the platform must define individual identifiers that will be
 used by BL1 or BL2 to load the corresponding image into memory from non-volatile
@@ -1518,6 +1518,40 @@
 - The function must not clobber x1, x2 and x3. It's also not safe to rely on
   stack. Otherwise obey AAPCS.
 
+Struct: plat_try_images_ops [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This optional structure holds platform hooks for alternative images load.
+It has to be defined in platform code and registered by calling
+plat_setup_try_img_ops() function, passing it the address of the
+plat_try_images_ops struct.
+
+Function : plat_setup_try_img_ops [optional]
+............................................
+
+::
+
+    Argument : const struct plat_try_images_ops *
+    Return   : void
+
+This optional function is called to register platform try images ops, given
+as argument.
+
+Function : plat_try_images_ops.next_instance [optional]
+.......................................................
+
+::
+
+    Argument : unsigned int image_id
+    Return   : int
+
+This optional function tries to load images from alternative places.
+In case PSA FWU is not used, it can be any instance or media. If PSA FWU is
+used, it is mandatory that the backup image is on the same media.
+This is required for MTD devices like NAND.
+The argument is the ID of the image for which we are looking for an alternative
+place. It returns 0 in case of success and a negative errno value otherwise.
+
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
@@ -1607,9 +1641,6 @@
 for performing any remaining platform-specific setup that can occur after the
 MMU and data cache have been enabled.
 
-if support for multiple boot sources is required, it initializes the boot
-sequence used by plat_try_next_boot_source().
-
 In Arm standard platforms, this function initializes the storage abstraction
 layer used to load the next bootloader image.
 
@@ -1712,6 +1743,18 @@
 corresponding to ``image_id``. This function is invoked in BL1, both in cold
 boot and FWU code path, before loading the image.
 
+Function : bl1_plat_calc_bl2_layout() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : const meminfo_t *bl1_mem_layout, meminfo_t *bl2_mem_layout
+    Return   : void
+
+This utility function calculates the memory layout of BL2, representing it in a
+`meminfo_t` structure. The default implementation derives this layout from the
+positioning of BL1’s RW data at the top of the memory layout.
+
 Function : bl1_plat_handle_post_image_load() [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1880,25 +1923,7 @@
 
 This optional function performs any BL2 platform initialization
 required before image loading, that is not done later in
-bl2_platform_setup(). Specifically, if support for multiple
-boot sources is required, it initializes the boot sequence used by
-plat_try_next_boot_source().
-
-Function : plat_try_next_boot_source() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : int
-
-This optional function passes to the next boot source in the redundancy
-sequence.
-
-This function moves the current boot redundancy source to the next
-element in the boot sequence. If there are no more boot sources then it
-must return 0, otherwise it must return 1. The default implementation
-of this always returns 0.
+bl2_platform_setup().
 
 Boot Loader Stage 2 (BL2) at EL3
 --------------------------------
@@ -3274,6 +3299,17 @@
 data on the designated crash console. It should only use general purpose
 registers x0 through x5 to do its work.
 
+Function : plat_setup_early_console [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : void
+
+This API is used to setup the early console, it is required only if the flag
+``EARLY_CONSOLE`` is enabled.
+
 .. _External Abort handling and RAS Support:
 
 External Abort handling and RAS Support
@@ -3560,7 +3596,7 @@
 
 --------------
 
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _PSCI: https://developer.arm.com/documentation/den0022/latest/
 .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index 33b3533..11bec7e 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -4,8 +4,8 @@
 Getting Started
 ===============
 
--  Make sure you have a Github account and you are logged on both
-   `developer.trustedfirmware.org`_ and `review.trustedfirmware.org`_.
+-  Make sure you have a Github account and you are logged on to
+   `review.trustedfirmware.org`_.
 
    Also make sure that you have registered your full name and email address in
    your `review.trustedfirmware.org`_ profile. Otherwise, the Gerrit server
@@ -334,7 +334,6 @@
 
 *Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
-.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
 .. _review.trustedfirmware.org: https://review.trustedfirmware.org
 .. _Git guidelines: http://git-scm.com/book/ch5-2.html
 .. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
diff --git a/docs/resources/diagrams/context_init_coldboot.png b/docs/resources/diagrams/context_init_coldboot.png
new file mode 100644
index 0000000..85606e4
--- /dev/null
+++ b/docs/resources/diagrams/context_init_coldboot.png
Binary files differ
diff --git a/docs/resources/diagrams/context_init_warmboot.png b/docs/resources/diagrams/context_init_warmboot.png
new file mode 100644
index 0000000..19f11e3
--- /dev/null
+++ b/docs/resources/diagrams/context_init_warmboot.png
Binary files differ
diff --git a/docs/resources/diagrams/context_memory_allocation.png b/docs/resources/diagrams/context_memory_allocation.png
new file mode 100644
index 0000000..a2e6a8e
--- /dev/null
+++ b/docs/resources/diagrams/context_memory_allocation.png
Binary files differ
diff --git a/docs/resources/diagrams/cpu_data_config_context_memory.png b/docs/resources/diagrams/cpu_data_config_context_memory.png
new file mode 100644
index 0000000..3e64ddd
--- /dev/null
+++ b/docs/resources/diagrams/cpu_data_config_context_memory.png
Binary files differ
diff --git a/docs/resources/diagrams/percpu-data-struct.png b/docs/resources/diagrams/percpu-data-struct.png
new file mode 100644
index 0000000..d8977d5
--- /dev/null
+++ b/docs/resources/diagrams/percpu-data-struct.png
Binary files differ
diff --git a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml b/docs/resources/diagrams/plantuml/rse_attestation_flow.puml
similarity index 99%
rename from docs/resources/diagrams/plantuml/rss_attestation_flow.puml
rename to docs/resources/diagrams/plantuml/rse_attestation_flow.puml
index aca5c01..9d7d780 100644
--- a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
+++ b/docs/resources/diagrams/plantuml/rse_attestation_flow.puml
@@ -5,7 +5,7 @@
 participant RMM
 participant BL31
 endbox
-box RSS
+box RSE
 participant DelegAttest
 participant InitAttest
 participant MeasuredBoot
diff --git a/docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml
new file mode 100644
index 0000000..97af562
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml
@@ -0,0 +1,79 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box RSE
+participant RSE_BL1_1
+participant RSE_BL1_2
+participant RSE_BL2
+participant RSE_S
+endbox
+box SCP
+participant SCP_BL1
+endbox
+box AP
+participant AP_BL1
+participant AP_BL2
+participant AP_BL31
+endbox
+
+== RSE Boot phase ==
+-> RSE_BL1_1: Reset
+Rnote over RSE_BL1_1: ROM code, XIP
+Rnote over RSE_BL1_2: OTP code, XIP
+Rnote over RSE_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
+activate RSE_BL1_1 #Green
+RSE_BL1_1 -->> RSE_BL1_2: Validate, measure
+Rnote over RSE_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
+RSE_BL1_1 -> RSE_BL1_2: Pass execution
+deactivate RSE_BL1_1
+activate RSE_BL1_2 #Green
+RSE_BL1_2 -->> RSE_BL2: Validate, measure, load
+Rnote over RSE_BL1_2: RSE_BL2 measurement\n\ saved to a shared buffer
+RSE_BL1_2 -> RSE_BL2: Pass execution
+deactivate RSE_BL1_2
+activate RSE_BL2 #Green
+RSE_BL2 -->> RSE_S: Validate, measure, load
+RSE_BL2 -->> SCP_BL1: Validate, measure, load
+Rnote over RSE_BL2: RSE_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
+RSE_BL2 -> SCP_BL1: Release from reset
+activate SCP_BL1 #Green
+Rnote over RSE_BL2, SCP_BL1: MHU init between RSE and SCP
+Rnote over SCP_BL1: Configure memory
+Rnote over RSE_BL2: Waits for SCP
+SCP_BL1 --> RSE_BL2: Done
+RSE_BL2 -->> AP_BL1: Validate, measure, load
+Rnote over RSE_BL2: AP_BL1 measurement\n\ saved to a shared buffer
+RSE_BL2 -> AP_BL1: Release from reset
+activate AP_BL1 #Green
+RSE_BL2 -> RSE_S: Pass execution
+deactivate RSE_BL2
+activate RSE_S #Green
+Rnote over RSE_S: Measurements read from\n\ shared buffer and saved by\n\
+Measured Boot service to\n\ measurement slots.
+
+== RSE Runtime / AP Boot phase ==
+Rnote over RSE_S, AP_BL1: MHU init between RSE and AP
+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
+AP_BL1 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL1 -->> AP_BL2: Validate, measure,load
+AP_BL1 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL1 -> AP_BL2: Pass execution
+deactivate AP_BL1
+activate AP_BL2 #Green
+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL2 -->> AP_BL31: Validate, measure,load
+Rnote over AP_BL2: Measure and load:\n\ BL31
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+Rnote over AP_BL2: Measure and load:\n\ RMM
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL2 -> AP_BL31: Pass execution
+deactivate AP_BL2
+activate AP_BL31 #Green
+== RSE / AP Runtime ==
+@enduml
diff --git a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
deleted file mode 100644
index 1aeb1a9..0000000
--- a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
+++ /dev/null
@@ -1,79 +0,0 @@
-@startuml
-skinparam ParticipantPadding 10
-skinparam BoxPadding 10
-box RSS
-participant RSS_BL1_1
-participant RSS_BL1_2
-participant RSS_BL2
-participant RSS_S
-endbox
-box SCP
-participant SCP_BL1
-endbox
-box AP
-participant AP_BL1
-participant AP_BL2
-participant AP_BL31
-endbox
-
-== RSS Boot phase ==
--> RSS_BL1_1: Reset
-Rnote over RSS_BL1_1: ROM code, XIP
-Rnote over RSS_BL1_2: OTP code, XIP
-Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
-activate RSS_BL1_1 #Green
-RSS_BL1_1 -->> RSS_BL1_2: Validate, measure
-Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
-RSS_BL1_1 -> RSS_BL1_2: Pass execution
-deactivate RSS_BL1_1
-activate RSS_BL1_2 #Green
-RSS_BL1_2 -->> RSS_BL2: Validate, measure, load
-Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer
-RSS_BL1_2 -> RSS_BL2: Pass execution
-deactivate RSS_BL1_2
-activate RSS_BL2 #Green
-RSS_BL2 -->> RSS_S: Validate, measure, load
-RSS_BL2 -->> SCP_BL1: Validate, measure, load
-Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
-RSS_BL2 -> SCP_BL1: Release from reset
-activate SCP_BL1 #Green
-Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP
-Rnote over SCP_BL1: Configure memory
-Rnote over RSS_BL2: Waits for SCP
-SCP_BL1 --> RSS_BL2: Done
-RSS_BL2 -->> AP_BL1: Validate, measure, load
-Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer
-RSS_BL2 -> AP_BL1: Release from reset
-activate AP_BL1 #Green
-RSS_BL2 -> RSS_S: Pass execution
-deactivate RSS_BL2
-activate RSS_S #Green
-Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\n\
-Measured Boot service to\n\ measurement slots.
-
-== RSS Runtime / AP Boot phase ==
-Rnote over RSS_S, AP_BL1: MHU init between RSS and AP
-Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
-AP_BL1 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL1 -->> AP_BL2: Validate, measure,load
-AP_BL1 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL1 -> AP_BL2: Pass execution
-deactivate AP_BL1
-activate AP_BL2 #Green
-Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL2 -->> AP_BL31: Validate, measure,load
-Rnote over AP_BL2: Measure and load:\n\ BL31
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-Rnote over AP_BL2: Measure and load:\n\ RMM
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL2 -> AP_BL31: Pass execution
-deactivate AP_BL2
-activate AP_BL31 #Green
-== RSS / AP Runtime ==
-@enduml
diff --git a/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml b/docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
similarity index 89%
rename from docs/resources/diagrams/plantuml/tfa_rss_dfd.puml
rename to docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
index a7e0ce5..68a80bf 100644
--- a/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml
+++ b/docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
@@ -5,7 +5,7 @@
  '/
 
 /'
-TF-A Data Flow Diagram including RSS
+TF-A Data Flow Diagram including RSE
 '/
 
 @startuml
@@ -54,12 +54,12 @@
             bl31 [label="TF-A Runtime\n(BL31)" fillcolor="#ddffb3"]
         }
 
-        # RSS cluster
-        subgraph cluster_rss{
-            label ="RSS";
+        # RSE cluster
+        subgraph cluster_rse{
+            label ="RSE";
             graph [style=filled color="#000000" fillcolor="#faf9cd"]
 
-            rss [label="Runtime Security\n\ Subsystem\n\ (RSS)" fillcolor="#ddffb3"]
+            rse [label="Runtime Security\n\ Subsystem\n\ (RSE)" fillcolor="#ddffb3"]
         }
     }
 
@@ -70,7 +70,7 @@
     sec -> bl2 [dir="both" lhead=cluster_tfa label="DF4"]
     nsec -> bl1 [dir="both" lhead=cluster_tfa, label="DF5"]
     bl2 ->  tzc [dir="both" ltail=cluster_tfa lhead=cluster_ip label="DF6" minlen=1]
-    bl31 -> rss [dir="both" ltail=cluster_tfa lhead=cluster_rss label="DF7" minlen=1]
+    bl31 -> rse [dir="both" ltail=cluster_tfa lhead=cluster_rse label="DF7" minlen=1]
 
 }
 
diff --git a/docs/resources/diagrams/rss_attestation_flow.svg b/docs/resources/diagrams/rse_attestation_flow.svg
similarity index 99%
rename from docs/resources/diagrams/rss_attestation_flow.svg
rename to docs/resources/diagrams/rse_attestation_flow.svg
index 3728c6f..7257576 100644
--- a/docs/resources/diagrams/rss_attestation_flow.svg
+++ b/docs/resources/diagrams/rse_attestation_flow.svg
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSS</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSE</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
 @startuml

 skinparam ParticipantPadding 10

 skinparam BoxPadding 10

@@ -6,7 +6,7 @@
 participant RMM

 participant BL31

 endbox

-box RSS

+box RSE

 participant DelegAttest

 participant InitAttest

 participant MeasuredBoot

diff --git a/docs/resources/diagrams/rss_measured_boot_flow.svg b/docs/resources/diagrams/rse_measured_boot_flow.svg
similarity index 90%
rename from docs/resources/diagrams/rss_measured_boot_flow.svg
rename to docs/resources/diagrams/rse_measured_boot_flow.svg
index f5bf311..0ccfbc2 100644
--- a/docs/resources/diagrams/rss_measured_boot_flow.svg
+++ b/docs/resources/diagrams/rse_measured_boot_flow.svg
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1826px" preserveAspectRatio="none" style="width:1254px;height:1826px;background:#FFFFFF;" version="1.1" viewBox="0 0 1254 1826" width="1254px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="610.5" x="27" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="318.25" y="18.0669">RSS</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="103" x="659.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="29" x="696.5" y="18.0669">SCP</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="451.5" x="784.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="1000.25" y="18.0669">AP</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="86" x2="86" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="232" x2="232" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="413" x2="413" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="594.5" x2="594.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="710.5" x2="710.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="830.5" x2="830.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1007.5" x2="1007.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1185" x2="1185" y1="56.4297" y2="1785.7969"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="45.1279">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="1804.792">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="45.1279">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="1804.792">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="45.1279">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="1804.792">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="45.1279">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="1804.792">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="45.1279">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="1804.792">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="45.1279">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="1804.792">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="45.1279">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="1804.792">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="45.1279">AP_BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="1804.792">AP_BL31</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="136" x="555.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="117" x="561.5" y="92.4966">RSS Boot phase</text><polygon fill="#181818" points="69.5,126.6953,79.5,130.6953,69.5,134.6953,73.5,130.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="0" x2="75.5" y1="130.6953" y2="130.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="36" x="7" y="125.6294">Reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="99" x="37" y="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="91" x="41" y="159.7622">ROM code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="95" x="185" y="176.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="87" x="189" y="192.895">OTP code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="861" x="368" y="209.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="281" x="658" y="226.0278">Stored in flash, loaded and executed in RAM</text><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="255.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="263.2266"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="91.5" x2="231.5" y1="259.2266" y2="259.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="117" x="98.5" y="254.1606">Validate, measure</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="5" y="272.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="288.2935">BL1_2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="9" y="303.4263">saved to a shared buffer</text><polygon fill="#181818" points="215.5,332.625,225.5,336.625,215.5,340.625,219.5,336.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="86.5" x2="221.5" y1="336.625" y2="336.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="93.5" y="331.5591">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="361.7578"/><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="369.7578"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="237.5" x2="412.5" y1="365.7578" y2="365.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="244.5" y="360.6919">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="150" y="378.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="154" y="394.8247">RSS_BL2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="154" y="409.9575">saved to a shared buffer</text><polygon fill="#181818" points="396.5,439.1563,406.5,443.1563,396.5,447.1563,400.5,443.1563" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="232.5" x2="402.5" y1="443.1563" y2="443.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="239.5" y="438.0903">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="468.2891"/><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="476.2891"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="593.5" y1="472.2891" y2="472.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="467.2231">Validate, measure, load</text><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="497.4219"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="505.4219"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="710" y1="501.4219" y2="501.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="496.356">Validate, measure, load</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="148" x="339" y="514.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="131" x="343" y="530.4888">RSS_S and SCP_BL1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="140" x="343" y="545.6216">measurements saved</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="343" y="560.7544">to a shared buffer</text><polygon fill="#181818" points="694,589.9531,704,593.9531,694,597.9531,698,593.9531" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="700" y1="593.9531" y2="593.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="588.8872">Release from reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="387" x="368" y="606.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="200" x="461.75" y="623.02">MHU init between RSS and SCP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="127" x="647" y="640.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="119" x="651" y="656.1528">Configure memory</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="93" x="367" y="673.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="85" x="371" y="689.2856">Waits for SCP</text><polygon fill="#181818" points="429.5,718.4844,419.5,722.4844,429.5,726.4844,425.5,722.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="423.5" x2="705" y1="722.4844" y2="722.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="34" x="435.5" y="717.4185">Done</text><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="747.6172"/><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="755.6172"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="830" y1="751.6172" y2="751.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="746.5513">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="331" y="764.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="143" x="335" y="780.6841">AP_BL1 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="335" y="795.8169">saved to a shared buffer</text><polygon fill="#181818" points="814,825.0156,824,829.0156,814,833.0156,818,829.0156" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="820" y1="829.0156" y2="829.0156"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="823.9497">Release from reset</text><polygon fill="#181818" points="577.5,854.1484,587.5,858.1484,577.5,862.1484,581.5,858.1484" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="413.5" x2="583.5" y1="858.1484" y2="858.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="420.5" y="853.0825">Pass execution</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="182" x="503" y="871.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="887.2153">Measurements read from</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="174" x="507" y="902.3481">shared buffer and saved by</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="917.481">Measured Boot service to</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="129" x="507" y="932.6138">measurement slots.</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="965.2461" y2="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="968.2461" y2="968.2461"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="237" x="505" y="954.6797"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="218" x="511" y="970.7466">RSS Runtime / AP Boot phase</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="313" x="556" y="992.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="191" x="617" y="1008.8794">MHU init between RSS and AP</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="126" x="768" y="1025.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="772" y="1042.0122">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="74" x="772" y="1057.145">FW_CONFIG</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="97" x="772" y="1072.2778">TB_FW_CONFIG</text><polygon fill="#181818" points="610.5,1101.4766,600.5,1105.4766,610.5,1109.4766,606.5,1105.4766" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1105.4766" y2="1105.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1100.4106">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1118.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1134.5435">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1149.6763">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1178.875"/><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1186.875"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="836" x2="1007" y1="1182.875" y2="1182.875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="843" y="1177.8091">Validate, measure,load</text><polygon fill="#181818" points="610.5,1208.0078,600.5,1212.0078,610.5,1216.0078,606.5,1212.0078" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1212.0078" y2="1212.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1206.9419">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1225.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1241.0747">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1256.2075">store measurement</text><polygon fill="#181818" points="991,1285.4063,1001,1289.4063,991,1293.4063,995,1289.4063" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="831" x2="997" y1="1289.4063" y2="1289.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="838" y="1284.3403">Pass execution</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1302.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1318.4731">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="949" y="1333.606">HW_CONFIG</text><polygon fill="#181818" points="610.5,1362.8047,600.5,1366.8047,610.5,1370.8047,606.5,1366.8047" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1366.8047" y2="1366.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1361.7388">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1379.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1395.8716">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1411.0044">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1440.2031"/><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1448.2031"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="1013" x2="1184" y1="1444.2031" y2="1444.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="1020" y="1439.1372">Validate, measure,load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1457.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1473.27">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="32" x="949" y="1488.4028">BL31</text><polygon fill="#181818" points="610.5,1517.6016,600.5,1521.6016,610.5,1525.6016,606.5,1521.6016" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1521.6016" y2="1521.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1516.5356">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1534.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1550.6685">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1565.8013">store measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1582.8672"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1598.9341">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="30" x="949" y="1614.0669">RMM</text><polygon fill="#181818" points="610.5,1643.2656,600.5,1647.2656,610.5,1651.2656,606.5,1647.2656" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1647.2656" y2="1647.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1642.1997">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1660.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1676.3325">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1691.4653">store measurement</text><polygon fill="#181818" points="1168,1720.6641,1178,1724.6641,1168,1728.6641,1172,1724.6641" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1008" x2="1174" y1="1724.6641" y2="1724.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="1015" y="1719.5981">Pass execution</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1753.2305" y2="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1756.2305" y2="1756.2305"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="148" x="549.5" y="1742.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="129" x="555.5" y="1758.731">RSS / AP Runtime</text><!--MD5=[e3f0ee259d2a4aa9c2a97ff856de0312]
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1826px" preserveAspectRatio="none" style="width:1254px;height:1826px;background:#FFFFFF;" version="1.1" viewBox="0 0 1254 1826" width="1254px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="610.5" x="27" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="318.25" y="18.0669">RSE</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="103" x="659.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="29" x="696.5" y="18.0669">SCP</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="451.5" x="784.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="1000.25" y="18.0669">AP</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="86" x2="86" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="232" x2="232" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="413" x2="413" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="594.5" x2="594.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="710.5" x2="710.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="830.5" x2="830.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1007.5" x2="1007.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1185" x2="1185" y1="56.4297" y2="1785.7969"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="45.1279">RSE_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="1804.792">RSE_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="45.1279">RSE_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="1804.792">RSE_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="45.1279">RSE_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="1804.792">RSE_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="45.1279">RSE_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="1804.792">RSE_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="45.1279">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="1804.792">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="45.1279">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="1804.792">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="45.1279">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="1804.792">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="45.1279">AP_BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="1804.792">AP_BL31</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="136" x="555.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="117" x="561.5" y="92.4966">RSE Boot phase</text><polygon fill="#181818" points="69.5,126.6953,79.5,130.6953,69.5,134.6953,73.5,130.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="0" x2="75.5" y1="130.6953" y2="130.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="36" x="7" y="125.6294">Reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="99" x="37" y="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="91" x="41" y="159.7622">ROM code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="95" x="185" y="176.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="87" x="189" y="192.895">OTP code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="861" x="368" y="209.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="281" x="658" y="226.0278">Stored in flash, loaded and executed in RAM</text><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="255.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="263.2266"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="91.5" x2="231.5" y1="259.2266" y2="259.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="117" x="98.5" y="254.1606">Validate, measure</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="5" y="272.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="288.2935">BL1_2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="9" y="303.4263">saved to a shared buffer</text><polygon fill="#181818" points="215.5,332.625,225.5,336.625,215.5,340.625,219.5,336.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="86.5" x2="221.5" y1="336.625" y2="336.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="93.5" y="331.5591">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="361.7578"/><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="369.7578"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="237.5" x2="412.5" y1="365.7578" y2="365.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="244.5" y="360.6919">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="150" y="378.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="154" y="394.8247">RSE_BL2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="154" y="409.9575">saved to a shared buffer</text><polygon fill="#181818" points="396.5,439.1563,406.5,443.1563,396.5,447.1563,400.5,443.1563" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="232.5" x2="402.5" y1="443.1563" y2="443.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="239.5" y="438.0903">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="468.2891"/><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="476.2891"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="593.5" y1="472.2891" y2="472.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="467.2231">Validate, measure, load</text><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="497.4219"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="505.4219"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="710" y1="501.4219" y2="501.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="496.356">Validate, measure, load</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="148" x="339" y="514.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="131" x="343" y="530.4888">RSE_S and SCP_BL1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="140" x="343" y="545.6216">measurements saved</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="343" y="560.7544">to a shared buffer</text><polygon fill="#181818" points="694,589.9531,704,593.9531,694,597.9531,698,593.9531" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="700" y1="593.9531" y2="593.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="588.8872">Release from reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="387" x="368" y="606.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="200" x="461.75" y="623.02">MHU init between RSE and SCP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="127" x="647" y="640.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="119" x="651" y="656.1528">Configure memory</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="93" x="367" y="673.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="85" x="371" y="689.2856">Waits for SCP</text><polygon fill="#181818" points="429.5,718.4844,419.5,722.4844,429.5,726.4844,425.5,722.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="423.5" x2="705" y1="722.4844" y2="722.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="34" x="435.5" y="717.4185">Done</text><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="747.6172"/><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="755.6172"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="830" y1="751.6172" y2="751.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="746.5513">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="331" y="764.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="143" x="335" y="780.6841">AP_BL1 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="335" y="795.8169">saved to a shared buffer</text><polygon fill="#181818" points="814,825.0156,824,829.0156,814,833.0156,818,829.0156" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="820" y1="829.0156" y2="829.0156"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="823.9497">Release from reset</text><polygon fill="#181818" points="577.5,854.1484,587.5,858.1484,577.5,862.1484,581.5,858.1484" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="413.5" x2="583.5" y1="858.1484" y2="858.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="420.5" y="853.0825">Pass execution</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="182" x="503" y="871.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="887.2153">Measurements read from</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="174" x="507" y="902.3481">shared buffer and saved by</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="917.481">Measured Boot service to</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="129" x="507" y="932.6138">measurement slots.</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="965.2461" y2="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="968.2461" y2="968.2461"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="237" x="505" y="954.6797"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="218" x="511" y="970.7466">RSE Runtime / AP Boot phase</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="313" x="556" y="992.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="191" x="617" y="1008.8794">MHU init between RSE and AP</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="126" x="768" y="1025.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="772" y="1042.0122">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="74" x="772" y="1057.145">FW_CONFIG</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="97" x="772" y="1072.2778">TB_FW_CONFIG</text><polygon fill="#181818" points="610.5,1101.4766,600.5,1105.4766,610.5,1109.4766,606.5,1105.4766" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1105.4766" y2="1105.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1100.4106">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1118.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1134.5435">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1149.6763">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1178.875"/><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1186.875"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="836" x2="1007" y1="1182.875" y2="1182.875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="843" y="1177.8091">Validate, measure,load</text><polygon fill="#181818" points="610.5,1208.0078,600.5,1212.0078,610.5,1216.0078,606.5,1212.0078" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1212.0078" y2="1212.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1206.9419">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1225.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1241.0747">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1256.2075">store measurement</text><polygon fill="#181818" points="991,1285.4063,1001,1289.4063,991,1293.4063,995,1289.4063" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="831" x2="997" y1="1289.4063" y2="1289.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="838" y="1284.3403">Pass execution</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1302.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1318.4731">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="949" y="1333.606">HW_CONFIG</text><polygon fill="#181818" points="610.5,1362.8047,600.5,1366.8047,610.5,1370.8047,606.5,1366.8047" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1366.8047" y2="1366.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1361.7388">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1379.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1395.8716">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1411.0044">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1440.2031"/><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1448.2031"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="1013" x2="1184" y1="1444.2031" y2="1444.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="1020" y="1439.1372">Validate, measure,load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1457.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1473.27">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="32" x="949" y="1488.4028">BL31</text><polygon fill="#181818" points="610.5,1517.6016,600.5,1521.6016,610.5,1525.6016,606.5,1521.6016" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1521.6016" y2="1521.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1516.5356">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1534.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1550.6685">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1565.8013">store measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1582.8672"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1598.9341">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="30" x="949" y="1614.0669">RMM</text><polygon fill="#181818" points="610.5,1643.2656,600.5,1647.2656,610.5,1651.2656,606.5,1647.2656" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1647.2656" y2="1647.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1642.1997">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1660.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1676.3325">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1691.4653">store measurement</text><polygon fill="#181818" points="1168,1720.6641,1178,1724.6641,1168,1728.6641,1172,1724.6641" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1008" x2="1174" y1="1724.6641" y2="1724.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="1015" y="1719.5981">Pass execution</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1753.2305" y2="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1756.2305" y2="1756.2305"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="148" x="549.5" y="1742.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="129" x="555.5" y="1758.731">RSE / AP Runtime</text><!--MD5=[e3f0ee259d2a4aa9c2a97ff856de0312]
 @startuml

 skinparam ParticipantPadding 10

 skinparam BoxPadding 10

-box RSS

-participant RSS_BL1_1

-participant RSS_BL1_2

-participant RSS_BL2

-participant RSS_S

+box RSE

+participant RSE_BL1_1

+participant RSE_BL1_2

+participant RSE_BL2

+participant RSE_S

 endbox

 box SCP

 participant SCP_BL1

@@ -17,65 +17,65 @@
 participant AP_BL31

 endbox

 

-== RSS Boot phase ==

--> RSS_BL1_1: Reset

-Rnote over RSS_BL1_1: ROM code, XIP

-Rnote over RSS_BL1_2: OTP code, XIP

-Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM

-activate RSS_BL1_1 #Green

-RSS_BL1_1 - ->> RSS_BL1_2: Validate, measure

-Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer

-RSS_BL1_1 -> RSS_BL1_2: Pass execution

-deactivate RSS_BL1_1

-activate RSS_BL1_2 #Green

-RSS_BL1_2 - ->> RSS_BL2: Validate, measure, load

-Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer

-RSS_BL1_2 -> RSS_BL2: Pass execution

-deactivate RSS_BL1_2

-activate RSS_BL2 #Green

-RSS_BL2 - ->> RSS_S: Validate, measure, load

-RSS_BL2 - ->> SCP_BL1: Validate, measure, load

-Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer

-RSS_BL2 -> SCP_BL1: Release from reset

+== RSE Boot phase ==

+-> RSE_BL1_1: Reset

+Rnote over RSE_BL1_1: ROM code, XIP

+Rnote over RSE_BL1_2: OTP code, XIP

+Rnote over RSE_BL2, AP_BL31: Stored in flash, loaded and executed in RAM

+activate RSE_BL1_1 #Green

+RSE_BL1_1 - ->> RSE_BL1_2: Validate, measure

+Rnote over RSE_BL1_1: BL1_2 measurement\n\ saved to a shared buffer

+RSE_BL1_1 -> RSE_BL1_2: Pass execution

+deactivate RSE_BL1_1

+activate RSE_BL1_2 #Green

+RSE_BL1_2 - ->> RSE_BL2: Validate, measure, load

+Rnote over RSE_BL1_2: RSE_BL2 measurement\n\ saved to a shared buffer

+RSE_BL1_2 -> RSE_BL2: Pass execution

+deactivate RSE_BL1_2

+activate RSE_BL2 #Green

+RSE_BL2 - ->> RSE_S: Validate, measure, load

+RSE_BL2 - ->> SCP_BL1: Validate, measure, load

+Rnote over RSE_BL2: RSE_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer

+RSE_BL2 -> SCP_BL1: Release from reset

 activate SCP_BL1 #Green

-Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP

+Rnote over RSE_BL2, SCP_BL1: MHU init between RSE and SCP

 Rnote over SCP_BL1: Configure memory

-Rnote over RSS_BL2: Waits for SCP

-SCP_BL1 - -> RSS_BL2: Done

-RSS_BL2 - ->> AP_BL1: Validate, measure, load

-Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer

-RSS_BL2 -> AP_BL1: Release from reset

+Rnote over RSE_BL2: Waits for SCP

+SCP_BL1 - -> RSE_BL2: Done

+RSE_BL2 - ->> AP_BL1: Validate, measure, load

+Rnote over RSE_BL2: AP_BL1 measurement\n\ saved to a shared buffer

+RSE_BL2 -> AP_BL1: Release from reset

 activate AP_BL1 #Green

-RSS_BL2 -> RSS_S: Pass execution

-deactivate RSS_BL2

-activate RSS_S #Green

-Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\nMeasured Boot service to\n\ measurement slots.

+RSE_BL2 -> RSE_S: Pass execution

+deactivate RSE_BL2

+activate RSE_S #Green

+Rnote over RSE_S: Measurements read from\n\ shared buffer and saved by\nMeasured Boot service to\n\ measurement slots.

 

-== RSS Runtime / AP Boot phase ==

-Rnote over RSS_S, AP_BL1: MHU init between RSS and AP

+== RSE Runtime / AP Boot phase ==

+Rnote over RSE_S, AP_BL1: MHU init between RSE and AP

 Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG

-AP_BL1 -> RSS_S: Extend measurement

-Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL1 -> RSE_S: Extend measurement

+Rnote over RSE_S: Measured Boot:\n\ store measurement

 AP_BL1 - ->> AP_BL2: Validate, measure,load

-AP_BL1 -> RSS_S: Extend measurement

-Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL1 -> RSE_S: Extend measurement

+Rnote over RSE_S: Measured Boot:\n\ store measurement

 AP_BL1 -> AP_BL2: Pass execution

 deactivate AP_BL1

 activate AP_BL2 #Green

 Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG

-AP_BL2 -> RSS_S: Extend measurement

-Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 -> RSE_S: Extend measurement

+Rnote over RSE_S: Measured Boot:\n\ store measurement

 AP_BL2 - ->> AP_BL31: Validate, measure,load

 Rnote over AP_BL2: Measure and load:\n\ BL31

-AP_BL2 -> RSS_S: Extend measurement

-Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 -> RSE_S: Extend measurement

+Rnote over RSE_S: Measured Boot:\n\ store measurement

 Rnote over AP_BL2: Measure and load:\n\ RMM

-AP_BL2 -> RSS_S: Extend measurement

-Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 -> RSE_S: Extend measurement

+Rnote over RSE_S: Measured Boot:\n\ store measurement

 AP_BL2 -> AP_BL31: Pass execution

 deactivate AP_BL2

 activate AP_BL31 #Green

-== RSS / AP Runtime ==

+== RSE / AP Runtime ==

 @enduml

 
 PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
diff --git a/docs/resources/diagrams/secure_sw_stack_sp.png b/docs/resources/diagrams/secure_sw_stack_sp.png
index 5cb2ca7..dc18cb4 100644
--- a/docs/resources/diagrams/secure_sw_stack_sp.png
+++ b/docs/resources/diagrams/secure_sw_stack_sp.png
Binary files differ
diff --git a/docs/resources/diagrams/secure_sw_stack_tos.png b/docs/resources/diagrams/secure_sw_stack_tos.png
index 1f2d555..2b42019 100644
--- a/docs/resources/diagrams/secure_sw_stack_tos.png
+++ b/docs/resources/diagrams/secure_sw_stack_tos.png
Binary files differ
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index 762801d..014221e 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -87,7 +87,7 @@
 +----------------------+
 | Neoverse-V2          |
 +----------------------+
-| Neoverse-Poseidon    |
+| Neoverse-V3          |
 +----------------------+
 
 For all other cores impacted by Spectre-BHB, some of which that do not implement
diff --git a/docs/threat_model/firmware_threat_model/index.rst b/docs/threat_model/firmware_threat_model/index.rst
index 05b6710..ce1752f 100644
--- a/docs/threat_model/firmware_threat_model/index.rst
+++ b/docs/threat_model/firmware_threat_model/index.rst
@@ -30,7 +30,7 @@
    threat_model
    threat_model_el3_spm
    threat_model_fvp_r
-   threat_model_rss_interface
+   threat_model_rse_interface
    threat_model_arm_cca
    threat_model_fw_update_and_recovery
 
diff --git a/docs/threat_model/firmware_threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
index 63bdc8a..f8e4f7d 100644
--- a/docs/threat_model/firmware_threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -623,6 +623,62 @@
 |                        |   UART interface(s).                                |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 16                                                  |
++========================+=====================================================+
+| Threat                 | | **An attacker could analyse the timing behaviour  |
+|                        |     of implemented methods in the system to infer   |
+|                        |     sensitive information.**                        |
+|                        |                                                     |
+|                        | | A timing side-channel attack is a type of attack  |
+|                        |   that exploits variations in the time it takes a   |
+|                        |   system to perform different operations. This      |
+|                        |   form of attack focuses on analyzing the time-     |
+|                        |   related information leakage that occurs during    |
+|                        |   the execution of cryptographic algorithms or      |
+|                        |   other security-sensitive processes. By observing  |
+|                        |   these timing differences, an attacker can gain    |
+|                        |   insights into the internal workings of a system   |
+|                        |   and potentially extract sensitive information.    |
+|                        |   Sensitive information that, when revealed even    |
+|                        |   partially, could heighten the susceptibility to   |
+|                        |   traditional attacks like brute-force attacks.     |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF2                                                 |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL1, BL2, BL31                                      |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Sensitive Data                                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | AppDebug                                            |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Information Disclosure                              |
++------------------------+------------------+----------------+-----------------+
+| 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            | |  Ensure that the execution time of critical       |
+|                        |    operations is constant and independent of        |
+|                        |    secret data. This prevents attackers from        |
+|                        |    exploiting timing differences to infer           |
+|                        |    information about sensitive data.                |
+|                        |                                                     |
+|                        | |  Introduce random delays/timing jitter or dummy   |
+|                        |    operations to make the timing behavior of program|
+|                        |    execution less predictable. This can disrupt the |
+|                        |    correlation between the execution time and       |
+|                        |    sensitive data.                                  |
+|                        |                                                     |
++------------------------+-----------------------------------------------------+
+| Mitigations            | |  Not implemented                                  |
+| implemented?           |                                                     |
++------------------------+-----------------------------------------------------+
 
 .. _Boot Firmware Threats:
 
diff --git a/docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst b/docs/threat_model/firmware_threat_model/threat_model_rse_interface.rst
similarity index 74%
rename from docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
rename to docs/threat_model/firmware_threat_model/threat_model_rse_interface.rst
index 025d2d9..3b391c1 100644
--- a/docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_rse_interface.rst
@@ -1,41 +1,41 @@
-Threat Model for RSS - AP interface
+Threat Model for RSE - AP interface
 ***********************************
 
 ************
 Introduction
 ************
 This document is an extension for the general TF-A threat-model. It considers
-those platforms where a Runtime Security Subsystem (RSS) is included in the SoC
+those platforms where a Runtime Security Engine (RSE) is included in the SoC
 next to the Application Processor (AP).
 
 ********************
 Target of Evaluation
 ********************
-The scope of this threat model only includes the interface between the RSS and
+The scope of this threat model only includes the interface between the RSE and
 AP. Otherwise, the TF-A :ref:`Generic Threat Model` document is applicable for
-the AP core. The threat model for the RSS firmware will be provided by the RSS
+the AP core. The threat model for the RSE firmware will be provided by the RSE
 firmware project in the future.
 
 
 Data Flow Diagram
 =================
 This diagram is different only from the general TF-A data flow diagram in that
-it includes the RSS and highlights the interface between the AP and the RSS
-cores. The interface description only focuses on the AP-RSS interface the rest
+it includes the RSE and highlights the interface between the AP and the RSE
+cores. The interface description only focuses on the AP-RSE interface the rest
 is the same as in the general TF-A threat-model document.
 
-.. uml:: ../../resources/diagrams/plantuml/tfa_rss_dfd.puml
-  :caption: Figure 1: TF-A Data Flow Diagram including RSS
+.. uml:: ../../resources/diagrams/plantuml/tfa_rse_dfd.puml
+  :caption: Figure 1: TF-A Data Flow Diagram including RSE
 
-.. table:: Table 1: TF-A - RSS data flow diagram
+.. table:: Table 1: TF-A - RSE data flow diagram
 
   +-----------------+--------------------------------------------------------+
   | Diagram Element | Description                                            |
   +=================+========================================================+
-  |       DF7       | | Boot images interact with RSS over a communication   |
+  |       DF7       | | Boot images interact with RSE over a communication   |
   |                 |   channel to record boot measurements and get image    |
   |                 |   verification keys. At runtime, BL31 obtains the      |
-  |                 |   realm world attestation signing key from RSS.        |
+  |                 |   realm world attestation signing key from RSE.        |
   +-----------------+--------------------------------------------------------+
 
 Threat Assessment
@@ -44,12 +44,12 @@
 threat-model document, :ref:`Generic Threat Model`. All the threats listed there
 are applicable for the AP core, here only the differences are highlighted.
 
-    - ID 11: The access to the communication interface between AP and RSS is
+    - ID 11: The access to the communication interface between AP and RSE is
       allowed only for firmware running at EL3. Accidentally exposing this
-      interface to NSCode can allow malicious code to interact with RSS and
+      interface to NSCode can allow malicious code to interact with RSE and
       gain access to sensitive data.
     - ID 13: Relevant in the context of the realm attestation key, which can be
-      retrieved by BL31 through DF7. The RSS communication protocol layer
+      retrieved by BL31 through DF7. The RSE communication protocol layer
       mitigates against this by clearing its internal buffer when reply is
       received. The caller of the API must do the same if data is not needed
       anymore.
diff --git a/docs/threat_model/supply_chain_threat_model.rst b/docs/threat_model/supply_chain_threat_model.rst
index 386a4b0..a0fed5c 100644
--- a/docs/threat_model/supply_chain_threat_model.rst
+++ b/docs/threat_model/supply_chain_threat_model.rst
@@ -115,7 +115,7 @@
 - *EDK2 UEFI*: Normal world bootloader from the EDK2 project [7]_. We use EDK2
   UEFI binaries hosted on tf.org servers for testing [8]_.
 
-Other software components used to test TF-A include U-Boot, Linux kernel, RSS,
+Other software components used to test TF-A include U-Boot, Linux kernel, RSE,
 MCP, and file systems, all sourced from the Arm Reference Platforms teams.
 
 TF-A Toolchain
diff --git a/drivers/arm/css/dsu/dsu.c b/drivers/arm/css/dsu/dsu.c
new file mode 100644
index 0000000..f0e8df1
--- /dev/null
+++ b/drivers/arm/css/dsu/dsu.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2024, Arm Limited. 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 <drivers/arm/css/dsu.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+/*
+ * Context structure that saves the state of DSU PMU registers
+ */
+cluster_pmu_state_t cluster_pmu_context[PLAT_ARM_CLUSTER_COUNT];
+
+/****************************************************************************
+ * This function, save_dsu_pmu_state, is designed to save the
+ * current state of the Performance Monitoring Unit (PMU) for a cluster.
+ *
+ * The function performs the following operations:
+ * 1. Saves the current values of several PMU registers
+ *    (CLUSTERPMCR_EL1, CLUSTERPMCNTENSET_EL1, CLUSTERPMCCNTR_EL1,
+ *    CLUSTERPMOVSSET_EL1, and CLUSTERPMSELR_EL1) into the cluster_pmu_state
+ *    structure.
+ *
+ * 2. Disables the PMU event counting by
+ *    clearing the E bit in the clusterpmcr_el1 register.
+ *
+ * 3. Iterates over the available PMU counters as
+ *    determined by the read_cluster_eventctr_num() function.
+ *    For each counter, it:
+ *    a. Selects the counter by writing its index to CLUSTERPMSELR_EL1.
+ *    b. Reads the current counter value (event count) and
+ *       the event type being counted from CLUSTERPMXEVCNTR_EL1 and
+ *       CLUSTERPMXEVTYPER_EL1 registers, respectively.
+ *
+ * This function is useful for preserving the DynamIQ Shared Unit's (DSU)
+ * PMU registers over a power cycle.
+ ***************************************************************************/
+
+void save_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_state)
+{
+	unsigned int idx = 0U;
+	unsigned int cluster_eventctr_num = read_cluster_eventctr_num();
+
+	assert(cluster_pmu_state != 0);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmcr);
+
+	write_clusterpmcr(cluster_pmu_state->clusterpmcr &
+			~(CLUSTERPMCR_E_BIT));
+
+	save_pmu_reg(cluster_pmu_state, clusterpmcntenset);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmccntr);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmovsset);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmselr);
+
+	for (idx = 0U ; idx < cluster_eventctr_num ; idx++) {
+		write_clusterpmselr(idx);
+		cluster_pmu_state->counter_val[idx] = read_clusterpmxevcntr();
+		cluster_pmu_state->counter_type[idx] = read_clusterpmxevtyper();
+	}
+}
+
+void cluster_off_dsu_pmu_context_save(void)
+{
+	unsigned int cluster_pos;
+
+	cluster_pos = (unsigned int) plat_cluster_id_by_mpidr(read_mpidr_el1());
+
+	save_dsu_pmu_state(&cluster_pmu_context[cluster_pos]);
+}
+
+/*****************************************************************************
+ * This function, restore_dsu_pmu_state, restores the state of the
+ * Performance Monitoring Unit (PMU) from a previously saved state.
+ *
+ * The function performs the following operations:
+ * 1. Restores the CLUSTERPMCR_EL1 register with the
+ *    saved value from the cluster_pmu_state structure.
+ * 2. Iterates over the available PMU counters as determined
+ *    by the read_cluster_eventctr_num() function. For each counter, it:
+ *    a. Selects the counter by writing its index to CLUSTERPMSELR_EL1.
+ *    b. Restores the counter value (event count) and the event type to
+ *       CLUSTERPMXEVCNTR_EL1 and CLUSTERPMXEVTYPER_EL1 registers, respectively
+ * 3. Restores several other PMU registers (CLUSTERPMSELR_EL1,
+ *    CLUSTERPMOVSCLR_EL1, CLUSTERPMOVSSET_EL1, CLUSTERPMCCNTR_EL1,
+ *    and CLUSTERPMCNTENSET_EL1) with their saved values.
+ *
+ *****************************************************************************/
+void restore_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_state)
+{
+	unsigned int idx = 0U;
+	unsigned int cluster_eventctr_num = read_cluster_eventctr_num();
+
+	assert(cluster_pmu_state != 0);
+
+	for (idx = 0U ; idx < cluster_eventctr_num ; idx++) {
+		write_clusterpmselr(idx);
+		write_clusterpmxevcntr(cluster_pmu_state->counter_val[idx]);
+		write_clusterpmxevtyper(cluster_pmu_state->counter_type[idx]);
+	}
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmselr);
+
+	write_clusterpmovsclr(~(uint32_t)cluster_pmu_state->clusterpmovsset);
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmovsset);
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmccntr);
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmcntenset);
+
+	write_clusterpmcr(cluster_pmu_state->clusterpmcr);
+}
+
+void cluster_on_dsu_pmu_context_restore(void)
+{
+	unsigned int cluster_pos;
+
+	cluster_pos = (unsigned int) plat_cluster_id_by_mpidr(read_mpidr_el1());
+
+	restore_dsu_pmu_state(&cluster_pmu_context[cluster_pos]);
+}
+
diff --git a/drivers/arm/css/sds/sds.c b/drivers/arm/css/sds/sds.c
index a5e6389..91f0a27 100644
--- a/drivers/arm/css/sds/sds.c
+++ b/drivers/arm/css/sds/sds.c
@@ -250,7 +250,7 @@
 	uintptr_t sds_mem_base = sds_regions[region_id].base;
 
 	if (!IS_SDS_REGION_VALID(sds_mem_base)) {
-		WARN("SDS: No valid SDS Memory Region found\n");
+		VERBOSE("SDS: No valid SDS Memory Region found\n");
 		return SDS_ERR_FAIL;
 	}
 
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index a4786bb..5e44aa9 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -75,7 +75,7 @@
 		panic();
 	}
 
-	/* Poll till PUP is zero before intiating write */
+	/* Poll till PUP is zero before initiating write */
 	gicd_dchipr_wait_for_power_update_progress(base);
 
 	write_gicd_dchipr(base, read_gicd_dchipr(base) |
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 3190f66..8ea164c 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1321,6 +1321,31 @@
 }
 
 /*******************************************************************************
+ * This function restores the PMR register to old value and also triggers
+ * gicv3_apply_errata_wa_2384374() that flushes the GIC buffer allowing any
+ * pending interrupts to processed. Returns the original PMR.
+ ******************************************************************************/
+unsigned int gicv3_deactivate_priority(unsigned int mask)
+{
+
+	unsigned int old_mask, proc_num;
+	uintptr_t gicr_base;
+
+	old_mask = gicv3_set_pmr(mask);
+
+	proc_num = plat_my_core_pos();
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+	assert(gicr_base != 0UL);
+
+	/* Add DSB to ensure visibility of System register writes */
+	dsb();
+
+	gicv3_apply_errata_wa_2384374(gicr_base);
+
+	return old_mask;
+}
+
+/*******************************************************************************
  * This function delegates the responsibility of discovering the corresponding
  * Redistributor frames to each CPU itself. It is a modified version of
  * gicv3_rdistif_base_addrs_probe() and is executed by each CPU in the platform
diff --git a/drivers/arm/mhu/mhu_v3_x.c b/drivers/arm/mhu/mhu_v3_x.c
new file mode 100644
index 0000000..118c608
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v3_x.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "mhu_v3_x.h"
+
+#include "mhu_v3_x_private.h"
+
+/*
+ * Get the device base from the device struct. Return an error if the dev is
+ * invalid.
+ */
+static enum mhu_v3_x_error_t get_dev_base(const struct mhu_v3_x_dev_t *dev,
+	 union _mhu_v3_x_frame_t **base)
+{
+	if (dev == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Ensure driver has been initialized */
+	if (dev->is_initialized == false) {
+		return MHU_V_3_X_ERR_NOT_INIT;
+	}
+
+	*base = (union _mhu_v3_x_frame_t *)dev->base;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_driver_init(struct mhu_v3_x_dev_t *dev)
+{
+	uint32_t aidr = 0;
+	uint8_t mhu_major_rev;
+	union _mhu_v3_x_frame_t *p_mhu;
+
+	if (dev == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Return if already initialized */
+	if (dev->is_initialized == true) {
+		return MHU_V_3_X_ERR_NONE;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	/* Read revision from MHU hardware */
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		aidr = p_mhu->pbx_frame.pbx_ctrl_page.pbx_aidr;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		aidr = p_mhu->mbx_frame.mbx_ctrl_page.mbx_aidr;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	/* Read the MHU Architecture Major Revision */
+	mhu_major_rev =
+		((aidr & MHU_ARCH_MAJOR_REV_MASK) >> MHU_ARCH_MAJOR_REV_OFF);
+
+	/* Return error if the MHU major revision is not 3 */
+	if (mhu_major_rev != MHU_MAJOR_REV_V3) {
+		/* Unsupported MHU version */
+		return MHU_V_3_X_ERR_UNSUPPORTED_VERSION;
+	}
+
+	/* Read the MHU Architecture Minor Revision */
+	dev->subversion =
+		((aidr & MHU_ARCH_MINOR_REV_MASK) >> MHU_ARCH_MINOR_REV_MASK);
+
+	/* Return error if the MHU minor revision is not 0 */
+	if (dev->subversion != MHU_MINOR_REV_3_0) {
+		/* Unsupported subversion */
+		return MHU_V_3_X_ERR_UNSUPPORTED_VERSION;
+	}
+
+	/* Initialize the Postbox/Mailbox to remain in operational state */
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		p_mhu->pbx_frame.pbx_ctrl_page.pbx_ctrl |= MHU_V3_OP_REQ;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		p_mhu->mbx_frame.mbx_ctrl_page.mbx_ctrl |= MHU_V3_OP_REQ;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	dev->is_initialized = true;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_get_num_channel_implemented(
+	 const struct mhu_v3_x_dev_t *dev,
+	 enum mhu_v3_x_channel_type_t ch_type, uint8_t *num_ch)
+{
+	enum mhu_v3_x_error_t status;
+	union _mhu_v3_x_frame_t *p_mhu;
+
+	if (num_ch == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	/* Read the number of channels implemented in the MHU */
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		*num_ch = (p_mhu->pbx_frame.pbx_ctrl_page.pbx_dbch_cfg0 + 1);
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		*num_ch = (p_mhu->mbx_frame.mbx_ctrl_page.mbx_dbch_cfg0 + 1);
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_clear(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only MBX can clear the Doorbell channel */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Clear the bits in the doorbell channel */
+	mdbcw_reg[channel].mdbcw_clr |= flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_write(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only PBX can set the Doorbell channel value */
+	if (dev->frame != MHU_V3_X_PBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+		&(p_mhu->pbx_frame.pdbcw_page);
+
+	/* Write the value to the doorbell channel */
+	pdbcw_reg[channel].pdbcw_set |= flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_read(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t *flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	enum mhu_v3_x_error_t status;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+
+	if (flags == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+			&(p_mhu->pbx_frame.pdbcw_page);
+
+		/* Read the value from Postbox Doorbell status register */
+		*flags = pdbcw_reg[channel].pdbcw_st;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+			&(p_mhu->mbx_frame.mdbcw_page);
+
+		/* Read the value from Mailbox Doorbell status register */
+		*flags = mdbcw_reg[channel].mdbcw_st;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_set(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Doorbell channel mask is not applicable for PBX */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Set the Doorbell channel mask */
+	mdbcw_reg[channel].mdbcw_msk_set |= flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Doorbell channel mask is not applicable for PBX */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Clear the Doorbell channel mask */
+	mdbcw_reg[channel].mdbcw_msk_clr = flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_get(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t *flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	if (flags == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Doorbell channel mask is not applicable for PBX */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Save the Doorbell channel mask status */
+	*flags = mdbcw_reg[channel].mdbcw_msk_st;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_enable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type)
+{
+	enum mhu_v3_x_error_t status;
+
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+			&(p_mhu->pbx_frame.pdbcw_page);
+
+		/*
+		 * Enable this doorbell channel to generate interrupts for
+		 * transfer acknowledge events.
+		 */
+		pdbcw_reg[channel].pdbcw_int_en = MHU_V3_X_PDBCW_INT_X_TFR_ACK;
+
+		/*
+		 * Enable this doorbell channel to contribute to the PBX
+		 * combined interrupt.
+		 */
+		pdbcw_reg[channel].pdbcw_ctrl = MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+			&(p_mhu->mbx_frame.mdbcw_page);
+
+		/*
+		 * Enable this doorbell channel to contribute to the MBX
+		 * combined interrupt.
+		 */
+		mdbcw_reg[channel].mdbcw_ctrl = MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_disable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type)
+{
+	enum mhu_v3_x_error_t status;
+
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+			&(p_mhu->pbx_frame.pdbcw_page);
+
+		/* Clear channel transfer acknowledge event interrupt */
+		pdbcw_reg[channel].pdbcw_int_clr = MHU_V3_X_PDBCW_INT_X_TFR_ACK;
+
+		/* Disable channel transfer acknowledge event interrupt */
+		pdbcw_reg[channel].pdbcw_int_en &=
+			~(MHU_V3_X_PDBCW_INT_X_TFR_ACK);
+
+		/*
+		 * Disable this doorbell channel from contributing to the PBX
+		 * combined interrupt.
+		 */
+		pdbcw_reg[channel].pdbcw_ctrl &=
+			~(MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN);
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+			&(p_mhu->mbx_frame.mdbcw_page);
+
+		/*
+		 * Disable this doorbell channel from contributing to the MBX
+		 * combined interrupt.
+		 */
+		mdbcw_reg[channel].mdbcw_ctrl &=
+			~(MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN);
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type)
+{
+	enum mhu_v3_x_error_t status;
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	/*
+	 * Only postbox doorbell channel transfer acknowledge interrupt can be
+	 * cleared manually.
+	 *
+	 * To clear MBX interrupt the unmasked status must be cleared using
+	 * mhu_v3_x_doorbell_clear.
+	 */
+	if (dev->frame != MHU_V3_X_PBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+	pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)&(
+			p_mhu->pbx_frame.pdbcw_page);
+
+	/* Clear channel transfer acknowledge event interrupt */
+	pdbcw_reg[channel].pdbcw_int_clr |= 0x1;
+
+	return MHU_V_3_X_ERR_NONE;
+}
diff --git a/drivers/arm/mhu/mhu_v3_x.h b/drivers/arm/mhu/mhu_v3_x.h
new file mode 100644
index 0000000..a3a1950
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v3_x.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_V3_X_H
+#define MHU_V3_X_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/* MHU Architecture Major Revision 3 */
+#define MHU_MAJOR_REV_V3 U(0x2)
+/* MHU Architecture Minor Revision 0 */
+#define MHU_MINOR_REV_3_0 U(0x0)
+
+/* MHU Architecture Major Revision offset */
+#define MHU_ARCH_MAJOR_REV_OFF U(0x4)
+/* MHU Architecture Major Revision mask */
+#define MHU_ARCH_MAJOR_REV_MASK (U(0xf) << MHU_ARCH_MAJOR_REV_OFF)
+
+/* MHU Architecture Minor Revision offset */
+#define MHU_ARCH_MINOR_REV_OFF U(0x0)
+/* MHU Architecture Minor Revision mask */
+#define MHU_ARCH_MINOR_REV_MASK (U(0xf) << MHU_ARCH_MINOR_REV_OFF)
+
+/* MHUv3 PBX/MBX Operational Request offset */
+#define MHU_V3_OP_REQ_OFF U(0)
+/* MHUv3 PBX/MBX Operational Request */
+#define MHU_V3_OP_REQ (U(1) << MHU_V3_OP_REQ_OFF)
+
+/**
+ * MHUv3 error enumeration types
+ */
+enum mhu_v3_x_error_t {
+	/* No error */
+	MHU_V_3_X_ERR_NONE,
+	/* MHU driver not initialized */
+	MHU_V_3_X_ERR_NOT_INIT,
+	/* MHU driver alreary initialized */
+	MHU_V_3_X_ERR_ALREADY_INIT,
+	/* MHU Revision not supported error */
+	MHU_V_3_X_ERR_UNSUPPORTED_VERSION,
+	/* Operation not supported */
+	MHU_V_3_X_ERR_UNSUPPORTED,
+	/* Invalid parameter */
+	MHU_V_3_X_ERR_INVALID_PARAM,
+	/* General MHU driver error */
+	MHU_V_3_X_ERR_GENERAL,
+};
+
+/**
+ * MHUv3 channel types
+ */
+enum mhu_v3_x_channel_type_t {
+	/* Doorbell channel */
+	MHU_V3_X_CHANNEL_TYPE_DBCH,
+	/* Channel type count */
+	MHU_V3_X_CHANNEL_TYPE_COUNT,
+};
+
+/**
+ * MHUv3 frame types
+ */
+enum mhu_v3_x_frame_t {
+	/* MHUv3 postbox frame */
+	MHU_V3_X_PBX_FRAME,
+	/* MHUv3 mailbox frame */
+	MHU_V3_X_MBX_FRAME,
+};
+
+/**
+ * MHUv3 device structure
+ */
+struct mhu_v3_x_dev_t {
+	/* Base address of the MHUv3 frame */
+	uintptr_t base;
+	/* Type of the MHUv3 frame */
+	enum mhu_v3_x_frame_t frame;
+	/* Minor revision of the MHUv3 */
+	uint32_t subversion;
+	/* Flag to indicate if the MHUv3 is initialized */
+	bool is_initialized;
+};
+
+/**
+ * Initializes the MHUv3
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_driver_init(struct mhu_v3_x_dev_t *dev);
+
+/**
+ * Returns the number of channels implemented
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ * num_ch	Pointer to the variable that will store the value
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_get_num_channel_implemented(
+	 const struct mhu_v3_x_dev_t *dev, enum mhu_v3_x_channel_type_t ch_type,
+	 uint8_t *num_ch);
+
+/**
+ * Clear flags from a doorbell channel
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to be cleared from the channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_clear(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags);
+
+/**
+ * Write flags to a doorbell channel
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to be written to the channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_write(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags);
+
+/**
+ * Read value from a doorbell channel
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Pointer to the variable that will store the flags read from the
+ *		channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_read(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t *flags);
+
+/**
+ * Set bits in a doorbell channel mask which is used to disable interrupts for
+ * received flags corresponding to the mask
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to set mask bits in this doorbell channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_set(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t flags);
+
+/**
+ * Clear bits in a doorbell channel mask which is used to disable interrupts
+ * for received flags corresponding to the mask
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to clear mask bits in this doorbell channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel, uint32_t flags);
+
+/**
+ * Get the mask of a doorbell channel which is used to disable interrupts for
+ * received flags corresponding to the mask
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Pointer to the variable that will store the flags read from the
+ *		mask value
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_get(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel, uint32_t *flags);
+
+/**
+ * Enable the channel interrupt
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_enable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type);
+
+/**
+ * Disable the channel interrupt
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_disable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type);
+
+/**
+ * Clear the channel interrupt
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type);
+
+#endif /* MHU_V3_X_H */
diff --git a/drivers/arm/mhu/mhu_v3_x_private.h b/drivers/arm/mhu/mhu_v3_x_private.h
new file mode 100644
index 0000000..9594a2a
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v3_x_private.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_V3_X_PRIVATE_H
+#define MHU_V3_X_PRIVATE_H
+
+#include <stdint.h>
+
+/* Flag for PDBCW Interrupt Transfer Acknowledgment  */
+#define MHU_V3_X_PDBCW_INT_X_TFR_ACK 0x1
+
+/* Flag for PDBCW CTRL Postbox combined interrupts enable */
+#define MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN 0x1
+
+/* Flag for MDBCW CTRL Mailbox combined interrupts enable */
+#define MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN 0x1
+
+/**
+ * Postbox control page structure
+ */
+struct _mhu_v3_x_pbx_ctrl_reg_t {
+	/* Offset: 0x000 (R/ ) Postbox Block Identifier */
+	const volatile uint32_t pbx_blk_id;
+	/* Offset: 0x004 (R/ ) Reserved */
+	const volatile uint8_t reserved_0[0x10 - 0x04];
+	/* Offset: 0x010 (R/ ) Postbox Feature Support 0 */
+	const volatile uint32_t pbx_feat_spt0;
+	/* Offset: 0x014 (R/ ) Postbox Feature Support 1 */
+	const volatile uint32_t pbx_feat_spt1;
+	/* Offset: 0x018 (R/ ) Reserved */
+	const volatile uint8_t reserved_1[0x20 - 0x18];
+	/* Offset: 0x020 (R/ ) Postbox Doorbell Channel Configuration 0 */
+	const volatile uint32_t pbx_dbch_cfg0;
+	/* Offset: 0x024 (R/ ) Reserved */
+	const volatile uint8_t reserved_2[0x30 - 0x24];
+	/* Offset: 0x030 (R/ ) Postbox FIFO Channel Configuration 0 */
+	const volatile uint32_t pbx_ffch_cfg0;
+	/* Offset: 0x034 (R/ ) Reserved */
+	const volatile uint8_t reserved_3[0x40 - 0x34];
+	/* Offset: 0x040 (R/ ) Postbox Fast Channel Configuration 0 */
+	const volatile uint32_t pbx_fch_cfg0;
+	/* Offset: 0x044 (R/ ) Reserved */
+	const volatile uint8_t reserved_4[0x100 - 0x44];
+	/* Offset: 0x100 (R/W) Postbox control */
+	volatile uint32_t pbx_ctrl;
+	/* Offset: 0x164 (R/ ) Reserved */
+	const volatile uint8_t reserved_5[0x400 - 0x104];
+	/*
+	 * Offset: 0x400 (R/ ) Postbox Doorbell Channel Interrupt Status n,
+	 * where n is 0 - 3.
+	 */
+	const volatile uint32_t pbx_dbch_int_st[4];
+	/*
+	 * Offset: 0x410 (R/ ) Postbox FIFO Channel <n> Interrupt Status n,
+	 * where n is 0 - 1.
+	 */
+	const volatile uint32_t pbx_ffch_int_st[2];
+	/* Offset: 0x418 (R/ ) Reserved */
+	const uint8_t reserved_6[0xFC8 - 0x418];
+	/* Offset: 0xFC8 (R/ ) Postbox Implementer Identification Register */
+	const volatile uint32_t pbx_iidr;
+	/* Offset: 0xFCC (R/ ) Postbox Architecture Identification Register */
+	const volatile uint32_t pbx_aidr;
+	/*
+	 * Offset: 0xFD0 (R/ ) Postbox Implementation Defined Identification
+	 * Register n, where n is 0 - 11.
+	 */
+	const volatile uint32_t impl_def_id[12];
+};
+
+/**
+ * Postbox doorbell channel window page structure
+ */
+struct _mhu_v3_x_pdbcw_reg_t {
+	/* Offset: 0x000 (R/ ) Postbox Doorbell Channel Window Status */
+	const volatile uint32_t pdbcw_st;
+	/* Offset: 0x004 (R/ ) Reserved */
+	const uint8_t reserved_0[0xC - 0x4];
+	/* Offset: 0x00C ( /W) Postbox Doorbell Channel Window Set */
+	volatile uint32_t pdbcw_set;
+	/*
+	 * Offset: 0x010 (R/ ) Postbox Doorbell Channel Window Interrupt Status
+	 */
+	const volatile uint32_t pdbcw_int_st;
+	/*
+	 * Offset: 0x014 ( /W) Postbox Doorbell Channel Window Interrupt Clear
+	 */
+	volatile uint32_t pdbcw_int_clr;
+	/*
+	 * Offset: 0x018 (R/W) Postbox Doorbell Channel Window Interrupt Enable
+	 */
+	volatile uint32_t pdbcw_int_en;
+	/* Offset: 0x01C (R/W) Postbox Doorbell Channel Window Control */
+	volatile uint32_t pdbcw_ctrl;
+};
+
+/**
+ * Postbox structure
+ */
+struct _mhu_v3_x_pbx {
+	/* Postbox Control */
+	struct _mhu_v3_x_pbx_ctrl_reg_t pbx_ctrl_page;
+	/* Postbox Doorbell Channel Window */
+	struct _mhu_v3_x_pdbcw_reg_t pdbcw_page;
+};
+
+/**
+ * Mailbox control page structure
+ */
+struct _mhu_v3_x_mbx_ctrl_reg_t {
+	/* Offset: 0x000 (R/ ) Mailbox Block Identifier */
+	const volatile uint32_t mbx_blk_id;
+	/* Offset: 0x004 (R/ ) Reserved */
+	const volatile uint8_t reserved_0[0x10 - 0x04];
+	/* Offset: 0x010 (R/ ) Mailbox Feature Support 0 */
+	const volatile uint32_t mbx_feat_spt0;
+	/* Offset: 0x014 (R/ ) Mailbox Feature Support 1 */
+	const volatile uint32_t mbx_feat_spt1;
+	/* Offset: 0x018 (R/ ) Reserved */
+	const volatile uint8_t reserved_1[0x20 - 0x18];
+	/* Offset: 0x020 (R/ ) Mailbox Doorbell Channel Configuration 0 */
+	const volatile uint32_t mbx_dbch_cfg0;
+	/* Offset: 0x024 (R/ ) Reserved */
+	const volatile uint8_t reserved_2[0x30 - 0x24];
+	/* Offset: 0x030 (R/ ) Mailbox FIFO Channel Configuration 0 */
+	const volatile uint32_t mbx_ffch_cfg0;
+	/* Offset: 0x034 (R/ ) Reserved */
+	const volatile uint8_t reserved_4[0x40 - 0x34];
+	/* Offset: 0x040 (R/ ) Mailbox Fast Channel Configuration 0 */
+	const volatile uint32_t mbx_fch_cfg0;
+	/* Offset: 0x044 (R/ ) Reserved */
+	const volatile uint8_t reserved_5[0x100 - 0x44];
+	/* Offset: 0x100 (R/W) Mailbox control */
+	volatile uint32_t mbx_ctrl;
+	/* Offset: 0x104 (R/ ) Reserved */
+	const volatile uint8_t reserved_6[0x140 - 0x104];
+	/* Offset: 0x140 (R/W) Mailbox Fast Channel control */
+	volatile uint32_t mbx_fch_ctrl;
+	/* Offset: 0x144 (R/W) Mailbox Fast Channel Group Interrupt Enable */
+	volatile uint32_t mbx_fcg_int_en;
+	/* Offset: 0x148 (R/ ) Reserved */
+	const volatile uint8_t reserved_7[0x400 - 0x148];
+	/*
+	 * Offset: 0x400 (R/ ) Mailbox Doorbell Channel Interrupt Status n,
+	 * where n = 0 - 3.
+	 */
+	const volatile uint32_t mbx_dbch_int_st[4];
+	/*
+	 * Offset: 0x410 (R/ ) Mailbox FIFO Channel Interrupt Status n, where
+	 * n = 0 - 1.
+	 */
+	const volatile uint32_t mbx_ffch_int_st[2];
+	/* Offset: 0x418 (R/ ) Reserved */
+	const volatile uint8_t reserved_8[0x470 - 0x418];
+	/* Offset: 0x470 (R/ ) Mailbox Fast Channel Group Interrupt Status */
+	const volatile uint32_t mbx_fcg_int_st;
+	/* Offset: 0x474 (R/ ) Reserved */
+	const volatile uint8_t reserved_9[0x480 - 0x474];
+	/*
+	 * Offset: 0x480 (R/ ) Mailbox Fast Channel Group <n> Interrupt Status,
+	 * where n = 0 - 31.
+	 */
+	const volatile uint32_t mbx_fch_grp_int_st[32];
+	/* Offset: 0x500 (R/ ) Reserved */
+	const volatile uint8_t reserved_10[0xFC8 - 0x500];
+	/* Offset: 0xFC8 (R/ ) Mailbox Implementer Identification Register */
+	const volatile uint32_t mbx_iidr;
+	/* Offset: 0xFCC (R/ ) Mailbox Architecture Identification Register */
+	const volatile uint32_t mbx_aidr;
+	/*
+	 * Offset: 0xFD0 (R/ ) Mailbox Implementation Defined Identification
+	 * Register n, where n is 0 - 11.
+	 */
+	const volatile uint32_t impl_def_id[12];
+};
+
+/**
+ * Mailbox doorbell channel window page structure
+ */
+struct _mhu_v3_x_mdbcw_reg_t {
+	/* Offset: 0x000 (R/ ) Mailbox Doorbell Channel Window Status */
+	const volatile uint32_t mdbcw_st;
+	/* Offset: 0x004 (R/ ) Mailbox Doorbell Channel Window Status Masked */
+	const volatile uint32_t mdbcw_st_msk;
+	/* Offset: 0x008 ( /W) Mailbox Doorbell Channel Window Clear */
+	volatile uint32_t mdbcw_clr;
+	/* Offset: 0x00C (R/ ) Reserved */
+	const volatile uint8_t reserved_0[0x10 - 0x0C];
+	/* Offset: 0x010 (R/ ) Mailbox Doorbell Channel Window Mask Status */
+	const volatile uint32_t mdbcw_msk_st;
+	/* Offset: 0x014 ( /W) Mailbox Doorbell Channel Window Mask Set */
+	volatile uint32_t mdbcw_msk_set;
+	/* Offset: 0x018 ( /W) Mailbox Doorbell Channel Window Mask Clear */
+	volatile uint32_t mdbcw_msk_clr;
+	/* Offset: 0x01C (R/W) Mailbox Doorbell Channel Window Control */
+	volatile uint32_t mdbcw_ctrl;
+};
+
+/**
+ * Mailbox structure
+ */
+struct _mhu_v3_x_mbx {
+	/* Mailbox control */
+	struct _mhu_v3_x_mbx_ctrl_reg_t mbx_ctrl_page;
+	/* Mailbox Doorbell Channel Window */
+	struct _mhu_v3_x_mdbcw_reg_t mdbcw_page;
+};
+
+/**
+ * MHUv3 frame type
+ */
+union _mhu_v3_x_frame_t {
+	/* Postbox Frame */
+	struct _mhu_v3_x_pbx pbx_frame;
+	/* Mailbox Frame */
+	struct _mhu_v3_x_mbx mbx_frame;
+};
+
+#endif /* MHU_V3_X_PRIVATE_H */
diff --git a/drivers/arm/mhu/mhu_wrapper_v3_x.c b/drivers/arm/mhu/mhu_wrapper_v3_x.c
new file mode 100644
index 0000000..3efd701
--- /dev/null
+++ b/drivers/arm/mhu/mhu_wrapper_v3_x.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/mhu.h>
+
+#include "mhu_v3_x.h"
+
+#define MHU_NOTIFY_VALUE	U(1234)
+
+#ifndef ALIGN_UP
+#define ALIGN_UP(num, align)	(((num) + ((align) - 1)) & ~((align) - 1))
+#endif
+
+/*
+ * MHUv3 Wrapper utility macros
+ */
+#define IS_ALIGNED(val, align)	(val == ALIGN_UP(val, align))
+
+/*
+ * MHU devices for host:
+ * HSE: Host to Secure Enclave (sender device)
+ * SEH: Secure Enclave to Host (receiver device)
+ */
+struct mhu_v3_x_dev_t mhu_hse_dev = {0, MHU_V3_X_PBX_FRAME};
+struct mhu_v3_x_dev_t mhu_seh_dev = {0, MHU_V3_X_MBX_FRAME};
+
+/* MHUv3 driver error to MHUv3 wrapper error mapping */
+static enum mhu_error_t error_mapping_to_mhu_error_t(enum mhu_v3_x_error_t err)
+{
+	switch (err) {
+	case MHU_V_3_X_ERR_NONE:
+		return MHU_ERR_NONE;
+
+	case MHU_V_3_X_ERR_NOT_INIT:
+		return MHU_ERR_NOT_INIT;
+
+	case MHU_V_3_X_ERR_UNSUPPORTED_VERSION:
+		return MHU_ERR_UNSUPPORTED_VERSION;
+
+	case MHU_V_3_X_ERR_UNSUPPORTED:
+		return MHU_ERR_UNSUPPORTED;
+
+	case MHU_V_3_X_ERR_INVALID_PARAM:
+		return MHU_ERR_INVALID_ARG;
+
+	default:
+		return MHU_ERR_GENERAL;
+	}
+}
+
+static enum mhu_error_t signal_and_wait_for_clear(
+	void *mhu_sender_dev, uint32_t value)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint8_t num_channels;
+	uint32_t read_val;
+
+	dev = (struct mhu_v3_x_dev_t *)mhu_sender_dev;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Wait for any pending acknowledgment from transmitter side */
+	do {
+		err = mhu_v3_x_doorbell_read(dev, num_channels - 1, &read_val);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	} while ((read_val & value) == value);
+
+	/* Use the last channel to notify that a transfer is ready */
+	err = mhu_v3_x_doorbell_write(dev, num_channels - 1, value);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Wait until receiver side acknowledges the transfer */
+	do {
+		err = mhu_v3_x_doorbell_read(dev, num_channels - 1, &read_val);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	} while ((read_val & value) == value);
+
+	return error_mapping_to_mhu_error_t(MHU_V_3_X_ERR_NONE);
+}
+
+static enum mhu_error_t wait_for_signal(
+	void *mhu_receiver_dev, uint32_t value)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint32_t read_val;
+	uint8_t num_channels;
+
+	dev = (struct mhu_v3_x_dev_t *)mhu_receiver_dev;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	do {
+		err = mhu_v3_x_doorbell_read(dev, num_channels - 1, &read_val);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	} while (read_val != value);
+
+	return error_mapping_to_mhu_error_t(err);
+}
+
+static enum mhu_error_t clear_and_wait_for_signal(
+	void *mhu_receiver_dev, uint32_t value)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint8_t num_channels;
+
+	dev = (struct mhu_v3_x_dev_t *)mhu_receiver_dev;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Clear all channels */
+	for (int i = 0; i < num_channels; i++) {
+		err = mhu_v3_x_doorbell_clear(dev, i, UINT32_MAX);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	}
+
+	return wait_for_signal(mhu_receiver_dev, value);
+}
+
+static enum mhu_error_t validate_buffer_params(uintptr_t buf_addr)
+{
+	if ((buf_addr == 0) || (!IS_ALIGNED(buf_addr, sizeof(uint32_t)))) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	return MHU_ERR_NONE;
+}
+
+enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint8_t num_ch;
+	uint32_t ch;
+
+	assert(mhu_sender_base != (uintptr_t)NULL);
+
+	mhu_hse_dev.base = mhu_sender_base;
+	dev = (struct mhu_v3_x_dev_t *)&mhu_hse_dev;
+
+	/* Initialize MHUv3 */
+	err = mhu_v3_x_driver_init(dev);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Read the number of doorbell channels implemented in the MHU */
+	err = mhu_v3_x_get_num_channel_implemented(
+		dev, MHU_V3_X_CHANNEL_TYPE_DBCH, &num_ch);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	} else if (num_ch < 2) {
+		/* This wrapper requires at least two channels implemented */
+		return MHU_ERR_UNSUPPORTED;
+	}
+
+	/*
+	 * The sender polls the postbox doorbell channel window status register
+	 * to get notified about successful transfer. So, disable the doorbell
+	 * channel's contribution to postbox combined interrupt.
+	 *
+	 * Also, clear and disable the postbox doorbell channel transfer
+	 * acknowledge interrupt.
+	 */
+	for (ch = 0; ch < num_ch; ch++) {
+		err = mhu_v3_x_channel_interrupt_disable(
+			dev, ch, MHU_V3_X_CHANNEL_TYPE_DBCH);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	}
+
+	return MHU_ERR_NONE;
+}
+
+enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint32_t ch;
+	uint8_t num_ch;
+
+	assert(mhu_receiver_base != (uintptr_t)NULL);
+
+	mhu_seh_dev.base = mhu_receiver_base;
+	dev = (struct mhu_v3_x_dev_t *)&mhu_seh_dev;
+
+	/* Initialize MHUv3 */
+	err = mhu_v3_x_driver_init(dev);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Read the number of doorbell channels implemented in the MHU */
+	err = mhu_v3_x_get_num_channel_implemented(
+		dev, MHU_V3_X_CHANNEL_TYPE_DBCH, &num_ch);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	} else if (num_ch < 2) {
+		/* This wrapper requires at least two channels implemented */
+		return MHU_ERR_UNSUPPORTED;
+	}
+
+	/* Mask all channels except the notifying channel */
+	for (ch = 0; ch < (num_ch - 1); ch++) {
+		/* Mask interrupts on channels used for data */
+		err = mhu_v3_x_doorbell_mask_set(dev, ch, UINT32_MAX);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	}
+
+	/* Unmask doorbell notification channel interrupt */
+	err = mhu_v3_x_doorbell_mask_clear(dev, (num_ch - 1), UINT32_MAX);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/*
+	 * Enable the doorbell channel's contribution to mailbox combined
+	 * interrupt.
+	 */
+	err = mhu_v3_x_channel_interrupt_enable(dev, (num_ch - 1),
+			MHU_V3_X_CHANNEL_TYPE_DBCH);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	return MHU_ERR_NONE;
+}
+
+/*
+ * Public function. See mhu.h
+ *
+ * The basic steps of transferring a message:
+ * 1. Send the size of the payload on Channel 0. It is the very first Bytes of
+ *    the transfer. Continue with Channel 1.
+ * 2. Send the payload, writing the channels one after the other (4 Bytes
+ *    each). The last available channel is reserved for controlling the
+ *    transfer. When the last channel is reached or no more data is left, STOP.
+ * 3. Notify the receiver using the last channel and wait for acknowledge. If
+ *    there is still data to transfer, jump to step 2. Otherwise, proceed.
+ *
+ */
+enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size)
+{
+	enum mhu_error_t mhu_err;
+	enum mhu_v3_x_error_t mhu_v3_err;
+	uint8_t num_channels;
+	uint8_t chan;
+	uint32_t *buffer;
+	struct mhu_v3_x_dev_t *dev;
+
+	if (size == 0) {
+		return MHU_ERR_NONE;
+	}
+
+	dev = (struct mhu_v3_x_dev_t *)&mhu_hse_dev;
+	chan = 0;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	mhu_err = validate_buffer_params((uintptr_t)send_buffer);
+	if (mhu_err != MHU_ERR_NONE) {
+		return mhu_err;
+	}
+
+	mhu_v3_err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+
+	/* First send the size of the actual message. */
+	mhu_v3_err = mhu_v3_x_doorbell_write(dev, chan, (uint32_t)size);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+	chan++;
+
+	buffer = (uint32_t *)send_buffer;
+	for (size_t i = 0; i < size; i += 4) {
+		mhu_v3_err = mhu_v3_x_doorbell_write(dev, chan, *buffer++);
+		if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(mhu_v3_err);
+		}
+
+		if (++chan == (num_channels - 1)) {
+			/* Use the last channel to notify transfer complete */
+			mhu_err = signal_and_wait_for_clear(
+				dev, MHU_NOTIFY_VALUE);
+			if (mhu_err != MHU_ERR_NONE) {
+				return mhu_err;
+			}
+			chan = 0;
+		}
+	}
+
+	if (chan != 0) {
+		/* Use the last channel to notify transfer complete */
+		mhu_err = signal_and_wait_for_clear(dev, MHU_NOTIFY_VALUE);
+		if (mhu_err != MHU_ERR_NONE) {
+			return mhu_err;
+		}
+	}
+
+	return MHU_ERR_NONE;
+}
+
+/*
+ * Public function. See mhu.h
+ *
+ * The basic steps of receiving a message:
+ * 1. Read the size of the payload from Channel 0. It is the very first
+ *    4 Bytes of the transfer. Continue with Channel 1.
+ * 2. Receive the payload, read the channels one after the other
+ *    (4 Bytes each). The last available channel is reserved for controlling
+ *    the transfer.
+ *    When the last channel is reached clear all the channels
+ *    (also sending an acknowledge on the last channel).
+ * 3. If there is still data to receive wait for a notification on the last
+ *    channel and jump to step 2 as soon as it arrived. Otherwise, proceed.
+ *
+ */
+enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size)
+{
+	enum mhu_error_t mhu_err;
+	enum mhu_v3_x_error_t mhu_v3_err;
+	uint32_t msg_len;
+	uint8_t num_channels;
+	uint8_t chan;
+	uint32_t *buffer;
+	struct mhu_v3_x_dev_t *dev;
+
+	dev = (struct mhu_v3_x_dev_t *)&mhu_seh_dev;
+	chan = 0;
+
+	mhu_err = validate_buffer_params((uintptr_t)receive_buffer);
+	if (mhu_err != MHU_ERR_NONE) {
+		return mhu_err;
+	}
+
+	mhu_v3_err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+
+	/* Busy wait for incoming reply */
+	mhu_err = wait_for_signal(dev, MHU_NOTIFY_VALUE);
+	if (mhu_err != MHU_ERR_NONE) {
+		return mhu_err;
+	}
+
+	/* The first word is the length of the actual message. */
+	mhu_v3_err = mhu_v3_x_doorbell_read(dev, chan, &msg_len);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+	chan++;
+
+	if (*size < msg_len) {
+		/* Message buffer too small */
+		*size = msg_len;
+		return MHU_ERR_BUFFER_TOO_SMALL;
+	}
+
+	buffer = (uint32_t *)receive_buffer;
+	for (size_t i = 0; i < msg_len; i += 4) {
+		mhu_v3_err = mhu_v3_x_doorbell_read(dev, chan, buffer++);
+		if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(mhu_v3_err);
+		}
+
+		/* Only wait for next transfer if still missing data. */
+		if (++chan == (num_channels - 1) && (msg_len - i) > 4) {
+			/* Busy wait for next transfer */
+			mhu_err = clear_and_wait_for_signal(
+				dev, MHU_NOTIFY_VALUE);
+			if (mhu_err != MHU_ERR_NONE) {
+				return mhu_err;
+			}
+			chan = 0;
+		}
+	}
+
+	/* Clear all channels */
+	for (uint8_t i = U(0); i < num_channels; i++) {
+		mhu_v3_err = mhu_v3_x_doorbell_clear(dev, i, UINT32_MAX);
+		if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(mhu_v3_err);
+		}
+	}
+
+	*size = msg_len;
+
+	return MHU_ERR_NONE;
+}
+
+size_t mhu_get_max_message_size(void)
+{
+	enum mhu_v3_x_error_t err __maybe_unused;
+	uint8_t num_channels;
+
+	err = mhu_v3_x_get_num_channel_implemented(&mhu_seh_dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+
+	assert(err == MHU_V_3_X_ERR_NONE);
+	assert(num_channels != U(0));
+	/*
+	 * Returns only usable size of memory. As one channel is specifically
+	 * used to inform about the size of payload, discard it from available
+	 * memory size.
+	 */
+	return (num_channels - 1) * sizeof(uint32_t);
+}
diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rse/rse_comms.c
similarity index 77%
rename from drivers/arm/rss/rss_comms.c
rename to drivers/arm/rse/rse_comms.c
index 332105f..cfc5a83 100644
--- a/drivers/arm/rss/rss_comms.c
+++ b/drivers/arm/rse/rse_comms.c
@@ -9,16 +9,16 @@
 
 #include <common/debug.h>
 #include <drivers/arm/mhu.h>
-#include <drivers/arm/rss_comms.h>
+#include <drivers/arm/rse_comms.h>
 #include <psa/client.h>
-#include <rss_comms_protocol.h>
+#include <rse_comms_protocol.h>
 
 /* Union as message space and reply space are never used at the same time, and this saves space as
  * we can overlap them.
  */
-union __packed __attribute__((aligned(4))) rss_comms_io_buffer_t {
-	struct serialized_rss_comms_msg_t msg;
-	struct serialized_rss_comms_reply_t reply;
+union __packed __attribute__((aligned(4))) rse_comms_io_buffer_t {
+	struct serialized_rse_comms_msg_t msg;
+	struct serialized_rse_comms_reply_t reply;
 };
 
 static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
@@ -40,13 +40,13 @@
 
 	comms_mhu_msg_size = mhu_get_max_message_size();
 
-	comms_embed_msg_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				   sizeof(struct rss_embed_msg_t) -
-				   PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+	comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) +
+				   sizeof(struct rse_embed_msg_t) -
+				   PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
 
-	comms_embed_reply_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				     sizeof(struct rss_embed_reply_t) -
-				     PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+	comms_embed_reply_min_size = sizeof(struct serialized_rse_comms_header_t) +
+				     sizeof(struct rse_embed_reply_t) -
+				     PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
 
 	/* Use embed if we can pack into one message and reply, else use
 	 * pointer_access. The underlying MHU transport protocol uses a
@@ -63,9 +63,9 @@
 	     comms_mhu_msg_size - sizeof(uint32_t)) ||
 	    (comms_embed_reply_min_size + out_size_total >
 	     comms_mhu_msg_size - sizeof(uint32_t))) {
-		return RSS_COMMS_PROTOCOL_POINTER_ACCESS;
+		return RSE_COMMS_PROTOCOL_POINTER_ACCESS;
 	} else {
-		return RSS_COMMS_PROTOCOL_EMBED;
+		return RSE_COMMS_PROTOCOL_EMBED;
 	}
 }
 
@@ -75,7 +75,7 @@
 	/* Declared statically to avoid using huge amounts of stack space. Maybe revisit if
 	 * functions not being reentrant becomes a problem.
 	 */
-	static union rss_comms_io_buffer_t io_buf;
+	static union rse_comms_io_buffer_t io_buf;
 	enum mhu_error_t err;
 	psa_status_t status;
 	static uint8_t seq_num = 1U;
@@ -94,13 +94,13 @@
 	io_buf.msg.header.client_id = 1U,
 	io_buf.msg.header.protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
 
-	status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
+	status = rse_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
 					    out_len, &io_buf.msg, &msg_size);
 	if (status != PSA_SUCCESS) {
 		return status;
 	}
 
-	VERBOSE("[RSS-COMMS] Sending message\n");
+	VERBOSE("[RSE-COMMS] Sending message\n");
 	VERBOSE("protocol_ver=%u\n", io_buf.msg.header.protocol_ver);
 	VERBOSE("seq_num=%u\n", io_buf.msg.header.seq_num);
 	VERBOSE("client_id=%u\n", io_buf.msg.header.client_id);
@@ -117,7 +117,7 @@
 #if DEBUG
 	/*
 	 * Poisoning the message buffer (with a known pattern).
-	 * Helps in detecting hypothetical RSS communication bugs.
+	 * Helps in detecting hypothetical RSE communication bugs.
 	 */
 	memset(&io_buf.msg, 0xA5, msg_size);
 #endif
@@ -127,12 +127,12 @@
 		return PSA_ERROR_COMMUNICATION_FAILURE;
 	}
 
-	VERBOSE("[RSS-COMMS] Received reply\n");
+	VERBOSE("[RSE-COMMS] Received reply\n");
 	VERBOSE("protocol_ver=%u\n", io_buf.reply.header.protocol_ver);
 	VERBOSE("seq_num=%u\n", io_buf.reply.header.seq_num);
 	VERBOSE("client_id=%u\n", io_buf.reply.header.client_id);
 
-	status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val,
+	status = rse_protocol_deserialize_reply(out_vec, out_len, &return_val,
 						&io_buf.reply, reply_size);
 	if (status != PSA_SUCCESS) {
 		return status;
@@ -152,16 +152,16 @@
 	return return_val;
 }
 
-int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
+int rse_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
 {
 	enum mhu_error_t err;
 
 	err = mhu_init_sender(mhu_sender_base);
 	if (err != MHU_ERR_NONE) {
 		if (err == MHU_ERR_ALREADY_INIT) {
-			INFO("[RSS-COMMS] Host to RSS MHU driver already initialized\n");
+			INFO("[RSE-COMMS] Host to RSE MHU driver already initialized\n");
 		} else {
-			ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err);
+			ERROR("[RSE-COMMS] Host to RSE MHU driver initialization failed: %d\n", err);
 			return -1;
 		}
 	}
@@ -169,9 +169,9 @@
 	err = mhu_init_receiver(mhu_receiver_base);
 	if (err != MHU_ERR_NONE) {
 		if (err == MHU_ERR_ALREADY_INIT) {
-			INFO("[RSS-COMMS] RSS to Host MHU driver already initialized\n");
+			INFO("[RSE-COMMS] RSE to Host MHU driver already initialized\n");
 		} else {
-			ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err);
+			ERROR("[RSE-COMMS] RSE to Host MHU driver initialization failed: %d\n", err);
 			return -1;
 		}
 	}
diff --git a/drivers/arm/rse/rse_comms.mk b/drivers/arm/rse/rse_comms.mk
new file mode 100644
index 0000000..3b87fe2
--- /dev/null
+++ b/drivers/arm/rse/rse_comms.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+$(warning "RSE driver is an experimental feature")
+
+RSE_COMMS_SOURCES	:=	$(addprefix drivers/arm/rse/,			\
+					rse_comms.c				\
+					rse_comms_protocol.c			\
+					rse_comms_protocol_embed.c		\
+					rse_comms_protocol_pointer_access.c	\
+				)
+
+# Default to MHUv2 if PLAT_MHU_VERSION undefined
+PLAT_MHU_VERSION ?= 2
+
+ifeq (${PLAT_MHU_VERSION}, 3)
+RSE_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
+					mhu_v3_x.c				\
+					mhu_wrapper_v3_x.c			\
+				)
+else ifeq (${PLAT_MHU_VERSION}, 2)
+RSE_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
+					mhu_v2_x.c				\
+					mhu_wrapper_v2_x.c			\
+				)
+else
+$(error Unsupported MHU version)
+endif
+
+PLAT_INCLUDES		+=	-Idrivers/arm/rse		\
+				-Idrivers/arm/mhu		\
+				-Iinclude/lib/psa
diff --git a/drivers/arm/rss/rss_comms_protocol.c b/drivers/arm/rse/rse_comms_protocol.c
similarity index 62%
rename from drivers/arm/rss/rss_comms_protocol.c
rename to drivers/arm/rse/rse_comms_protocol.c
index a1b1b58..3eb7eaa 100644
--- a/drivers/arm/rss/rss_comms_protocol.c
+++ b/drivers/arm/rse/rse_comms_protocol.c
@@ -7,15 +7,15 @@
 #include <assert.h>
 
 #include <common/debug.h>
-#include "rss_comms_protocol.h"
+#include "rse_comms_protocol.h"
 
-psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_serialize_msg(psa_handle_t handle,
 					int16_t type,
 					const psa_invec *in_vec,
 					uint8_t in_len,
 					const psa_outvec *out_vec,
 					uint8_t out_len,
-					struct serialized_rss_comms_msg_t *msg,
+					struct serialized_rse_comms_msg_t *msg,
 					size_t *msg_len)
 {
 	psa_status_t status;
@@ -25,15 +25,15 @@
 	assert(in_vec != NULL);
 
 	switch (msg->header.protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		status = rss_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
+	case RSE_COMMS_PROTOCOL_EMBED:
+		status = rse_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
 							  out_len, &msg->msg.embed, msg_len);
 		if (status != PSA_SUCCESS) {
 			return status;
 		}
 		break;
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
-		status = rss_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
+		status = rse_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
 								   out_vec, out_len,
 								   &msg->msg.pointer_access,
 								   msg_len);
@@ -45,26 +45,26 @@
 		return PSA_ERROR_NOT_SUPPORTED;
 	}
 
-	*msg_len += sizeof(struct serialized_rss_comms_header_t);
+	*msg_len += sizeof(struct serialized_rse_comms_header_t);
 
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_deserialize_reply(psa_outvec *out_vec,
 					    uint8_t out_len,
 					    psa_status_t *return_val,
-					    const struct serialized_rss_comms_reply_t *reply,
+					    const struct serialized_rse_comms_reply_t *reply,
 					    size_t reply_size)
 {
 	assert(reply != NULL);
 	assert(return_val != NULL);
 
 	switch (reply->header.protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		return rss_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
+	case RSE_COMMS_PROTOCOL_EMBED:
+		return rse_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
 							    &reply->reply.embed, reply_size);
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
-		return rss_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
+		return rse_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
 								     &reply->reply.pointer_access,
 								     reply_size);
 	default:
diff --git a/drivers/arm/rse/rse_comms_protocol.h b/drivers/arm/rse/rse_comms_protocol.h
new file mode 100644
index 0000000..24f3965
--- /dev/null
+++ b/drivers/arm/rse/rse_comms_protocol.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_H__
+#define __RSE_COMMS_PROTOCOL_H__
+
+#include <cdefs.h>
+#include <stdint.h>
+
+#include <psa/client.h>
+#include "rse_comms_protocol_embed.h"
+#include "rse_comms_protocol_pointer_access.h"
+
+enum rse_comms_protocol_version_t {
+	RSE_COMMS_PROTOCOL_EMBED = 0,
+	RSE_COMMS_PROTOCOL_POINTER_ACCESS = 1,
+};
+
+struct __packed serialized_rse_comms_header_t {
+	uint8_t protocol_ver;
+	uint8_t seq_num;
+	uint16_t client_id;
+};
+
+/* MHU message passed from Host to RSE to deliver a PSA client call */
+struct __packed serialized_rse_comms_msg_t {
+	struct serialized_rse_comms_header_t header;
+	union __packed {
+		struct rse_embed_msg_t embed;
+		struct rse_pointer_access_msg_t pointer_access;
+	} msg;
+};
+
+/* MHU reply message to hold the PSA client reply result returned by RSE */
+struct __packed serialized_rse_comms_reply_t {
+	struct serialized_rse_comms_header_t header;
+	union __packed {
+		struct rse_embed_reply_t embed;
+		struct rse_pointer_access_reply_t pointer_access;
+	} reply;
+};
+
+/* in_len and out_len are uint8_ts, therefore if there are more than 255 iovecs
+ * an error may occur.
+ */
+CASSERT(PSA_MAX_IOVEC <= UINT8_MAX, assert_rse_comms_max_iovec_too_large);
+
+psa_status_t rse_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const psa_invec *in_vec,
+					uint8_t in_len,
+					const psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rse_comms_msg_t *msg,
+					size_t *msg_len);
+
+psa_status_t rse_protocol_deserialize_reply(psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rse_comms_reply_t *reply,
+					    size_t reply_size);
+
+#endif /* __RSE_COMMS_PROTOCOL_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_common.h b/drivers/arm/rse/rse_comms_protocol_common.h
similarity index 89%
rename from drivers/arm/rss/rss_comms_protocol_common.h
rename to drivers/arm/rse/rse_comms_protocol_common.h
index 177d636..235ea92 100644
--- a/drivers/arm/rss/rss_comms_protocol_common.h
+++ b/drivers/arm/rse/rse_comms_protocol_common.h
@@ -17,8 +17,8 @@
  * Res: Reserved.
  */
 
-#ifndef RSS_COMMS_PROTOCOL_COMMON
-#define RSS_COMMS_PROTOCOL_COMMON
+#ifndef RSE_COMMS_PROTOCOL_COMMON
+#define RSE_COMMS_PROTOCOL_COMMON
 
 #define TYPE_OFFSET	(0U)
 #define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
@@ -32,4 +32,4 @@
 	 ((((uint32_t)(in_len)) << IN_LEN_OFFSET) & IN_LEN_MASK) | \
 	 ((((uint32_t)(out_len)) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
 
-#endif /* RSS_COMMS_PROTOCOL_COMMON */
+#endif /* RSE_COMMS_PROTOCOL_COMMON */
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.c b/drivers/arm/rse/rse_comms_protocol_embed.c
similarity index 85%
rename from drivers/arm/rss/rss_comms_protocol_embed.c
rename to drivers/arm/rse/rse_comms_protocol_embed.c
index 05628cc..d425257 100644
--- a/drivers/arm/rss/rss_comms_protocol_embed.c
+++ b/drivers/arm/rse/rse_comms_protocol_embed.c
@@ -9,16 +9,16 @@
 #include <string.h>
 
 #include <common/debug.h>
-#include "rss_comms_protocol_common.h"
-#include "rss_comms_protocol_embed.h"
+#include "rse_comms_protocol_common.h"
+#include "rse_comms_protocol_embed.h"
 
-psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_embed_serialize_msg(psa_handle_t handle,
 					      int16_t type,
 					      const psa_invec *in_vec,
 					      uint8_t in_len,
 					      const psa_outvec *out_vec,
 					      uint8_t out_len,
-					      struct rss_embed_msg_t *msg,
+					      struct rse_embed_msg_t *msg,
 					      size_t *msg_len)
 {
 	uint32_t payload_size = 0;
@@ -55,10 +55,10 @@
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_embed_deserialize_reply(psa_outvec *out_vec,
 						  uint8_t out_len,
 						  psa_status_t *return_val,
-						  const struct rss_embed_reply_t *reply,
+						  const struct rse_embed_reply_t *reply,
 						  size_t reply_size)
 {
 	uint32_t payload_offset = 0;
diff --git a/drivers/arm/rse/rse_comms_protocol_embed.h b/drivers/arm/rse/rse_comms_protocol_embed.h
new file mode 100644
index 0000000..165978d
--- /dev/null
+++ b/drivers/arm/rse/rse_comms_protocol_embed.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_EMBED_H__
+#define __RSE_COMMS_PROTOCOL_EMBED_H__
+
+#include <cdefs.h>
+
+#include <psa/client.h>
+
+#include <platform_def.h>
+
+
+
+struct __packed rse_embed_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param; /* type, in_len, out_len */
+	uint16_t io_size[PSA_MAX_IOVEC];
+	uint8_t trailer[PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+struct __packed rse_embed_reply_t {
+	int32_t return_val;
+	uint16_t out_size[PSA_MAX_IOVEC];
+	uint8_t trailer[PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+psa_status_t rse_protocol_embed_serialize_msg(psa_handle_t handle,
+					      int16_t type,
+					      const psa_invec *in_vec,
+					      uint8_t in_len,
+					      const psa_outvec *out_vec,
+					      uint8_t out_len,
+					      struct rse_embed_msg_t *msg,
+					      size_t *msg_len);
+
+psa_status_t rse_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+						  uint8_t out_len,
+						  psa_status_t *return_val,
+						  const struct rse_embed_reply_t *reply,
+						  size_t reply_size);
+
+#endif /* __RSE_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.c b/drivers/arm/rse/rse_comms_protocol_pointer_access.c
similarity index 78%
rename from drivers/arm/rss/rss_comms_protocol_pointer_access.c
rename to drivers/arm/rse/rse_comms_protocol_pointer_access.c
index 3a10a98..63524eb 100644
--- a/drivers/arm/rss/rss_comms_protocol_pointer_access.c
+++ b/drivers/arm/rse/rse_comms_protocol_pointer_access.c
@@ -6,16 +6,16 @@
  */
 #include <assert.h>
 
-#include "rss_comms_protocol_common.h"
-#include "rss_comms_protocol_pointer_access.h"
+#include "rse_comms_protocol_common.h"
+#include "rse_comms_protocol_pointer_access.h"
 
-psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_pointer_access_serialize_msg(psa_handle_t handle,
 						       int16_t type,
 						       const psa_invec *in_vec,
 						       uint8_t in_len,
 						       const psa_outvec *out_vec,
 						       uint8_t out_len,
-						       struct rss_pointer_access_msg_t *msg,
+						       struct rse_pointer_access_msg_t *msg,
 						       size_t *msg_len)
 {
 	unsigned int i;
@@ -42,10 +42,10 @@
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
 							   uint8_t out_len,
 							   psa_status_t *return_val,
-							   const struct rss_pointer_access_reply_t *reply,
+							   const struct rse_pointer_access_reply_t *reply,
 							   size_t reply_size)
 {
 	unsigned int i;
diff --git a/drivers/arm/rse/rse_comms_protocol_pointer_access.h b/drivers/arm/rse/rse_comms_protocol_pointer_access.h
new file mode 100644
index 0000000..e5935f3
--- /dev/null
+++ b/drivers/arm/rse/rse_comms_protocol_pointer_access.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__
+#define __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__
+
+#include <cdefs.h>
+
+#include <psa/client.h>
+
+struct __packed rse_pointer_access_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param;
+	uint32_t io_sizes[PSA_MAX_IOVEC];
+	uint64_t host_ptrs[PSA_MAX_IOVEC];
+};
+
+struct __packed rse_pointer_access_reply_t {
+	int32_t return_val;
+	uint32_t out_sizes[PSA_MAX_IOVEC];
+};
+
+psa_status_t rse_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+						       int16_t type,
+						       const psa_invec *in_vec,
+						       uint8_t in_len,
+						       const psa_outvec *out_vec,
+						       uint8_t out_len,
+						       struct rse_pointer_access_msg_t *msg,
+						       size_t *msg_len);
+
+psa_status_t rse_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+							   uint8_t out_len,
+							   psa_status_t *return_val,
+							   const struct rse_pointer_access_reply_t *reply,
+							   size_t reply_size);
+
+#endif /* __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/drivers/arm/rss/rss_comms.mk b/drivers/arm/rss/rss_comms.mk
deleted file mode 100644
index c1c994b..0000000
--- a/drivers/arm/rss/rss_comms.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2022, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning "RSS driver is an experimental feature")
-
-RSS_COMMS_SOURCES	:=	$(addprefix drivers/arm/rss/,			\
-					rss_comms.c				\
-					rss_comms_protocol.c			\
-					rss_comms_protocol_embed.c		\
-					rss_comms_protocol_pointer_access.c	\
-				)
-
-RSS_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
-					mhu_v2_x.c				\
-					mhu_wrapper_v2_x.c			\
-				)
-
-PLAT_INCLUDES		+=	-Idrivers/arm/rss		\
-				-Idrivers/arm/mhu
diff --git a/drivers/arm/rss/rss_comms_protocol.h b/drivers/arm/rss/rss_comms_protocol.h
deleted file mode 100644
index 9a38057..0000000
--- a/drivers/arm/rss/rss_comms_protocol.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_H__
-#define __RSS_COMMS_PROTOCOL_H__
-
-#include <cdefs.h>
-#include <stdint.h>
-
-#include <psa/client.h>
-#include "rss_comms_protocol_embed.h"
-#include "rss_comms_protocol_pointer_access.h"
-
-enum rss_comms_protocol_version_t {
-	RSS_COMMS_PROTOCOL_EMBED = 0,
-	RSS_COMMS_PROTOCOL_POINTER_ACCESS = 1,
-};
-
-struct __packed serialized_rss_comms_header_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-};
-
-/* MHU message passed from Host to RSS to deliver a PSA client call */
-struct __packed serialized_rss_comms_msg_t {
-	struct serialized_rss_comms_header_t header;
-	union __packed {
-		struct rss_embed_msg_t embed;
-		struct rss_pointer_access_msg_t pointer_access;
-	} msg;
-};
-
-/* MHU reply message to hold the PSA client reply result returned by RSS */
-struct __packed serialized_rss_comms_reply_t {
-	struct serialized_rss_comms_header_t header;
-	union __packed {
-		struct rss_embed_reply_t embed;
-		struct rss_pointer_access_reply_t pointer_access;
-	} reply;
-};
-
-/* in_len and out_len are uint8_ts, therefore if there are more than 255 iovecs
- * an error may occur.
- */
-CASSERT(PSA_MAX_IOVEC <= UINT8_MAX, assert_rss_comms_max_iovec_too_large);
-
-psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
-					int16_t type,
-					const psa_invec *in_vec,
-					uint8_t in_len,
-					const psa_outvec *out_vec,
-					uint8_t out_len,
-					struct serialized_rss_comms_msg_t *msg,
-					size_t *msg_len);
-
-psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
-					    uint8_t out_len,
-					    psa_status_t *return_val,
-					    const struct serialized_rss_comms_reply_t *reply,
-					    size_t reply_size);
-
-#endif /* __RSS_COMMS_PROTOCOL_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.h b/drivers/arm/rss/rss_comms_protocol_embed.h
deleted file mode 100644
index c81c795..0000000
--- a/drivers/arm/rss/rss_comms_protocol_embed.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_EMBED_H__
-#define __RSS_COMMS_PROTOCOL_EMBED_H__
-
-#include <cdefs.h>
-
-#include <psa/client.h>
-
-#include <platform_def.h>
-
-
-
-struct __packed rss_embed_msg_t {
-	psa_handle_t handle;
-	uint32_t ctrl_param; /* type, in_len, out_len */
-	uint16_t io_size[PSA_MAX_IOVEC];
-	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
-};
-
-struct __packed rss_embed_reply_t {
-	int32_t return_val;
-	uint16_t out_size[PSA_MAX_IOVEC];
-	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
-};
-
-psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
-					      int16_t type,
-					      const psa_invec *in_vec,
-					      uint8_t in_len,
-					      const psa_outvec *out_vec,
-					      uint8_t out_len,
-					      struct rss_embed_msg_t *msg,
-					      size_t *msg_len);
-
-psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
-						  uint8_t out_len,
-						  psa_status_t *return_val,
-						  const struct rss_embed_reply_t *reply,
-						  size_t reply_size);
-
-#endif /* __RSS_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.h b/drivers/arm/rss/rss_comms_protocol_pointer_access.h
deleted file mode 100644
index a4d054b..0000000
--- a/drivers/arm/rss/rss_comms_protocol_pointer_access.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
-#define __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
-
-#include <cdefs.h>
-
-#include <psa/client.h>
-
-struct __packed rss_pointer_access_msg_t {
-	psa_handle_t handle;
-	uint32_t ctrl_param;
-	uint32_t io_sizes[PSA_MAX_IOVEC];
-	uint64_t host_ptrs[PSA_MAX_IOVEC];
-};
-
-struct __packed rss_pointer_access_reply_t {
-	int32_t return_val;
-	uint32_t out_sizes[PSA_MAX_IOVEC];
-};
-
-psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
-						       int16_t type,
-						       const psa_invec *in_vec,
-						       uint8_t in_len,
-						       const psa_outvec *out_vec,
-						       uint8_t out_len,
-						       struct rss_pointer_access_msg_t *msg,
-						       size_t *msg_len);
-
-psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
-							   uint8_t out_len,
-							   psa_status_t *return_val,
-							   const struct rss_pointer_access_reply_t *reply,
-							   size_t reply_size);
-
-#endif /* __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 6c6f978..ef04c4d 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,20 +69,35 @@
 	return smmuv3_poll(smmu_base + SMMU_S_GBPA, SMMU_S_GBPA_UPDATE, 0U);
 }
 
-/*
- * Initialize the SMMU by invalidating all secure caches and TLBs.
- * Abort all incoming transactions in order to implement a default
- * deny policy on reset
- */
+/* Initialize the SMMU by invalidating all secure caches and TLBs. */
 int __init smmuv3_init(uintptr_t smmu_base)
 {
-	/* Abort all incoming transactions */
-	if (smmuv3_security_init(smmu_base) != 0)
+	/*
+	 * Initiate invalidation of secure caches and TLBs if the SMMU
+	 * supports secure state. If not, it's implementation defined
+	 * as to how SMMU_S_INIT register is accessed.
+	 * As per Arm SMMUv3 specification the SMMU_S_INIT register in a SMMU
+	 * with RME implementation has following properties:
+	 * a) all SMMU registers that are specified to be accessible only in
+	 *    the Secure physical address space are additionally accessible in
+	 *    Root physical address space.
+	 * b) as GPT information is permitted to be cached in a TLB, the
+	 *    SMMU_S_INIT.INV_ALL operation also invalidates all GPT information
+	 *    cached in TLBs.
+	 * Additionally, it is Root firmware’s responsibility to write to
+	 * INV_ALL before enabling SMMU_ROOT_CR0.{ACCESSEN,GPCEN}.
+	 */
+	mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
+
+	/* Wait for global invalidation operation to finish */
+	if (smmuv3_poll(smmu_base + SMMU_S_INIT,
+			SMMU_S_INIT_INV_ALL, 0U) != 0) {
 		return -1;
+	}
 
 #if ENABLE_RME
 
-	if (get_armv9_2_feat_rme_support() != 0U) {
+	if (is_feat_rme_present()) {
 		if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) &
 				  SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) {
 			WARN("Skip SMMU GPC configuration.\n");
@@ -137,23 +152,7 @@
 
 #endif /* ENABLE_RME */
 
-	/*
-	 * Initiate invalidation of secure caches and TLBs if the SMMU
-	 * supports secure state. If not, it's implementation defined
-	 * as to how SMMU_S_INIT register is accessed.
-	 * Arm SMMU Arch RME supplement, section 3.4: all SMMU registers
-	 * specified to be accessible only in secure physical address space are
-	 * additionally accessible in root physical address space in an SMMU
-	 * with RME.
-	 * Section 3.3: as GPT information is permitted to be cached in a TLB,
-	 * the SMMU_S_INIT.INV_ALL mechanism also invalidates GPT information
-	 * cached in TLBs.
-	 */
-	mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
-
-	/* Wait for global invalidation operation to finish */
-	return smmuv3_poll(smmu_base + SMMU_S_INIT,
-				SMMU_S_INIT_INV_ALL, 0U);
+	return 0;
 }
 
 int smmuv3_ns_set_abort_all(uintptr_t smmu_base)
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 608866c..8c5ff9d 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -328,7 +328,6 @@
 	unsigned int data_len, len, i;
 	unsigned int plat_nv_ctr;
 	int rc;
-	bool is_trial_run = false;
 
 	/* Get the counter value from current image. The AM expects the IPM
 	 * to return the counter value as a DER encoded integer */
@@ -388,9 +387,14 @@
 		return 1;
 	} else if (*cert_nv_ctr > plat_nv_ctr) {
 #if PSA_FWU_SUPPORT && IMAGE_BL2
-		is_trial_run = fwu_is_trial_run_state();
+		if (fwu_get_active_bank_state() == FWU_BANK_STATE_ACCEPTED) {
+			*need_nv_ctr_upgrade = true;
+		} else {
+			*need_nv_ctr_upgrade = false;
+		}
+#else
+		*need_nv_ctr_upgrade = true;
 #endif /* PSA_FWU_SUPPORT && IMAGE_BL2 */
-		*need_nv_ctr_upgrade = !is_trial_run;
 	}
 
 	return 0;
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index a2c6430..55ab935 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,16 +19,15 @@
 MBEDTLS_MINOR=$(shell grep -hP "define MBEDTLS_VERSION_MINOR" ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
 $(info MBEDTLS_VERSION_MAJOR is [${MBEDTLS_MAJOR}] MBEDTLS_VERSION_MINOR is [${MBEDTLS_MINOR}])
 
+ifneq (${MBEDTLS_MAJOR}, 3)
+  $(error Error: TF-A only supports MbedTLS versions > 3.x)
+endif
+
 # Specify mbed TLS configuration file
-ifeq (${MBEDTLS_MAJOR}, 2)
-        $(info Deprecation Notice: Please migrate to Mbedtls version 3.x (refer to TF-A documentation for the exact version number))
-	MBEDTLS_CONFIG_FILE             ?=	"<drivers/auth/mbedtls/mbedtls_config-2.h>"
-else ifeq (${MBEDTLS_MAJOR}, 3)
-	ifeq (${PSA_CRYPTO},1)
-		MBEDTLS_CONFIG_FILE     ?=      "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
-	else
-		MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-3.h>"
-	endif
+ifeq (${PSA_CRYPTO},1)
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
+else
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/mbedtls_config-3.h>"
 endif
 
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
@@ -47,9 +46,11 @@
 					platform.c 			\
 					platform_util.c			\
 					bignum.c			\
+					bignum_core.c			\
 					gcm.c 				\
 					md.c				\
 					pk.c 				\
+					pk_ecc.c 			\
 					pk_wrap.c 			\
 					pkparse.c 			\
 					pkwrite.c 			\
@@ -59,38 +60,21 @@
 					ecp_curves.c			\
 					ecp.c				\
 					rsa.c				\
+					rsa_alt_helpers.c		\
 					x509.c 				\
 					x509_crt.c 			\
 					)
 
-ifeq (${MBEDTLS_MAJOR}, 2)
-	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
-						rsa_internal.c		\
-						)
-else ifeq (${MBEDTLS_MAJOR}, 3)
-	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
-						bignum_core.c		\
-						rsa_alt_helpers.c	\
-						hash_info.c		\
-						)
-
-	# Currently on Mbedtls-3 there is outstanding bug due to usage
-	# of redundant declaration[1], So disable redundant-decls
-	# compilation flag to avoid compilation error when compiling with
-	# Mbedtls-3.
-	# [1]: https://github.com/Mbed-TLS/mbedtls/issues/6910
-	LIBMBEDTLS_CFLAGS += -Wno-error=redundant-decls
-endif
-
 ifeq (${PSA_CRYPTO},1)
+LIBMBEDTLS_CFLAGS 	+= -Wno-error=unused-but-set-variable
 LIBMBEDTLS_SRCS         += $(addprefix ${MBEDTLS_DIR}/library/,    	\
 					psa_crypto.c                   	\
 					psa_crypto_client.c            	\
-					psa_crypto_driver_wrappers.c   	\
 					psa_crypto_hash.c              	\
 					psa_crypto_rsa.c               	\
 					psa_crypto_ecp.c               	\
 					psa_crypto_slot_management.c   	\
+					psa_util.c			\
 					)
 endif
 
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 230cec9..9bfcaac 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,6 +65,18 @@
 
 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+
+
+/*
+ * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
+ * advised that it's better to copy out the declaration than it would be to
+ * update to 3.5.2, where this function is exposed.
+ */
+int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
+			     const mbedtls_x509_buf *sig_params,
+			     mbedtls_md_type_t *md_alg,
+			     mbedtls_pk_type_t *pk_alg,
+			     void **sig_opts);
 /*
  * Verify a signature.
  *
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index 5891acf..2da97dc 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <mbedtls/memory_buffer_alloc.h>
 #include <mbedtls/oid.h>
 #include <mbedtls/platform.h>
+#include <mbedtls/psa_util.h>
 #include <mbedtls/version.h>
 #include <mbedtls/x509.h>
 #include <psa/crypto.h>
@@ -49,16 +50,6 @@
 	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	*/
 
-static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(
-						mbedtls_md_type_t md_type)
-{
-	assert((md_type == MBEDTLS_MD_SHA256) ||
-	       (md_type == MBEDTLS_MD_SHA384) ||
-	       (md_type == MBEDTLS_MD_SHA512));
-
-	return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) (md_type + 0x5);
-}
-
 /*
  * AlgorithmIdentifier  ::=  SEQUENCE  {
  *     algorithm               OBJECT IDENTIFIER,
@@ -292,6 +283,62 @@
 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
 	**/
 
+/*
+ * This is a helper function that adjusts the start of the pk_start to point to
+ * the subjectPublicKey bytes within the SubjectPublicKeyInfo block.
+ *
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
+ *       algorithm            AlgorithmIdentifier,
+ *       subjectPublicKey     BIT STRING }
+ *
+ * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
+ * otherwise success(0).
+ **/
+static int pk_bytes_from_subpubkey(unsigned char **pk_start,
+				   unsigned int *pk_len)
+{
+	mbedtls_asn1_buf alg_oid, alg_params;
+	int rc;
+	unsigned char *pk_end;
+	size_t len;
+	unsigned char *pk_ptr = *pk_start;
+
+	pk_end = pk_ptr + *pk_len;
+	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
+				  MBEDTLS_ASN1_CONSTRUCTED |
+				  MBEDTLS_ASN1_SEQUENCE);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	pk_end = pk_ptr + len;
+	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+	pk_end = pk_ptr + len - (alg_oid.len + alg_params.len +
+		 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG));
+	rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	*pk_start = pk_ptr;
+	*pk_len = len;
+
+	return rc;
+}
+
+/*
+ * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
+ * advised that it's better to copy out the declaration than it would be to
+ * update to 3.5.2, where this function is exposed.
+ */
+int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
+			     const mbedtls_x509_buf *sig_params,
+			     mbedtls_md_type_t *md_alg,
+			     mbedtls_pk_type_t *pk_alg,
+			     void **sig_opts);
 /*
  * Verify a signature.
  *
@@ -388,6 +435,22 @@
 	psa_set_key_type(&psa_key_attr, psa_key_type);
 	psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
 
+	/*
+	 * Note: In the implementation of the psa_import_key function in
+	 * version 3.6.0, the function expects the starting pointer of the
+	 * subject public key instead of the starting point of
+	 * SubjectPublicKeyInfo.
+	 * This is only needed while dealing with RSASSA_PSS (RSA Signature
+	 * scheme with Appendix based on Probabilistic Signature Scheme)
+	 * algorithm.
+	 */
+	if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
+		rc = pk_bytes_from_subpubkey((unsigned char **) &pk_ptr, &pk_len);
+		if (rc != 0) {
+			goto end2;
+		}
+	}
+
 	/* Get the key_id using import API */
 	status = psa_import_key(&psa_key_attr,
 				pk_ptr,
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c
index 21942b4..8bab6e8 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -173,7 +173,6 @@
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
 	[BL2_IMAGE_ID]				=	&bl2_image,
-	[HW_CONFIG_ID]				=	&hw_config,
 	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
 	[FW_CONFIG_ID]				=	&fw_config,
 	[FWU_CERT_ID]				=	&fwu_cert,
diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
index ce2aa7e..8dccaec 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl2.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,6 +84,22 @@
 		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
 #endif /* SPD_spmd */
 
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
+
 /*
  * Trusted key certificate
  */
diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c
index 8c37248..619b241 100644
--- a/drivers/auth/tbbr/tbbr_cot_common.c
+++ b/drivers/auth/tbbr/tbbr_cot_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,7 +52,7 @@
 	AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
 auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
 
 /* trusted_boot_fw_cert */
@@ -109,19 +109,3 @@
 		}
 	}
 };
-
-/* HW Config */
-const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &hw_config_hash
-			}
-		}
-	}
-};
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 4cbc0f7..3e87efc 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -34,6 +34,20 @@
 	return ops->get_rate(id);
 }
 
+int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate)
+{
+	unsigned long lrate;
+
+	assert((ops != NULL) && (ops->set_rate != NULL));
+
+	if (orate != NULL) {
+		return ops->set_rate(id, rate, orate);
+	}
+
+	/* In case the caller is not interested in the output rate */
+	return ops->set_rate(id, rate, &lrate);
+}
+
 int clk_get_parent(unsigned long id)
 {
 	assert((ops != NULL) && (ops->get_parent != NULL));
@@ -41,6 +55,13 @@
 	return ops->get_parent(id);
 }
 
+int clk_set_parent(unsigned long id, unsigned long parent_id)
+{
+	assert((ops != NULL) && (ops->set_parent != NULL));
+
+	return ops->set_parent(id, parent_id);
+}
+
 bool clk_is_enabled(unsigned long id)
 {
 	assert((ops != NULL) && (ops->is_enabled != NULL));
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
index ff432be..b6f06e0 100644
--- a/drivers/fwu/fwu.c
+++ b/drivers/fwu/fwu.c
@@ -24,6 +24,17 @@
 CASSERT((offsetof(struct fwu_metadata, crc_32) == 0),
 	crc_32_must_be_first_member_of_structure);
 
+/*
+ * Ensure that the NR_OF_FW_BANKS selected by the platform is not
+ * zero and not greater than the maximum number of banks allowed
+ * by the specification.
+ */
+CASSERT((NR_OF_FW_BANKS > 0) && (NR_OF_FW_BANKS <= NR_OF_MAX_FW_BANKS),
+	assert_fwu_num_banks_invalid_value);
+
+#define FWU_METADATA_VERSION		2U
+#define FWU_FW_STORE_DESC_OFFSET	0x20U
+
 static struct fwu_metadata metadata;
 static bool is_metadata_initialized __unused;
 
@@ -51,16 +62,54 @@
 /*******************************************************************************
  * Check the sanity of FWU metadata.
  *
- * return -1 on error, otherwise 0
+ * return -EINVAL on error, otherwise 0
  ******************************************************************************/
 static int fwu_metadata_sanity_check(void)
 {
-	/* ToDo: add more conditions for sanity check */
-	if ((metadata.active_index >= NR_OF_FW_BANKS) ||
-	    (metadata.previous_active_index >= NR_OF_FW_BANKS)) {
-		return -1;
+	if (metadata.version != FWU_METADATA_VERSION) {
+		WARN("Incorrect FWU Metadata version of %u\n",
+		     metadata.version);
+		return -EINVAL;
+	}
+
+	if (metadata.active_index >= NR_OF_FW_BANKS) {
+		WARN("Active Index value(%u) greater than the configured value(%d)",
+		     metadata.active_index, NR_OF_FW_BANKS);
+		return -EINVAL;
+	}
+
+	if (metadata.previous_active_index >= NR_OF_FW_BANKS) {
+		WARN("Previous Active Index value(%u) greater than the configured value(%d)",
+		     metadata.previous_active_index, NR_OF_FW_BANKS);
+		return -EINVAL;
+	}
+
+#if PSA_FWU_METADATA_FW_STORE_DESC
+	if (metadata.fw_desc.num_banks != NR_OF_FW_BANKS) {
+		WARN("Number of Banks(%u) in FWU Metadata different from the configured value(%d)",
+		     metadata.fw_desc.num_banks, NR_OF_FW_BANKS);
+		return -EINVAL;
 	}
 
+	if (metadata.fw_desc.num_images != NR_OF_IMAGES_IN_FW_BANK) {
+		WARN("Number of Images(%u) in FWU Metadata different from the configured value(%d)",
+		     metadata.fw_desc.num_images, NR_OF_IMAGES_IN_FW_BANK);
+		return -EINVAL;
+	}
+
+	if (metadata.desc_offset != FWU_FW_STORE_DESC_OFFSET) {
+		WARN("Descriptor Offset(0x%x) in the FWU Metadata not equal to 0x20\n",
+		     metadata.desc_offset);
+		return -EINVAL;
+	}
+#else
+	if (metadata.desc_offset != 0U) {
+		WARN("Descriptor offset has non zero value of 0x%x\n",
+		     metadata.desc_offset);
+		return -EINVAL;
+	}
+#endif
+
 	return 0;
 }
 
@@ -133,28 +182,80 @@
 }
 
 /*******************************************************************************
- * The system runs in the trial run state if any of the images in the active
- * firmware bank has not been accepted yet.
+ * Check for an alternate bank for the platform to boot from. This function will
+ * mostly be called whenever the count of the number of times a platform boots
+ * in the Trial State exceeds a pre-set limit.
+ * The function first checks if the platform can boot from the previously active
+ * bank. If not, it tries to find another bank in the accepted state.
+ * And finally, if both the checks fail, as a last resort, it tries to find
+ * a valid bank.
  *
- * Returns true if the system is running in the trial state.
+ * Returns the index of a bank to boot, else returns invalid index
+ * INVALID_BOOT_IDX.
  ******************************************************************************/
-bool fwu_is_trial_run_state(void)
+uint32_t fwu_get_alternate_boot_bank(void)
 {
-	bool trial_run = false;
+	uint32_t i;
 
-	assert(is_metadata_initialized);
+	/* First check if the previously active bank can be used */
+	if (metadata.bank_state[metadata.previous_active_index] ==
+	    FWU_BANK_STATE_ACCEPTED) {
+		return metadata.previous_active_index;
+	}
 
-	for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
-		struct fwu_image_entry *entry = &metadata.img_entry[i];
-		struct fwu_image_properties *img_props =
-			&entry->img_props[metadata.active_index];
-		if (img_props->accepted == 0) {
-			trial_run = true;
-			break;
+	/* Now check for any other bank in the accepted state */
+	for (i = 0U; i < NR_OF_FW_BANKS; i++) {
+		if (i == metadata.active_index ||
+		    i == metadata.previous_active_index) {
+			continue;
+		}
+
+		if (metadata.bank_state[i] == FWU_BANK_STATE_ACCEPTED) {
+			return i;
 		}
 	}
 
-	return trial_run;
+	/*
+	 * No accepted bank found. Now try booting from a valid bank.
+	 * Give priority to the previous active bank.
+	 */
+	if (metadata.bank_state[metadata.previous_active_index] ==
+	    FWU_BANK_STATE_VALID) {
+		return metadata.previous_active_index;
+	}
+
+	for (i = 0U; i < NR_OF_FW_BANKS; i++) {
+		if (i == metadata.active_index ||
+		    i == metadata.previous_active_index) {
+			continue;
+		}
+
+		if (metadata.bank_state[i] == FWU_BANK_STATE_VALID) {
+			return i;
+		}
+	}
+
+	return INVALID_BOOT_IDX;
+}
+
+/*******************************************************************************
+ * The platform can be in one of Valid, Invalid or Accepted states.
+ *
+ * Invalid - One or more images in the bank are corrupted, or partially
+ *           overwritten. The bank is not to be used for booting.
+ *
+ * Valid - All images of the bank are valid but at least one image has not
+ *         been accepted. This implies that the platform is in Trial State.
+ *
+ * Accepted - All images of the bank are valid and accepted.
+ *
+ * Returns the state of the current active bank
+ ******************************************************************************/
+uint32_t fwu_get_active_bank_state(void)
+{
+	assert(is_metadata_initialized);
+
+	return metadata.bank_state[metadata.active_index];
 }
 
 const struct fwu_metadata *fwu_get_metadata(void)
diff --git a/drivers/measured_boot/rse/dice_prot_env.c b/drivers/measured_boot/rse/dice_prot_env.c
new file mode 100644
index 0000000..dad30b2
--- /dev/null
+++ b/drivers/measured_boot/rse/dice_prot_env.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+#include <lib/cassert.h>
+#include <lib/psa/dice_protection_environment.h>
+
+#include <platform_def.h>
+
+#define DPE_ALG_SHA512 0
+#define DPE_ALG_SHA384 1
+#define DPE_ALG_SHA256 2
+
+#if DPE_ALG_ID == DPE_ALG_SHA512
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA512
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_512
+#elif DPE_ALG_ID == DPE_ALG_SHA384
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA384
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_384
+#elif DPE_ALG_ID == DPE_ALG_SHA256
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA256
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_256
+#else
+#  error Invalid DPE hash algorithm.
+#endif /* DPE_ALG_ID */
+
+/* Ensure that computed hash values fits into the DiceInputValues structure */
+CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE,
+	assert_digest_size_bigger_than_allocated_buffer);
+
+static int initial_context_handle;
+
+static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata,
+					DiceInputValues  *dice_inputs)
+{
+	/* Hash of the content certificate signing key (public part) */
+	memcpy(dice_inputs->authority_hash, metadata->signer_id,
+	       DPE_DIGEST_SIZE);
+
+	/* SW type string identifier */
+	assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE);
+	dice_inputs->code_descriptor = metadata->sw_type;
+	dice_inputs->code_descriptor_size = metadata->sw_type_size;
+}
+
+void dpe_init(struct dpe_metadata *metadata)
+{
+	assert(metadata != NULL);
+
+	/* Init the non-const members of the metadata structure */
+	while (metadata->id != DPE_INVALID_ID) {
+		/* Terminating 0 character is not needed due to CBOR encoding */
+		metadata->sw_type_size =
+			strlen((const char *)&metadata->sw_type);
+		metadata++;
+	}
+
+	plat_dpe_get_context_handle(&initial_context_handle);
+}
+
+int dpe_measure_and_record(struct dpe_metadata *metadata,
+			   uintptr_t data_base, uint32_t data_size,
+			   uint32_t data_id)
+{
+	static int current_context_handle;
+	DiceInputValues dice_inputs = { 0 };
+	int new_parent_context_handle;
+	int new_context_handle;
+	dpe_error_t ret;
+	int rc;
+
+	assert(metadata != NULL);
+
+	/* Get the metadata associated with this image. */
+	while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) {
+		metadata++;
+	}
+
+	/* If image is not present in metadata array then skip */
+	if (metadata->id == DPE_INVALID_ID) {
+		return 0;
+	}
+
+	/* Calculate hash */
+	rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+				  (void *)data_base, data_size,
+				   dice_inputs.code_hash);
+	if (rc != 0) {
+		return rc;
+	}
+
+	map_metadata_to_dice_inputs(metadata, &dice_inputs);
+
+	/* Only at the first call */
+	if (current_context_handle == 0) {
+		current_context_handle = initial_context_handle;
+	}
+
+	VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id);
+	ret = dpe_derive_context(current_context_handle,
+				 metadata->cert_id,
+				 metadata->retain_parent_context,
+				 metadata->allow_new_context_to_derive,
+				 metadata->create_certificate,
+				 &dice_inputs,
+				 metadata->target_locality,
+				 false, /* return_certificate */
+				 true, /* allow_new_context_to_export */
+				 false, /* export_cdi */
+				 &new_context_handle,
+				 &new_parent_context_handle,
+				 NULL, 0, NULL,  /* new_certificate_* */
+				 NULL, 0, NULL); /* exported_cdi_* */
+	if (ret == DPE_NO_ERROR) {
+		current_context_handle = new_parent_context_handle;
+		if (metadata->allow_new_context_to_derive == true) {
+			/* Share new_context_handle with child component:
+			 * e.g: BL2, BL33.
+			 */
+			VERBOSE("Share new_context_handle with child: 0x%x\n",
+				new_context_handle);
+			plat_dpe_share_context_handle(&new_context_handle,
+						      &new_parent_context_handle);
+		}
+	} else {
+		ERROR("dpe_derive_context failed: %d\n", ret);
+	}
+
+	return (ret == DPE_NO_ERROR) ? 0 : -1;
+}
+
+int dpe_set_signer_id(struct dpe_metadata *metadata,
+		      const void *pk_oid,
+		      const void *pk_ptr,
+		      size_t pk_len)
+{
+	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+	int rc;
+	bool hash_calc_done = false;
+
+	assert(metadata != NULL);
+
+	/*
+	 * 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->id != DPE_INVALID_ID) {
+		/* Get the metadata associated with this key-oid */
+		if (metadata->pk_oid == pk_oid) {
+			if (hash_calc_done == false) {
+				/* 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;
+			}
+
+			/*
+			 * 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->signer_id,
+				     hash_data,
+				     DPE_DIGEST_SIZE);
+			metadata->signer_id_size = DPE_DIGEST_SIZE;
+		}
+
+		metadata++;
+	}
+
+	return 0;
+}
diff --git a/drivers/measured_boot/rse/dice_prot_env.mk b/drivers/measured_boot/rse/dice_prot_env.mk
new file mode 100644
index 0000000..7c83307
--- /dev/null
+++ b/drivers/measured_boot/rse/dice_prot_env.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Hash algorithm for DICE Protection Environment
+# SHA-256 (or stronger) is required.
+DPE_HASH_ALG	:=	sha256
+
+ifeq (${DPE_HASH_ALG}, sha512)
+    DPE_ALG_ID		:=	DPE_ALG_SHA512
+    DPE_DIGEST_SIZE	:=	64U
+else ifeq (${DPE_HASH_ALG}, sha384)
+    DPE_ALG_ID		:=	DPE_ALG_SHA384
+    DPE_DIGEST_SIZE	:=	48U
+else
+    DPE_ALG_ID		:=	DPE_ALG_SHA256
+    DPE_DIGEST_SIZE	:=	32U
+endif #DPE_HASH_ALG
+
+# Set definitions for DICE Protection Environment
+$(eval $(call add_defines,\
+    $(sort \
+        DPE_ALG_ID \
+        DPE_DIGEST_SIZE \
+)))
+
+DPE_SOURCES	+=	drivers/measured_boot/rse/dice_prot_env.c
diff --git a/drivers/measured_boot/rse/qcbor.mk b/drivers/measured_boot/rse/qcbor.mk
new file mode 100644
index 0000000..2146e5d
--- /dev/null
+++ b/drivers/measured_boot/rse/qcbor.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TF-A was tested with v1.2 version of QCBOR
+
+ifeq (${QCBOR_DIR},)
+        $(error Error: QCBOR_DIR not set)
+endif
+
+QCBOR_SOURCES	+=	${QCBOR_DIR}/src/qcbor_encode.c \
+			${QCBOR_DIR}/src/qcbor_decode.c \
+			${QCBOR_DIR}/src/UsefulBuf.c
+
+QCBOR_INCLUDES	+=	${QCBOR_DIR}/inc
+
+# Floating point numbers are not used, so disable the support.
+# This reduces the library size as well.
+$(eval $(call add_define,QCBOR_DISABLE_FLOAT_HW_USE))
+$(eval $(call add_define,USEFULBUF_DISABLE_ALL_FLOAT))
+$(eval $(call add_define,QCBOR_DISABLE_PREFERRED_FLOAT))
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rse/rse_measured_boot.c
similarity index 86%
rename from drivers/measured_boot/rss/rss_measured_boot.c
rename to drivers/measured_boot/rse/rse_measured_boot.c
index 258aa8d..5337c3d 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rse/rse_measured_boot.c
@@ -9,7 +9,7 @@
 
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 #include <lib/psa/measured_boot.h>
 #include <psa/crypto_types.h>
 #include <psa/crypto_values.h>
@@ -46,12 +46,12 @@
 #endif /* ENABLE_ASSERTIONS */
 
 /* Functions' declarations */
-void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr)
+void rse_measured_boot_init(struct rse_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) {
+	while (metadata_ptr->id != RSE_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;
@@ -59,7 +59,7 @@
 	}
 }
 
-int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
+int rse_mboot_measure_and_record(struct rse_mboot_metadata *metadata_ptr,
 				 uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id)
 {
@@ -70,13 +70,13 @@
 	assert(metadata_ptr != NULL);
 
 	/* Get the metadata associated with this image. */
-	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
+	while ((metadata_ptr->id != RSE_MBOOT_INVALID_ID) &&
 		(metadata_ptr->id != data_id)) {
 		metadata_ptr++;
 	}
 
 	/* If image is not present in metadata array then skip */
-	if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
+	if (metadata_ptr->id == RSE_MBOOT_INVALID_ID) {
 		return 0;
 	}
 
@@ -87,7 +87,7 @@
 		return rc;
 	}
 
-	ret = rss_measured_boot_extend_measurement(
+	ret = rse_measured_boot_extend_measurement(
 						metadata_ptr->slot,
 						metadata_ptr->signer_id,
 						metadata_ptr->signer_id_size,
@@ -106,7 +106,7 @@
 	return 0;
 }
 
-int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr,
 			    const void *pk_oid,
 			    const void *pk_ptr,
 			    size_t pk_len)
@@ -125,10 +125,10 @@
 	 * The platform may decide not to measure all of the images
 	 * in the system.
 	 */
-	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
+	while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) {
 		/* Get the metadata associated with this key-oid */
 		if (metadata_ptr->pk_oid == pk_oid) {
-			if (!hash_calc_done) {
+			if (hash_calc_done == false) {
 				/* Calculate public key hash */
 				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
 							  (void *)pk_ptr,
diff --git a/drivers/measured_boot/rss/rss_measured_boot.mk b/drivers/measured_boot/rse/rse_measured_boot.mk
similarity index 65%
rename from drivers/measured_boot/rss/rss_measured_boot.mk
rename to drivers/measured_boot/rse/rse_measured_boot.mk
index 18ee836..1bd971f 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.mk
+++ b/drivers/measured_boot/rse/rse_measured_boot.mk
@@ -6,27 +6,27 @@
 
 # Hash algorithm for measured boot
 # SHA-256 (or stronger) is required.
-MBOOT_RSS_HASH_ALG		:=	sha256
+MBOOT_RSE_HASH_ALG		:=	sha256
 
-ifeq (${MBOOT_RSS_HASH_ALG}, sha512)
+ifeq (${MBOOT_RSE_HASH_ALG}, sha512)
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA512
     MBOOT_DIGEST_SIZE		:=	64U
-else ifeq (${MBOOT_RSS_HASH_ALG}, sha384)
+else ifeq (${MBOOT_RSE_HASH_ALG}, sha384)
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA384
     MBOOT_DIGEST_SIZE		:=	48U
 else
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA256
     MBOOT_DIGEST_SIZE		:=	32U
-endif #MBOOT_RSS_HASH_ALG
+endif #MBOOT_RSE_HASH_ALG
 
 # Set definitions for Measured Boot driver.
 $(eval $(call add_defines,\
     $(sort \
         MBOOT_ALG_ID \
         MBOOT_DIGEST_SIZE \
-        MBOOT_RSS_BACKEND \
+        MBOOT_RSE_BACKEND \
 )))
 
-MEASURED_BOOT_SRC_DIR	:= drivers/measured_boot/rss/
+MEASURED_BOOT_SRC_DIR	:= drivers/measured_boot/rse/
 
-MEASURED_BOOT_SOURCES	+= ${MEASURED_BOOT_SRC_DIR}rss_measured_boot.c
+MEASURED_BOOT_SOURCES	+= ${MEASURED_BOOT_SRC_DIR}rse_measured_boot.c
diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
index 1af51f8..12e22e9 100644
--- a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
+++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
@@ -26,8 +26,8 @@
 # CST_BL31
 define CST_BL31_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL31_INPUT_FILE}
 endef
 
@@ -36,8 +36,8 @@
 # CST_BL32
 define CST_BL32_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL32_INPUT_FILE}
 endef
 
@@ -46,8 +46,8 @@
 # CST_BL33
 define CST_BL33_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL33_INPUT_FILE}
 endef
 
@@ -56,8 +56,8 @@
 # CST_SCP_BL2
 define CST_SCP_BL2_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${FUSE_INPUT_FILE}
 endef
 
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk
new file mode 100644
index 0000000..f5279d3
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk
@@ -0,0 +1,19 @@
+#
+# Copyright 2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES		+= \
+	-I${PLAT_DRIVERS_INCLUDE_PATH}/clk/s32cc \
+
+CLK_SOURCES		:= \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_drv.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_modules.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_utils.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_early_clks.c \
+	drivers/clk/clk.c \
+
+ifeq (${BL_COMM_CLK_NEEDED},yes)
+BL2_SOURCES		+= ${CLK_SOURCES}
+endif
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
new file mode 100644
index 0000000..e6653bd
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/clk.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-utils.h>
+
+#define MAX_STACK_DEPTH		(15U)
+
+static int update_stack_depth(unsigned int *depth)
+{
+	if (*depth == 0U) {
+		return -ENOMEM;
+	}
+
+	(*depth)--;
+	return 0;
+}
+
+static int s32cc_clk_enable(unsigned long id)
+{
+	return -ENOTSUP;
+}
+
+static void s32cc_clk_disable(unsigned long id)
+{
+}
+
+static bool s32cc_clk_is_enabled(unsigned long id)
+{
+	return false;
+}
+
+static unsigned long s32cc_clk_get_rate(unsigned long id)
+{
+	return 0;
+}
+
+static int set_module_rate(const struct s32cc_clk_obj *module,
+			   unsigned long rate, unsigned long *orate,
+			   unsigned int *depth);
+
+static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_osc *osc = s32cc_obj2osc(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((osc->freq != 0UL) && (rate != osc->freq)) {
+		ERROR("Already initialized oscillator. freq = %lu\n",
+		      osc->freq);
+		return -EINVAL;
+	}
+
+	osc->freq = rate;
+	*orate = osc->freq;
+
+	return 0;
+}
+
+static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_clk *clk = s32cc_obj2clk(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) &&
+	    ((rate < clk->min_freq) || (rate > clk->max_freq))) {
+		ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n",
+		      rate, clk->min_freq, clk->max_freq);
+		return -EINVAL;
+	}
+
+	if (clk->module != NULL) {
+		return set_module_rate(clk->module, rate, orate, depth);
+	}
+
+	if (clk->pclock != NULL) {
+		return set_clk_freq(&clk->pclock->desc, rate, orate, depth);
+	}
+
+	return -EINVAL;
+}
+
+static int set_module_rate(const struct s32cc_clk_obj *module,
+			   unsigned long rate, unsigned long *orate,
+			   unsigned int *depth)
+{
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	switch (module->type) {
+	case s32cc_clk_t:
+		ret = set_clk_freq(module, rate, orate, depth);
+		break;
+	case s32cc_osc_t:
+		ret = set_osc_freq(module, rate, orate, depth);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int s32cc_clk_set_rate(unsigned long id, unsigned long rate,
+			      unsigned long *orate)
+{
+	unsigned int depth = MAX_STACK_DEPTH;
+	const struct s32cc_clk *clk;
+	int ret;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	ret = set_module_rate(&clk->desc, rate, orate, &depth);
+	if (ret != 0) {
+		ERROR("Failed to set frequency (%lu MHz) for clock %lu\n",
+		      rate, id);
+	}
+
+	return ret;
+}
+
+static int s32cc_clk_get_parent(unsigned long id)
+{
+	return -ENOTSUP;
+}
+
+static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id)
+{
+	return -ENOTSUP;
+}
+
+void s32cc_clk_register_drv(void)
+{
+	static const struct clk_ops s32cc_clk_ops = {
+		.enable		= s32cc_clk_enable,
+		.disable	= s32cc_clk_disable,
+		.is_enabled	= s32cc_clk_is_enabled,
+		.get_rate	= s32cc_clk_get_rate,
+		.set_rate	= s32cc_clk_set_rate,
+		.get_parent	= s32cc_clk_get_parent,
+		.set_parent	= s32cc_clk_set_parent,
+	};
+
+	clk_register(&s32cc_clk_ops);
+}
+
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
new file mode 100644
index 0000000..f8fc52f
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-utils.h>
+
+/* Oscillators */
+static struct s32cc_osc fxosc =
+	S32CC_OSC_INIT(S32CC_FXOSC);
+static struct s32cc_clk fxosc_clk =
+	S32CC_MODULE_CLK(fxosc);
+
+static struct s32cc_osc firc =
+	S32CC_OSC_INIT(S32CC_FIRC);
+static struct s32cc_clk firc_clk =
+	S32CC_MODULE_CLK(firc);
+
+static struct s32cc_osc sirc =
+	S32CC_OSC_INIT(S32CC_SIRC);
+static struct s32cc_clk sirc_clk =
+	S32CC_MODULE_CLK(sirc);
+
+static struct s32cc_clk *s32cc_hw_clk_list[3] = {
+	/* Oscillators */
+	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
+	[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
+	[S32CC_CLK_ID(S32CC_CLK_FXOSC)] = &fxosc_clk,
+};
+
+static struct s32cc_clk_array s32cc_hw_clocks = {
+	.type_mask = S32CC_CLK_TYPE(S32CC_CLK_FIRC),
+	.clks = &s32cc_hw_clk_list[0],
+	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
+};
+
+struct s32cc_clk *s32cc_get_arch_clk(unsigned long id)
+{
+	static const struct s32cc_clk_array *clk_table[1] = {
+		&s32cc_hw_clocks,
+	};
+
+	return s32cc_get_clk_from_table(clk_table, ARRAY_SIZE(clk_table), id);
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_utils.c b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
new file mode 100644
index 0000000..14ab674
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-utils.h>
+
+static struct s32cc_clk *s32cc_clk_get_from_array(const struct s32cc_clk_array *arr,
+						  unsigned long clk_id)
+{
+	unsigned long type, id;
+
+	type = S32CC_CLK_TYPE(clk_id);
+
+	if (type != arr->type_mask) {
+		return NULL;
+	}
+
+	id = S32CC_CLK_ID(clk_id);
+
+	if (id >= arr->n_clks) {
+		return NULL;
+	}
+
+	return arr->clks[id];
+}
+
+struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
+					   size_t size,
+					   unsigned long clk_id)
+{
+	struct s32cc_clk *clk;
+	size_t i;
+
+	for (i = 0; i < size; i++) {
+		clk = s32cc_clk_get_from_array(clk_arr[i], clk_id);
+		if (clk != NULL) {
+			return clk;
+		}
+	}
+
+	return NULL;
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
new file mode 100644
index 0000000..fc1dc02
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <drivers/clk.h>
+#include <s32cc-clk-drv.h>
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-utils.h>
+
+#define S32CC_FXOSC_FREQ	(40U * MHZ)
+
+int s32cc_init_early_clks(void)
+{
+	int ret;
+
+	s32cc_clk_register_drv();
+
+	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
diff --git a/drivers/nxp/console/console.mk b/drivers/nxp/console/console.mk
index 6174650..5f3c6e3 100644
--- a/drivers/nxp/console/console.mk
+++ b/drivers/nxp/console/console.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2021 NXP
+# Copyright 2021-2024 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -28,8 +28,13 @@
 CONSOLE_SOURCES		:=	drivers/arm/pl011/aarch64/pl011_console.S	\
 				${PLAT_DRIVERS_PATH}/console/console_pl011.c
 else
+ifeq ($(CONSOLE), LINFLEX)
+CONSOLE_SOURCES		:=	${PLAT_DRIVERS_PATH}/console/linflex_console.S
+else
 	$(error -> CONSOLE not set!)
 endif
+
+endif
 endif
 
 ifeq (${BL_COMM_CONSOLE_NEEDED},yes)
diff --git a/drivers/nxp/console/linflex_console.S b/drivers/nxp/console/linflex_console.S
new file mode 100644
index 0000000..abcbb59
--- /dev/null
+++ b/drivers/nxp/console/linflex_console.S
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/libc/errno.h>
+
+#include <asm_macros.S>
+#include <console_macros.S>
+#include <lib/utils_def.h>
+
+#define LDIV_MULTIPLIER		U(16)
+
+#define LINFLEX_LINCR1		(0x0)
+#define LINCR1_INIT		BIT_32(0)
+#define LINCR1_MME		BIT_32(4)
+
+#define LINFLEX_LINSR		(0x8)
+#define LINSR_LINS_INITMODE	(0x00001000)
+#define LINSR_LINS_MASK		(0x0000F000)
+
+#define LINFLEX_UARTCR		(0x10)
+#define UARTCR_ROSE		BIT_32(23)
+
+#define LINFLEX_UARTSR		(0x14)
+#define LINFLEX_LINIBRR		(0x28)
+#define LINFLEX_LINFBRR		(0x24)
+#define LINFLEX_BDRL		(0x38)
+#define LINFLEX_UARTPTO		(0x50)
+
+#define UARTCR_UART		BIT_32(0)
+#define UARTCR_WL0		BIT_32(1)
+#define UARTCR_PC0		BIT_32(3)
+#define UARTCR_TXEN		BIT_32(4)
+#define UARTCR_RXEN		BIT_32(5)
+#define UARTCR_PC1		BIT_32(6)
+#define UARTCR_TFBM		BIT_32(8)
+#define UARTCR_RFBM		BIT_32(9)
+#define UARTCR_OSR_SHIFT	U(24)
+#define UARTCR_OSR_WIDTH	U(4)
+
+#define UARTSR_DTF		BIT_32(1)
+
+/*
+ * "core" functions are low-level implementations that do not require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+.globl console_linflex_core_init
+.globl console_linflex_core_putc
+
+.globl console_linflex_register
+.globl console_linflex_putc
+
+/**
+ * uint32_t get_ldiv_mult(uintptr_t baseaddr, uint32_t clock,
+ *                        uint32_t baud, console_t *console,);
+ *
+ * Clobber list : x0 - x6
+ * Out x4: LDIV multiplier
+ */
+func get_ldiv_mult
+	ldr	w4, [x0, LINFLEX_UARTCR]
+	mov	w5, w4
+
+	/* Prepare choices in w5 and w6 */
+	ubfx	x5, x5, #UARTCR_OSR_SHIFT, #UARTCR_OSR_WIDTH
+	mov	w6, #LDIV_MULTIPLIER
+
+	and	w4, w4, #UARTCR_ROSE
+	cmp	w4, #0x0
+	csel	w4, w5, w6, ne
+	ret
+endfunc get_ldiv_mult
+
+/*
+ * void linflex_set_brg(uintptr_t baseaddr, uint32_t clock
+ *                      uint32_t baud, console_t *console);
+ *
+ * Clobber list : x0 - x7, x13
+ */
+func linflex_set_brg
+	mov	x13, x30
+	bl	get_ldiv_mult
+	mov	x30, x13
+
+	/* (x4) dividr = baudrate * ldiv_mult */
+	mul	x4, x4, x2
+	/* (x5) divisr = clock rate */
+	mov	x5, x1
+	/* (x6) ibr = divisr / dividr */
+	udiv	x6, x5, x4
+	/* (x7) fbr = divisr % dividr */
+	msub	x7, x6, x4, x5
+	/* fbr *= 16 / dividr */
+	lsl	x7, x7, #4
+	udiv	x7, x7, x4
+	/* fbr &= 0xf */
+	and	w7, w7, #0xf
+	str	w6, [x0, LINFLEX_LINIBRR]
+	str	w7, [x0, LINFLEX_LINFBRR]
+	ret
+endfunc linflex_set_brg
+
+/**
+ * int console_linflex_core_init(uintptr_t baseaddr, uint32_t clock,
+ *                               uint32_t baud);
+ *
+ * In:  x0 - Linflex base address
+ *      x1 - clock frequency
+ *      x2 - baudrate
+ * Out: x0 - 1 on success, 0 on error
+ * Clobber list : x0 - x7, x13 - x14
+ */
+func console_linflex_core_init
+	/* Set master mode and init mode */
+	mov	w4, #(LINCR1_INIT)
+	str	w4, [x0, LINFLEX_LINCR1]
+	mov	w4, #(LINCR1_MME | LINCR1_INIT)
+	str	w4, [x0, LINFLEX_LINCR1]
+
+	/* wait for init mode entry */
+wait_init_entry:
+	ldr	w4, [x0, LINFLEX_LINSR]
+	and	w4, w4, #LINSR_LINS_MASK
+	cmp	w4, #LINSR_LINS_INITMODE
+	b.ne	wait_init_entry
+
+	/* Set UART bit */
+	mov	w4, #UARTCR_UART
+	str	w4, [x0, LINFLEX_UARTCR]
+
+	mov	x14, x30
+	bl	linflex_set_brg
+	mov	x30, x14
+
+	/* Set preset timeout register value. */
+	mov	w4, #0xf
+	str	w4, [x0, LINFLEX_UARTPTO]
+
+	/* 8-bit data, no parity, Tx/Rx enabled, UART mode */
+	mov	w4, #(UARTCR_PC1 | UARTCR_RXEN | UARTCR_TXEN | UARTCR_PC0 | \
+		      UARTCR_WL0 | UARTCR_UART | UARTCR_RFBM | UARTCR_TFBM)
+	str	w4, [x0, LINFLEX_UARTCR]
+
+	/* End init mode */
+	ldr	w4, [x0, LINFLEX_LINCR1]
+	bic	w4, w4, #LINCR1_INIT
+	str	w4, [x0, LINFLEX_LINCR1]
+	ret
+endfunc console_linflex_core_init
+
+/**
+ * int console_linflex_register(uintptr_t baseaddr, uint32_t clock,
+ *                              uint32_t clock, uint32_t baud);
+ *
+ * Function to initialize and register the console.
+ * The caller needs to pass an empty console_linflex_t
+ * structure in which *MUST* be allocated in
+ * persistent memory (e.g. a global or static local
+ * variable, *NOT* on the stack).
+ * In:  x0 - Linflex base address
+ *      x1 - clock frequency
+ *      x2 - baudrate
+ *      x3 - pointer to empty console_t structure
+ * Out: x0 - 1 on success, 0 on error
+ * Clobber list : x0 - x7, x13 - x15
+ */
+func console_linflex_register
+	mov	x15, x30
+	bl	console_linflex_core_init
+	mov	x30, x15
+
+	/* Populate the base address */
+	str	x0, [x3, #CONSOLE_T_BASE]
+
+	mov	x0, x3
+	finish_console_register linflex, putc=1, getc=0, flush=0
+endfunc console_linflex_register
+
+/**
+ * int console_linflex_core_putc(int c, uintptr_t baseaddr);
+
+ * Out: w0 - printed character on success, < 0 on error.
+ * Clobber list : x0 - x3
+ */
+func console_linflex_core_putc
+	cbz	x1, putc_error
+
+	cmp	w0, #'\n'
+	b.ne	print_char
+
+	/* Print '\r\n' for each '\n' */
+	mov	x0, #'\r'
+	mov	x14, x30
+	bl	console_linflex_core_putc
+	mov	x30, x14
+	mov	x0, #'\n'
+
+print_char:
+	ldr	w2, [x1, LINFLEX_UARTCR]
+	and	w2, w2, #UARTCR_TFBM
+	cmp	w2, #0x0
+	b.eq	buffer_mode
+
+fifo_mode:
+	/* UART is in FIFO mode */
+	ldr	w2, [x1, LINFLEX_UARTSR]
+	and	w2, w2, #UARTSR_DTF
+	cmp	w2, #0
+	b.ne	fifo_mode
+
+	strb	w0, [x1, LINFLEX_BDRL]
+	b	no_error
+
+buffer_mode:
+	strb	w0, [x1, LINFLEX_BDRL]
+
+buffer_loop:
+	ldr	w2, [x1, LINFLEX_UARTSR]
+	and	w3, w2, #UARTSR_DTF
+	cmp	w3, #0
+	b.eq	buffer_loop
+
+	/**
+	 * In Buffer Mode the DTFTFF bit of UARTSR register
+	 * has to be set in software
+	 */
+	mov	w2, #UARTSR_DTF
+	str	w2, [x1, LINFLEX_UARTSR]
+
+no_error:
+	mov	x0, #0
+	ret
+
+putc_error:
+	mov	x0, #-EINVAL
+	ret
+endfunc console_linflex_core_putc
+
+/**
+ * int console_linflex_putc(int c, console_t *console);
+ *
+ * Function to output a character over the console. It
+ * returns the character printed on success or -EINVAL on error.
+ * In : w0 - character to be printed
+ *      x1 - pointer to console_t struct
+ * Out: w0 - printed character on success, < 0 on error.
+ * Clobber list : x0 - x3, x15
+ */
+func console_linflex_putc
+	cbz	x1, putc_error
+	ldr	x1, [x1, #CONSOLE_T_BASE]
+
+	b	console_linflex_core_putc
+puct_error:
+	mov	x0, #-EINVAL
+	ret
+endfunc console_linflex_putc
diff --git a/drivers/nxp/ddr/phy-gen2/ddrphy.mk b/drivers/nxp/ddr/phy-gen2/ddrphy.mk
index ba5c774..a09a278 100644
--- a/drivers/nxp/ddr/phy-gen2/ddrphy.mk
+++ b/drivers/nxp/ddr/phy-gen2/ddrphy.mk
@@ -12,9 +12,9 @@
 DDR_PHY_H  =
 
 $(DDR_PHY_C): $(DDR_PHY_H) $(COMMON_HDRS) src
-	@cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
+	$(q)cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
 
 $(DDR_PHY_H): src
-	@cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
+	$(q)cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
 
 #------------------------------------------------
diff --git a/drivers/nxp/drivers.mk b/drivers/nxp/drivers.mk
index d77e985..761571d 100644
--- a/drivers/nxp/drivers.mk
+++ b/drivers/nxp/drivers.mk
@@ -97,3 +97,7 @@
 ifeq (${IFC_NAND_NEEDED},yes)
 include ${PLAT_DRIVERS_PATH}/ifc/nand/ifc_nand.mk
 endif
+
+ifeq (${CLK_NEEDED},yes)
+include ${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk.mk
+endif
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 555fe7f..c4f7493 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -50,7 +50,7 @@
 {
 	size_t bytes_read;
 	int result;
-	mbr_entry_t *tmp;
+	mbr_entry_t tmp;
 
 	assert(mbr_entry != NULL);
 	/* MBR partition table is in LBA0. */
@@ -73,19 +73,19 @@
 		return -ENOENT;
 	}
 
-	tmp = (mbr_entry_t *)(&mbr_sector[MBR_PRIMARY_ENTRY_OFFSET]);
+	memcpy(&tmp, mbr_sector + MBR_PRIMARY_ENTRY_OFFSET, sizeof(tmp));
 
-	if (tmp->first_lba != 1) {
+	if (tmp.first_lba != 1) {
 		VERBOSE("MBR header may have an invalid first LBA\n");
 		return -EINVAL;
 	}
 
-	if ((tmp->sector_nums == 0) || (tmp->sector_nums == UINT32_MAX)) {
+	if ((tmp.sector_nums == 0) || (tmp.sector_nums == UINT32_MAX)) {
 		VERBOSE("MBR header entry has an invalid number of sectors\n");
 		return -EINVAL;
 	}
 
-	memcpy(mbr_entry, tmp, sizeof(mbr_entry_t));
+	memcpy(mbr_entry, &tmp, sizeof(mbr_entry_t));
 	return 0;
 }
 
@@ -190,11 +190,11 @@
 static int load_mbr_entries(uintptr_t image_handle)
 {
 	mbr_entry_t mbr_entry;
-	int i;
+	unsigned int i;
 
 	list.entry_count = MBR_PRIMARY_ENTRY_NUMBER;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		load_mbr_entry(image_handle, &mbr_entry, i);
 		list.list[i].start = mbr_entry.first_lba * 512;
 		list.list[i].length = mbr_entry.sector_nums * 512;
@@ -244,7 +244,7 @@
 		return result;
 	}
 
-	for (i = 0; i < (unsigned int)list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		result = load_gpt_entry(image_handle, &entry);
 		if (result != 0) {
 			VERBOSE("Failed to load gpt entry data(%u) error is (%i)\n",
@@ -441,9 +441,9 @@
  */
 const partition_entry_t *get_partition_entry(const char *name)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		if (strcmp(name, list.list[i].name) == 0) {
 			return &list.list[i];
 		}
@@ -452,14 +452,15 @@
 }
 
 /*
- * Try retrieving a partition table entry based on the GUID.
+ * Try retrieving a partition table entry based on the partition type GUID.
  */
-const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
+const partition_entry_t *get_partition_entry_by_type(
+	const struct efi_guid *type_guid)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
-		if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) {
+	for (i = 0U; i < list.entry_count; i++) {
+		if (guidcmp(type_guid, &list.list[i].type_guid) == 0) {
 			return &list.list[i];
 		}
 	}
@@ -468,14 +469,15 @@
 }
 
 /*
- * Try retrieving a partition table entry based on the UUID.
+ * Try retrieving a partition table entry based on the unique partition GUID.
  */
-const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
+const partition_entry_t *get_partition_entry_by_guid(
+	const struct efi_guid *part_guid)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
-		if (guidcmp(part_uuid, &list.list[i].part_guid) == 0) {
+	for (i = 0U; i < list.entry_count; i++) {
+		if (guidcmp(part_guid, &list.list[i].part_guid) == 0) {
 			return &list.list[i];
 		}
 	}
diff --git a/drivers/renesas/rcar/qos/D3/qos_init_d3.c b/drivers/renesas/rcar/qos/D3/qos_init_d3.c
index b96e822..8e1ebcb 100644
--- a/drivers/renesas/rcar/qos/D3/qos_init_d3.c
+++ b/drivers/renesas/rcar/qos/D3/qos_init_d3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,7 +18,7 @@
 
 struct rcar_gen3_dbsc_qos_settings d3_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
 	{ DBSC_DBSCHSZ0, 0x00000001 },
diff --git a/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c b/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c
index 6f4c66c..1931dd1 100644
--- a/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c
+++ b/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 
 struct rcar_gen3_dbsc_qos_settings e3_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
 	{ DBSC_DBSCHSZ0, 0x00000001 },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c b/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c
index 329bcb8..6d93313 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,7 @@
 struct rcar_gen3_dbsc_qos_settings h3_v11_qos[] = {
 	/* BUFCAM settings */
 	/* DBSC_DBCAM0CNF0 not set */
-	{ DBSC_DBCAM0CNF1, 0x00044218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	/* DBSC_DBCAM0CNF3 not set */
 	{ DBSC_DBSCHCNT0, 0x080F0037 },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c b/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c
index c20ab08..f44da87 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -63,7 +63,7 @@
 
 struct rcar_gen3_dbsc_qos_settings h3_v20_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218U },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4U },
 	{ DBSC_DBCAM0CNF3, 0x00000000U },
 	{ DBSC_DBSCHCNT0, 0x000F0037U },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c b/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c
index 1fe6182..867d9e0 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings h3_v30_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218U },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4U },
 	{ DBSC_DBCAM0CNF3, 0x00000000U },
 	{ DBSC_DBSCHCNT0, 0x000F0037U },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c b/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c
index f1ee41b..d758dbf 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings h3n_v30_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218U },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4U },
 	{ DBSC_DBCAM0CNF3, 0x00000000U },
 	{ DBSC_DBSCHCNT0, 0x000F0037U },
diff --git a/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c b/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c
index a8264cb..d096d01 100644
--- a/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c
+++ b/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,7 +19,7 @@
 struct rcar_gen3_dbsc_qos_settings m3_v10_qos[] = {
 	/* BUFCAM settings */
 	/* DBSC_DBCAM0CNF0 not set */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBCAM0CNF3, 0x00000000 },
 	{ DBSC_DBSCHCNT0, 0x080F0037 },
diff --git a/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c b/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c
index 22fd83a..640fe80 100644
--- a/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c
+++ b/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2017-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings m3_v11_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBCAM0CNF3, 0x00000000 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
diff --git a/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c b/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c
index 43d21d7..f5ca4b6 100644
--- a/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c
+++ b/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2019-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings m3_v30_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBCAM0CNF3, 0x00000000 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
diff --git a/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c b/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
index 446340b..95c6ac9 100644
--- a/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
+++ b/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2017-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -60,7 +60,7 @@
 
 struct rcar_gen3_dbsc_qos_settings m3n_v10_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
 	{ DBSC_DBSCHSZ0, 0x00000001 },
diff --git a/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c b/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c
index 076876c..4e1734c 100644
--- a/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c
+++ b/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation
  * All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -19,7 +19,7 @@
 
 struct rcar_gen3_dbsc_qos_settings v3m_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00044218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x080F003F },
 	{ DBSC_DBSCHCNT1, 0x00001010 },
diff --git a/drivers/scmi-msg/common.h b/drivers/scmi-msg/common.h
index 62f3087..6b186d0 100644
--- a/drivers/scmi-msg/common.h
+++ b/drivers/scmi-msg/common.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause */
 /*
- * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2020, Linaro Limited
  */
 #ifndef SCMI_MSG_COMMON_H
@@ -15,6 +15,7 @@
 #include "clock.h"
 #include "power_domain.h"
 #include "reset_domain.h"
+#include "sensor.h"
 
 #define SCMI_VERSION			0x20000U
 #define SCMI_IMPL_VERSION		0U
@@ -119,6 +120,13 @@
 scmi_msg_handler_t scmi_msg_get_pd_handler(struct scmi_msg *msg);
 
 /*
+ * scmi_msg_get_sensor_handler - Return a handler for a sensor message
+ * @msg - message to process
+ * Return a function handler for the message or NULL
+ */
+scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg);
+
+/*
  * Process Read, process and write response for input SCMI message
  *
  * @msg: SCMI message context
diff --git a/drivers/scmi-msg/entry.c b/drivers/scmi-msg/entry.c
index 399115c..5ac68e1 100644
--- a/drivers/scmi-msg/entry.c
+++ b/drivers/scmi-msg/entry.c
@@ -15,6 +15,7 @@
 #pragma weak scmi_msg_get_rstd_handler
 #pragma weak scmi_msg_get_pd_handler
 #pragma weak scmi_msg_get_voltage_handler
+#pragma weak scmi_msg_get_sensor_handler
 
 scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg __unused)
 {
@@ -36,6 +37,11 @@
 	return NULL;
 }
 
+scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg __unused)
+{
+	return NULL;
+}
+
 void scmi_status_response(struct scmi_msg *msg, int32_t status)
 {
 	assert(msg->out && msg->out_size >= sizeof(int32_t));
@@ -75,6 +81,9 @@
 	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
 		handler = scmi_msg_get_pd_handler(msg);
 		break;
+	case SCMI_PROTOCOL_ID_SENSOR:
+		handler = scmi_msg_get_sensor_handler(msg);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/scmi-msg/sensor.c b/drivers/scmi-msg/sensor.c
new file mode 100644
index 0000000..a47018d
--- /dev/null
+++ b/drivers/scmi-msg/sensor.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2021-2024 NXP
+ */
+
+#include <cdefs.h>
+#include <string.h>
+
+#include "common.h"
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/utils_def.h>
+
+static bool message_id_is_supported(size_t message_id);
+
+uint16_t plat_scmi_sensor_count(unsigned int agent_id __unused)
+{
+	if (sensor_ops.sensor_count != NULL) {
+		return sensor_ops.sensor_count(agent_id);
+	}
+
+	return 0U;
+}
+
+uint8_t plat_scmi_sensor_max_requests(unsigned int agent_id __unused)
+{
+	if (sensor_ops.sensor_max_request != NULL) {
+		return sensor_ops.sensor_max_request(agent_id);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_reg(unsigned int agent_id __unused,
+			      unsigned int *addr)
+{
+	if (sensor_ops.get_sensor_req != NULL) {
+		return sensor_ops.get_sensor_req(agent_id, addr);
+	}
+
+	return 0U;
+}
+
+int32_t plat_scmi_sensor_reading_get(uint32_t agent_id __unused,
+				     uint16_t sensor_id __unused,
+				     uint32_t *val __unused)
+{
+	if (sensor_ops.sensor_reading_get != NULL) {
+		return sensor_ops.sensor_reading_get(agent_id, sensor_id, val);
+	}
+
+	return 0;
+}
+
+uint32_t plat_scmi_sensor_description_get(uint32_t agent_id __unused,
+					  uint16_t desc_index __unused,
+					  struct scmi_sensor_desc *desc __unused)
+{
+	if (sensor_ops.sensor_description_get != NULL) {
+		return sensor_ops.sensor_description_get(agent_id, desc_index, desc);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_update_interval(uint32_t agent_id __unused,
+					  uint16_t sensor_id __unused)
+{
+	if (sensor_ops.sensor_update_interval != NULL) {
+		return sensor_ops.sensor_update_interval(agent_id, sensor_id);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_state(uint32_t agent_id __unused,
+				uint16_t sensor_id __unused)
+{
+	if (sensor_ops.sensor_state != NULL) {
+		return sensor_ops.sensor_state(agent_id, sensor_id);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_timestamped(uint32_t agent_id __unused,
+				      uint16_t sensor_id __unused)
+{
+	if (sensor_ops.sensor_timestamped != NULL) {
+		return sensor_ops.sensor_timestamped(agent_id, sensor_id);
+	}
+
+	return 0U;
+}
+
+static void report_version(struct scmi_msg *msg)
+{
+	struct scmi_protocol_version_p2a return_values = {
+		.status = SCMI_SUCCESS,
+		.version = SCMI_PROTOCOL_VERSION_SENSOR,
+	};
+
+	if (msg->in_size != 0U) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void report_attributes(struct scmi_msg *msg)
+{
+	unsigned int addr[2];
+	unsigned int len;
+
+	struct scmi_protocol_attributes_p2a_sensor return_values = {
+		.status = SCMI_SUCCESS,
+	};
+
+	if (msg->in_size != 0U) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	return_values.num_sensors = plat_scmi_sensor_count(msg->agent_id);
+	return_values.max_reqs = plat_scmi_sensor_max_requests(msg->agent_id);
+	len = plat_scmi_sensor_reg(msg->agent_id, addr);
+	if (len != 0U) {
+		return_values.sensor_reg_low = addr[0];
+		return_values.sensor_reg_high = addr[1];
+		return_values.sensor_reg_len = len;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void report_message_attributes(struct scmi_msg *msg)
+{
+	struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in;
+	struct scmi_protocol_message_attributes_p2a return_values = {
+		.status = SCMI_SUCCESS,
+		/* For this protocol, attributes shall be zero */
+		.attributes = 0U,
+	};
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	if (!message_id_is_supported(in_args->message_id)) {
+		scmi_status_response(msg, SCMI_NOT_FOUND);
+		return;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void scmi_sensor_description_get(struct scmi_msg *msg)
+{
+	const struct scmi_sensor_description_get_a2p *in_args = (void *)msg->in;
+	struct scmi_sensor_description_get_p2a return_values = {
+		.status = SCMI_SUCCESS,
+	};
+	struct scmi_sensor_desc desc;
+	unsigned int desc_index = 0U;
+	unsigned int num_sensor_flags;
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	desc_index = SPECULATION_SAFE_VALUE(in_args->desc_index);
+
+	num_sensor_flags = plat_scmi_sensor_description_get(msg->agent_id, desc_index,
+							    &desc);
+	return_values.num_sensor_flags = num_sensor_flags;
+
+	memcpy(msg->out, &return_values, sizeof(return_values));
+	memcpy(msg->out + sizeof(return_values), &desc, sizeof(desc));
+	msg->out_size_out = sizeof(return_values) + sizeof(struct scmi_sensor_desc);
+}
+
+static void scmi_sensor_config_get(struct scmi_msg *msg)
+{
+	const struct scmi_sensor_config_get_a2p *in_args = (void *)msg->in;
+	struct scmi_sensor_config_get_p2a return_values = {
+		.status = SCMI_SUCCESS,
+	};
+	unsigned int sensor_id = 0U;
+	uint32_t update_interval, state, timestamped;
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	sensor_id = SPECULATION_SAFE_VALUE(in_args->sensor_id);
+
+	if (sensor_id >= plat_scmi_sensor_count(msg->agent_id)) {
+		scmi_status_response(msg, SCMI_INVALID_PARAMETERS);
+		return;
+	}
+
+	update_interval = plat_scmi_sensor_update_interval(msg->agent_id, sensor_id);
+	state = plat_scmi_sensor_state(msg->agent_id, sensor_id);
+	timestamped = plat_scmi_sensor_timestamped(msg->agent_id, sensor_id);
+	return_values.sensor_config = (update_interval << 11) | (timestamped << 1) | state;
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void scmi_sensor_reading_get(struct scmi_msg *msg)
+{
+	const struct scmi_sensor_reading_get_a2p *in_args = (void *)msg->in;
+	struct scmi_sensor_reading_get_p2a return_values = {
+		.status = SCMI_SUCCESS,
+	};
+	unsigned int sensor_id = 0U;
+	int32_t ret;
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	sensor_id = SPECULATION_SAFE_VALUE(in_args->sensor_id);
+
+	if (sensor_id >= plat_scmi_sensor_count(msg->agent_id)) {
+		scmi_status_response(msg, SCMI_INVALID_PARAMETERS);
+		return;
+	}
+
+	ret = plat_scmi_sensor_reading_get(msg->agent_id, sensor_id,
+					  (uint32_t *)&return_values.val);
+	if (ret) {
+		scmi_status_response(msg, SCMI_HARDWARE_ERROR);
+		return;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void scmi_sensor_list_update_intervals(struct scmi_msg *msg)
+{
+	/* TODO */
+	scmi_status_response(msg, SCMI_NOT_SUPPORTED);
+}
+
+static const scmi_msg_handler_t scmi_sensor_handler_table[SCMI_SENSOR_MAX] = {
+	[SCMI_PROTOCOL_VERSION] = report_version,
+	[SCMI_PROTOCOL_ATTRIBUTES] = report_attributes,
+	[SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes,
+	[SCMI_SENSOR_DESCRIPTION_GET] = scmi_sensor_description_get,
+	[SCMI_SENSOR_CONFIG_GET] = scmi_sensor_config_get,
+	[SCMI_SENSOR_LIST_UPDATE_INTERVALS] = scmi_sensor_list_update_intervals,
+	[SCMI_SENSOR_READING_GET] = scmi_sensor_reading_get,
+};
+
+static bool message_id_is_supported(size_t message_id)
+{
+	return scmi_sensor_handler_table[message_id] != NULL;
+}
+
+scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg)
+{
+	unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id);
+
+	if (!message_id_is_supported(message_id)) {
+		VERBOSE("pd handle not found %u\n", msg->message_id);
+		return NULL;
+	}
+
+	return scmi_sensor_handler_table[message_id];
+}
diff --git a/drivers/scmi-msg/sensor.h b/drivers/scmi-msg/sensor.h
new file mode 100644
index 0000000..28cbb1e
--- /dev/null
+++ b/drivers/scmi-msg/sensor.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2023-2024 NXP
+ */
+
+#ifndef SCMI_MSG_SENSOR_H
+#define SCMI_MSG_SENSOR_H
+
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+#define SCMI_PROTOCOL_VERSION_SENSOR	0x20000U
+
+/*
+ * Identifiers of the SCMI SENSOR Protocol commands
+ */
+enum scmi_sensor_command_id {
+	SCMI_SENSOR_DESCRIPTION_GET = 0x003,
+	SCMI_SENSOR_TRIP_POINT_NOTIFY = 0x004,
+	SCMI_SENSOR_TRIP_POINT_CONFIG = 0x005,
+	SCMI_SENSOR_READING_GET = 0x006,
+	SCMI_SENSOR_AXIS_DESCRIPTION_GET = 0x007,
+	SCMI_SENSOR_LIST_UPDATE_INTERVALS = 0x008,
+	SCMI_SENSOR_CONFIG_GET = 0x009,
+	SCMI_SENSOR_CONFIG_SET = 0x00A,
+	SCMI_SENSOR_CONTINUOUS_UPDATE_NOTIFY = 0x00B,
+	SCMI_SENSOR_MAX = 0x00C,
+};
+
+/* Protocol attributes */
+struct scmi_protocol_attributes_p2a_sensor {
+	int32_t status;
+	int16_t num_sensors;
+	uint8_t max_reqs;
+	uint8_t res;
+	uint32_t sensor_reg_low;
+	uint32_t sensor_reg_high;
+	uint32_t sensor_reg_len;
+};
+
+#define SCMI_SENSOR_NAME_LENGTH_MAX	16U
+
+struct scmi_sensor_desc {
+	uint32_t id;
+	uint32_t attr_low;
+	uint32_t attr_high;
+	uint8_t name[SCMI_SENSOR_NAME_LENGTH_MAX];
+	uint32_t power;
+	uint32_t resolution;
+	int32_t min_range_low;
+	int32_t min_range_high;
+	int32_t max_range_low;
+	int32_t max_range_high;
+};
+
+struct scmi_sensor_description_get_a2p {
+	uint32_t desc_index;
+};
+
+struct scmi_sensor_description_get_p2a {
+	int32_t status;
+	uint32_t num_sensor_flags;
+};
+
+struct scmi_sensor_config_get_a2p {
+	uint32_t sensor_id;
+};
+
+struct scmi_sensor_config_get_p2a {
+	int32_t status;
+	uint32_t sensor_config;
+};
+
+/*
+ * Sensor Reading Get
+ */
+struct scmi_sensor_reading_get_a2p {
+	uint32_t sensor_id;
+	uint32_t flags;
+};
+
+struct scmi_sensor_val {
+	uint32_t value_low;
+	uint32_t value_high;
+	uint32_t timestap_low;
+	uint32_t timestap_high;
+};
+
+struct scmi_sensor_reading_get_p2a {
+	int32_t status;
+	struct scmi_sensor_val val;
+};
+
+typedef struct {
+	uint16_t (*sensor_count)(unsigned int agent_id);
+	uint8_t (*sensor_max_request)(unsigned int agent_id);
+	uint32_t (*get_sensor_req)(unsigned int agent_id, unsigned int *addr);
+	int32_t (*sensor_reading_get)(uint32_t agent_id, uint16_t sensor_id,
+				      uint32_t *val);
+	uint32_t (*sensor_description_get)(unsigned int agent_id, uint16_t sensor_id,
+					  struct scmi_sensor_desc *desc);
+	uint32_t (*sensor_update_interval)(uint32_t agent_id, uint16_t sensor_id);
+	uint32_t (*sensor_state)(uint32_t agent_id, uint16_t sensor_id);
+	uint16_t (*sensor_timestamped)(uint32_t agent_id, uint16_t sensor_id);
+} plat_scmi_sensor_ops_t;
+
+#define REGISTER_SCMI_SENSOR_OPS(_sensor_count, _sensor_max_request, \
+				 _get_sensor_req, _sensor_reading_get, \
+				 _sensor_description_get, _sensor_update_interval, \
+				 _sensor_state, _sensor_timestamped) \
+	const plat_scmi_sensor_ops_t sensor_ops = { \
+		.sensor_count = _sensor_count, \
+		.sensor_max_request = _sensor_max_request, \
+		.get_sensor_req = _get_sensor_req, \
+		.sensor_reading_get = _sensor_reading_get, \
+		.sensor_description_get = _sensor_description_get, \
+		.sensor_update_interval = _sensor_update_interval, \
+		.sensor_state = _sensor_state, \
+		.sensor_timestamped = _sensor_timestamped, \
+	}
+
+extern const plat_scmi_sensor_ops_t sensor_ops;
+
+#endif /* SCMI_MSG_SENSOR_H */
diff --git a/drivers/st/bsec/bsec2.c b/drivers/st/bsec/bsec2.c
index a6e5220..db07d1c 100644
--- a/drivers/st/bsec/bsec2.c
+++ b/drivers/st/bsec/bsec2.c
@@ -166,11 +166,13 @@
 	struct dt_node_info bsec_info;
 
 	if (fdt_get_address(&fdt) == 0) {
+		EARLY_ERROR("%s: DT not found\n", __func__);
 		panic();
 	}
 
 	node = bsec_get_dt_node(&bsec_info);
 	if (node < 0) {
+		EARLY_ERROR("%s: BSEC node not found\n", __func__);
 		panic();
 	}
 
@@ -226,13 +228,21 @@
  */
 uint32_t bsec_probe(void)
 {
+	uint32_t version;
+	uint32_t id;
+
 	if (is_otp_invalid_mode()) {
+		EARLY_ERROR("%s: otp_invalid_mod\n", __func__);
 		return BSEC_ERROR;
 	}
 
-	if (((bsec_get_version() != BSEC_IP_VERSION_1_1) &&
-	     (bsec_get_version() != BSEC_IP_VERSION_2_0)) ||
-	    (bsec_get_id() != BSEC_IP_ID_2)) {
+	version = bsec_get_version();
+	id = bsec_get_id();
+
+	if (((version != BSEC_IP_VERSION_1_1) &&
+	     (version != BSEC_IP_VERSION_2_0)) ||
+	    (id != BSEC_IP_ID_2)) {
+		EARLY_ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
 		panic();
 	}
 
diff --git a/drivers/st/bsec/bsec3.c b/drivers/st/bsec/bsec3.c
index a803a3a..3fdaf16 100644
--- a/drivers/st/bsec/bsec3.c
+++ b/drivers/st/bsec/bsec3.c
@@ -188,7 +188,7 @@
 	uint32_t id = bsec_get_id();
 
 	if ((version != BSEC_IP_VERSION_1_0) || (id != BSEC_IP_ID_3)) {
-		ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
+		EARLY_ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
 		panic();
 	}
 
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
index 9fe8c8c..6787d50 100644
--- a/drivers/st/clk/clk-stm32-core.c
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 	return stm32_clock_data;
 }
 
-static void stm32mp1_clk_lock(struct spinlock *lock)
+static void _clk_lock(struct spinlock *lock)
 {
 	if (stm32mp_lock_available()) {
 		/* Assume interrupts are masked */
@@ -36,21 +36,21 @@
 	}
 }
 
-static void stm32mp1_clk_unlock(struct spinlock *lock)
+static void _clk_unlock(struct spinlock *lock)
 {
 	if (stm32mp_lock_available()) {
 		spin_unlock(lock);
 	}
 }
 
-void stm32mp1_clk_rcc_regs_lock(void)
+void clk_stm32_rcc_regs_lock(void)
 {
-	stm32mp1_clk_lock(&reg_lock);
+	_clk_lock(&reg_lock);
 }
 
-void stm32mp1_clk_rcc_regs_unlock(void)
+void clk_stm32_rcc_regs_unlock(void)
 {
-	stm32mp1_clk_unlock(&reg_lock);
+	_clk_unlock(&reg_lock);
 }
 
 #define TIMEOUT_US_1S	U(1000000)
@@ -224,6 +224,15 @@
 	return NULL;
 }
 
+static const struct stm32_clk_ops *_clk_get_ops(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+
+	assert(clk->ops != NO_OPS);
+
+	return priv->ops_array[clk->ops];
+}
+
 #define clk_div_mask(_width) GENMASK(((_width) - 1U), 0U)
 
 static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -377,7 +386,7 @@
 
 int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, clk_id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, clk_id);
 	const struct parent_cfg *parent;
 	uint16_t mux_id;
 	int sel;
@@ -394,8 +403,8 @@
 	mux_id &= MUX_PARENT_MASK;
 	parent = &priv->parents[mux_id];
 
-	if (clk->ops->get_parent != NULL) {
-		sel = clk->ops->get_parent(priv, clk_id);
+	if (ops->get_parent != NULL) {
+		sel = ops->get_parent(priv, clk_id);
 	} else {
 		sel = clk_mux_get_parent(priv, mux_id);
 	}
@@ -464,7 +473,7 @@
 
 unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 	int parent;
 
 	if ((unsigned int)id >= priv->num) {
@@ -476,14 +485,14 @@
 		return 0UL;
 	}
 
-	if (clk->ops->recalc_rate != NULL) {
+	if (ops->recalc_rate != NULL) {
 		unsigned long prate = 0UL;
 
 		if (parent != CLK_IS_ROOT) {
 			prate = _clk_stm32_get_rate(priv, parent);
 		}
 
-		return clk->ops->recalc_rate(priv, id, prate);
+		return ops->recalc_rate(priv, id, prate);
 	}
 
 	if (parent == CLK_IS_ROOT) {
@@ -520,10 +529,10 @@
 
 int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->enable != NULL) {
-		clk->ops->enable(priv, id);
+	if (ops->enable != NULL) {
+		ops->enable(priv, id);
 	}
 
 	return 0;
@@ -550,7 +559,7 @@
 
 	priv->gate_refcounts[id]++;
 
-	if (priv->gate_refcounts[id] == UINT_MAX) {
+	if (priv->gate_refcounts[id] == UINT8_MAX) {
 		ERROR("%s: %d max enable count !", __func__, id);
 		panic();
 	}
@@ -562,19 +571,19 @@
 {
 	int ret;
 
-	stm32mp1_clk_lock(&refcount_lock);
+	_clk_lock(&refcount_lock);
 	ret = _clk_stm32_enable_core(priv, id);
-	stm32mp1_clk_unlock(&refcount_lock);
+	_clk_unlock(&refcount_lock);
 
 	return ret;
 }
 
 void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->disable != NULL) {
-		clk->ops->disable(priv, id);
+	if (ops->disable != NULL) {
+		ops->disable(priv, id);
 	}
 }
 
@@ -610,19 +619,19 @@
 
 void _clk_stm32_disable(struct stm32_clk_priv *priv, int id)
 {
-	stm32mp1_clk_lock(&refcount_lock);
+	_clk_lock(&refcount_lock);
 
 	_clk_stm32_disable_core(priv, id);
 
-	stm32mp1_clk_unlock(&refcount_lock);
+	_clk_unlock(&refcount_lock);
 }
 
 bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->is_enabled != NULL) {
-		return clk->ops->is_enabled(priv, id);
+	if (ops->is_enabled != NULL) {
+		return ops->is_enabled(priv, id);
 	}
 
 	return priv->gate_refcounts[id];
@@ -957,6 +966,10 @@
 {
 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
 
+	if (osc_data->frequency == 0UL) {
+		return 0;
+	}
+
 	_clk_stm32_gate_enable(priv, osc_data->gate_id);
 
 	if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, true) != 0U) {
@@ -971,6 +984,10 @@
 {
 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
 
+	if (osc_data->frequency == 0UL) {
+		return;
+	}
+
 	_clk_stm32_gate_disable(priv, osc_data->gate_id);
 
 	if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, false) != 0U) {
@@ -1073,12 +1090,10 @@
 	priv->base = base;
 
 	for (i = 0U; i < priv->num; i++) {
-		const struct clk_stm32 *clk = _clk_get(priv, i);
-
-		assert(clk->ops != NULL);
+		const struct stm32_clk_ops *ops = _clk_get_ops(priv, i);
 
-		if (clk->ops->init != NULL) {
-			clk->ops->init(priv, i);
+		if (ops->init != NULL) {
+			ops->init(priv, i);
 		}
 	}
 
diff --git a/drivers/st/clk/clk-stm32-core.h b/drivers/st/clk/clk-stm32-core.h
index 8bfb513..bfb5f11 100644
--- a/drivers/st/clk/clk-stm32-core.h
+++ b/drivers/st/clk/clk-stm32-core.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -21,23 +21,23 @@
 };
 
 struct clk_div_table {
-	unsigned int val;
-	unsigned int div;
+	uint16_t val;
+	uint16_t div;
 };
 
 struct div_cfg {
+	const struct clk_div_table *table;
 	uint16_t offset;
 	uint8_t shift;
 	uint8_t width;
 	uint8_t flags;
 	uint8_t bitrdy;
-	const struct clk_div_table *table;
 };
 
 struct parent_cfg {
-	uint8_t num_parents;
 	const uint16_t *id_parents;
 	struct mux_cfg *mux;
+	uint8_t num_parents;
 };
 
 struct stm32_clk_priv;
@@ -56,9 +56,9 @@
 struct clk_stm32 {
 	uint16_t binding;
 	uint16_t parent;
+	uint8_t ops;
 	uint8_t flags;
 	void *clock_cfg;
-	const struct stm32_clk_ops *ops;
 };
 
 struct stm32_clk_priv {
@@ -73,8 +73,9 @@
 	const uint32_t nb_div;
 	struct clk_oscillator_data *osci_data;
 	const uint32_t nb_osci_data;
-	uint32_t *gate_refcounts;
+	uint8_t *gate_refcounts;
 	void *pdata;
+	const struct stm32_clk_ops **ops_array;
 };
 
 struct stm32_clk_bypass {
@@ -97,18 +98,14 @@
 
 struct clk_oscillator_data {
 	const char *name;
-	uint16_t id_clk;
-	unsigned long frequency;
-	uint16_t gate_id;
-	uint16_t gate_rdy_id;
 	struct stm32_clk_bypass *bypass;
 	struct stm32_clk_css *css;
 	struct stm32_clk_drive *drive;
-};
+	unsigned long frequency;
+	uint16_t id_clk;
+	uint16_t gate_id;
+	uint16_t gate_rdy_id;
 
-struct clk_fixed_rate {
-	const char *name;
-	unsigned long fixed_rate;
 };
 
 struct clk_gate_cfg {
@@ -144,6 +141,9 @@
 #define MASK_WIDTH_SHIFT(_width, _shift) \
 	GENMASK(((_width) + (_shift) - 1U), (_shift))
 
+void clk_stm32_rcc_regs_lock(void);
+void clk_stm32_rcc_regs_unlock(void);
+
 int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base);
 void clk_stm32_enable_critical_clocks(void);
 
@@ -218,7 +218,7 @@
 #endif
 
 struct clk_stm32_div_cfg {
-	int id;
+	uint8_t id;
 };
 
 #define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \
@@ -229,11 +229,11 @@
 		.clock_cfg	= &(struct clk_stm32_div_cfg){\
 			.id	= (_div_id),\
 		},\
-		.ops		= &clk_stm32_divider_ops,\
+		.ops		= STM32_DIVIDER_OPS,\
 	}
 
 struct clk_stm32_gate_cfg {
-	int id;
+	uint8_t id;
 };
 
 #define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \
@@ -244,12 +244,12 @@
 		.clock_cfg	= &(struct clk_stm32_gate_cfg){\
 			.id	= (_gate_id),\
 		},\
-		.ops		= &clk_stm32_gate_ops,\
+		.ops		= STM32_GATE_OPS,\
 	}
 
 struct fixed_factor_cfg {
-	unsigned int mult;
-	unsigned int div;
+	uint8_t mult;
+	uint8_t div;
 };
 
 unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
@@ -263,7 +263,7 @@
 			.mult	= (_mult),\
 			.div	= (_div),\
 		},\
-		.ops		= &clk_fixed_factor_ops,\
+		.ops		= FIXED_FACTOR_OPS,\
 	}
 
 #define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \
@@ -275,7 +275,7 @@
 			.offset		= (_offset),\
 			.bit_idx	= (_bit_idx),\
 		},\
-		.ops		= &clk_gate_ops,\
+		.ops		= GATE_OPS,\
 	}
 
 #define STM32_MUX(idx, _binding, _mux_id, _flags) \
@@ -284,7 +284,7 @@
 		.parent		= (MUX(_mux_id)),\
 		.flags		= (_flags),\
 		.clock_cfg	= NULL,\
-		.ops		= (&clk_mux_ops),\
+		.ops		= STM32_MUX_OPS\
 	}
 
 struct clk_timer_cfg {
@@ -301,7 +301,7 @@
 			.apbdiv = (_apbdiv),\
 			.timpre = (_timpre),\
 		},\
-		.ops		= &clk_timer_ops,\
+		.ops		= STM32_TIMER_OPS,\
 	}
 
 struct clk_stm32_fixed_rate_cfg {
@@ -315,7 +315,7 @@
 		.clock_cfg	= &(struct clk_stm32_fixed_rate_cfg){\
 			.rate	= (_rate),\
 		},\
-		.ops		= &clk_stm32_fixed_rate_ops,\
+		.ops		= STM32_FIXED_RATE_OPS,\
 	}
 
 #define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\
@@ -355,7 +355,7 @@
 void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id);
 
 struct stm32_osc_cfg {
-	int osc_id;
+	uint8_t osc_id;
 };
 
 #define CLK_OSC(idx, _idx, _parent, _osc_id) \
@@ -366,7 +366,7 @@
 		.clock_cfg	= &(struct stm32_osc_cfg){\
 			.osc_id = (_osc_id),\
 		},\
-		.ops		= &clk_stm32_osc_ops,\
+		.ops		= STM32_OSC_OPS,\
 	}
 
 #define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \
@@ -377,7 +377,7 @@
 		.clock_cfg	= &(struct stm32_osc_cfg){\
 			.osc_id	= (_osc_id),\
 		},\
-		.ops		= &clk_stm32_osc_nogate_ops,\
+		.ops		= STM32_OSC_NOGATE_OPS,\
 	}
 
 extern const struct stm32_clk_ops clk_mux_ops;
@@ -390,4 +390,19 @@
 extern const struct stm32_clk_ops clk_stm32_osc_ops;
 extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops;
 
+enum {
+	NO_OPS,
+	FIXED_FACTOR_OPS,
+	GATE_OPS,
+	STM32_MUX_OPS,
+	STM32_DIVIDER_OPS,
+	STM32_GATE_OPS,
+	STM32_TIMER_OPS,
+	STM32_FIXED_RATE_OPS,
+	STM32_OSC_OPS,
+	STM32_OSC_NOGATE_OPS,
+
+	STM32_LAST_OPS
+};
+
 #endif /* CLK_STM32_CORE_H */
diff --git a/drivers/st/clk/clk-stm32mp13.c b/drivers/st/clk/clk-stm32mp13.c
index 01d1764..fd62049 100644
--- a/drivers/st/clk/clk-stm32mp13.c
+++ b/drivers/st/clk/clk-stm32mp13.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -186,65 +186,7 @@
 	_MCE,
 	_FMC_K,
 	_QSPI_K,
-#if defined(IMAGE_BL32)
-	_LTDC,
-	_DMA1,
-	_DMA2,
-	_MDMA,
-	_ETH1MAC,
-	_USBH,
-	_TIM2,
-	_TIM3,
-	_TIM4,
-	_TIM5,
-	_TIM6,
-	_TIM7,
-	_LPTIM1_K,
-	_SPI2_K,
-	_SPI3_K,
-	_SPDIF_K,
-	_TIM1,
-	_TIM8,
-	_SPI1_K,
-	_SAI1_K,
-	_SAI2_K,
-	_DFSDM,
-	_FDCAN_K,
-	_TIM13,
-	_TIM14,
-	_TIM16,
-	_TIM17,
-	_SPI4_K,
-	_SPI5_K,
-	_I2C1_K,
-	_I2C2_K,
-	_ADFSDM,
-	_LPTIM2_K,
-	_LPTIM3_K,
-	_LPTIM4_K,
-	_LPTIM5_K,
-	_VREF,
-	_DTS,
-	_PMBCTRL,
-	_HDP,
-	_STGENRO,
-	_DCMIPP_K,
-	_DMAMUX1,
-	_DMAMUX2,
-	_DMA3,
-	_ADC1_K,
-	_ADC2_K,
-	_TSC,
-	_AXIMC,
-	_ETH1CK,
-	_ETH1TX,
-	_ETH1RX,
-	_CRC1,
-	_ETH2CK,
-	_ETH2TX,
-	_ETH2RX,
-	_ETH2MAC,
-#endif
+
 	CK_LAST
 };
 
@@ -947,7 +889,7 @@
 #endif
 
 /* RCC clock device driver private */
-static unsigned int refcounts_mp13[CK_LAST];
+static uint8_t refcounts_mp13[CK_LAST];
 
 static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
 
@@ -1007,6 +949,11 @@
 		return;
 	}
 
+	/* Do not reconfigure LSE if already enabled */
+	if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
+		return;
+	}
+
 	clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
 
 	clk_oscillator_set_drive(priv, _CK_LSE, drive);
@@ -1027,8 +974,8 @@
 	timeout = timeout_init_us(HSIDIV_TIMEOUT);
 	while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
-			      address, mmio_read_32(address));
+			EARLY_ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
+				    address, mmio_read_32(address));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1050,7 +997,7 @@
 	}
 
 	if (hsidiv == 4U) {
-		ERROR("Invalid clk-hsi frequency\n");
+		EARLY_ERROR("Invalid clk-hsi frequency\n");
 		return -EINVAL;
 	}
 
@@ -1292,7 +1239,7 @@
 	uint32_t value = 0;
 
 	if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) {
-		ERROR("Invalid Vref clock !\n");
+		EARLY_ERROR("Invalid Vref clock !\n");
 		panic();
 	}
 
@@ -1352,6 +1299,123 @@
 	return &pdata->pll[pll_idx];
 }
 
+/* Define characteristic for PLL1 : PLL_2000 */
+#define POST_DIVM_MIN	8000000U
+#define POST_DIVM_MAX	16000000U
+#define DIVM_MIN	0U
+#define DIVM_MAX	63U
+#define DIVN_MIN	24U
+#define DIVN_MAX	99U
+#define DIVP_MIN	0U
+#define DIVP_MAX	127U
+#define FRAC_MAX	8192U
+#define VCO_MIN		992000000U
+#define VCO_MAX		2000000000U
+
+static int clk_compute_pll1_settings(uint32_t freq_khz)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_pll_dt_cfg *pll1 = clk_stm32_pll_get_pdata(_PLL1);
+	struct stm32_pll_dt_cfg *pll2 = clk_stm32_pll_get_pdata(_PLL2);
+	unsigned long long best_diff = ULLONG_MAX;
+	unsigned int divm;
+	unsigned long input_freq = 0UL;
+	uint32_t src =  pll2->vco.src;
+
+	/* PLL1 share the same clock source than PLL2 */
+	switch (src) {
+	case CLK_PLL12_HSI:
+		input_freq = _clk_stm32_get_rate(priv, _CK_HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = _clk_stm32_get_rate(priv, _CK_HSE);
+		break;
+	default:
+		break;
+	}
+
+	if (input_freq == 0UL) {
+		panic();
+	}
+
+	/* Following parameters have always the same value */
+	pll1->output.output[PLL_CFG_Q] = 0U;
+	pll1->output.output[PLL_CFG_R] = 0U;
+
+	for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
+		unsigned long post_divm = input_freq / divm;
+		unsigned int divp;
+
+		if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
+			continue;
+		}
+
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			unsigned long long output_freq = freq_khz * 1000ULL;
+			unsigned long long freq;
+			unsigned long long divn;
+			unsigned long long frac;
+			unsigned int i;
+
+			freq = output_freq * divm * (divp + 1U);
+
+			divn = (freq / input_freq) - 1U;
+			if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
+				continue;
+			}
+
+			frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
+
+			/* 2 loops to refine the fractional part */
+			for (i = 2U; i != 0U; i--) {
+				unsigned long long diff;
+				unsigned long long vco;
+
+				if (frac > FRAC_MAX) {
+					break;
+				}
+
+				vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
+
+				if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
+					frac++;
+					continue;
+				}
+
+				freq = vco / (divp + 1U);
+				if (output_freq < freq) {
+					diff = freq - output_freq;
+				} else {
+					diff = output_freq - freq;
+				}
+
+				if (diff < best_diff)  {
+					pll1->vco.src = src;
+					pll1->vco.status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_PLLON;
+					pll1->vco.div_mn[PLL_CFG_M] = divm - 1U;
+					pll1->vco.div_mn[PLL_CFG_N] = (uint32_t)divn;
+					pll1->vco.frac = (uint32_t)frac;
+					pll1->output.output[PLL_CFG_P] = divp;
+
+					if (diff == 0U) {
+						return 0;
+					}
+
+					best_diff = diff;
+				}
+
+				frac++;
+			}
+		}
+	}
+
+	if (best_diff == ULLONG_MAX) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
 {
 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
@@ -1388,8 +1452,8 @@
 	/* Wait PLL lock */
 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("%d clock start failed @ 0x%x: 0x%x\n",
-			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+			ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
 			return -EINVAL;
 		}
 	}
@@ -1406,8 +1470,8 @@
 	/* Wait PLL lock */
 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("%d clock stop failed @ 0x%x: 0x%x\n",
-			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+			ERROR("PLL%d stop failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
 			return -EINVAL;
 		}
 	}
@@ -1629,7 +1693,7 @@
 }
 
 struct stm32_pll_cfg {
-	int pll_id;
+	uint8_t pll_id;
 };
 
 static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv,  int id,
@@ -1711,12 +1775,12 @@
 	.clock_cfg	= &(struct stm32_pll_cfg) {\
 		.pll_id = _pll_id,\
 	},\
-	.ops = &clk_stm32_pll_ops,\
+	.ops = STM32_PLL_OPS,\
 }
 
 struct clk_stm32_composite_cfg {
-	int gate_id;
-	int div_id;
+	uint8_t gate_id;
+	uint8_t div_id;
 };
 
 static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
@@ -1768,9 +1832,32 @@
 		.gate_id	= (_gate_id),\
 		.div_id	= (_div_id),\
 	},\
-	.ops = &clk_stm32_composite_ops,\
+	.ops = STM32_COMPOSITE_OPS,\
 }
 
+enum {
+	STM32_PLL_OPS = STM32_LAST_OPS,
+	STM32_COMPOSITE_OPS,
+
+	MP13_LAST_OPS
+};
+
+static const struct stm32_clk_ops *ops_array_mp13[MP13_LAST_OPS] = {
+	[NO_OPS] =  NULL,
+	[FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
+	[GATE_OPS] = &clk_gate_ops,
+	[STM32_MUX_OPS] = &clk_mux_ops,
+	[STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
+	[STM32_GATE_OPS] = &clk_stm32_gate_ops,
+	[STM32_TIMER_OPS] = &clk_timer_ops,
+	[STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
+	[STM32_OSC_OPS] = &clk_stm32_osc_ops,
+	[STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
+
+	[STM32_PLL_OPS] = &clk_stm32_pll_ops,
+	[STM32_COMPOSITE_OPS] = &clk_stm32_composite_ops
+};
+
 static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
 	/* ROOT CLOCKS */
 	CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
@@ -1882,7 +1969,6 @@
 	STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2),
 	STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK),
 
-/* TODO: CHECK CLOCK FOR BL2/BL32 AND IF ONLY FOR TEST OR NOT */
 	STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3),
 	STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4),
 	STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5),
@@ -1896,61 +1982,6 @@
 	STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1),
 	STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2),
 	STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE),
-
-#if defined(IMAGE_BL32)
-	STM32_GATE(_TIM2, TIM2_K, _CKTIMG1, 0, GATE_TIM2),
-	STM32_GATE(_TIM3, TIM3_K, _CKTIMG1, 0, GATE_TIM3),
-	STM32_GATE(_TIM4, TIM4_K, _CKTIMG1, 0, GATE_TIM4),
-	STM32_GATE(_TIM5, TIM5_K, _CKTIMG1, 0, GATE_TIM5),
-	STM32_GATE(_TIM6, TIM6_K, _CKTIMG1, 0, GATE_TIM6),
-	STM32_GATE(_TIM7, TIM7_K, _CKTIMG1, 0, GATE_TIM7),
-	STM32_GATE(_TIM13, TIM13_K, _CKTIMG3, 0, GATE_TIM13),
-	STM32_GATE(_TIM14, TIM14_K, _CKTIMG3, 0, GATE_TIM14),
-	STM32_GATE(_LPTIM1_K, LPTIM1_K, MUX(MUX_LPTIM1), 0, GATE_LPTIM1),
-	STM32_GATE(_SPI2_K, SPI2_K, MUX(MUX_SPI23), 0, GATE_SPI2),
-	STM32_GATE(_SPI3_K, SPI3_K, MUX(MUX_SPI23), 0, GATE_SPI3),
-	STM32_GATE(_SPDIF_K, SPDIF_K, MUX(MUX_SPDIF), 0, GATE_SPDIF),
-	STM32_GATE(_TIM1, TIM1_K, _CKTIMG2, 0, GATE_TIM1),
-	STM32_GATE(_TIM8, TIM8_K, _CKTIMG2, 0, GATE_TIM8),
-	STM32_GATE(_TIM16, TIM16_K, _CKTIMG3, 0, GATE_TIM16),
-	STM32_GATE(_TIM17, TIM17_K, _CKTIMG3, 0, GATE_TIM17),
-	STM32_GATE(_SPI1_K, SPI1_K, MUX(MUX_SPI1), 0, GATE_SPI1),
-	STM32_GATE(_SPI4_K, SPI4_K, MUX(MUX_SPI4), 0, GATE_SPI4),
-	STM32_GATE(_SPI5_K, SPI5_K, MUX(MUX_SPI5), 0, GATE_SPI5),
-	STM32_GATE(_SAI1_K, SAI1_K, MUX(MUX_SAI1), 0, GATE_SAI1),
-	STM32_GATE(_SAI2_K, SAI2_K, MUX(MUX_SAI2), 0, GATE_SAI2),
-	STM32_GATE(_DFSDM, DFSDM_K, MUX(MUX_SAI1), 0, GATE_DFSDM),
-	STM32_GATE(_FDCAN_K, FDCAN_K, MUX(MUX_FDCAN), 0, GATE_FDCAN),
-	STM32_GATE(_USBH, USBH, _CKAXI, 0, GATE_USBH),
-	STM32_GATE(_I2C1_K, I2C1_K, MUX(MUX_I2C12), 0, GATE_I2C1),
-	STM32_GATE(_I2C2_K, I2C2_K, MUX(MUX_I2C12), 0, GATE_I2C2),
-	STM32_GATE(_ADFSDM, ADFSDM_K, MUX(MUX_SAI1), 0, GATE_ADFSDM),
-	STM32_GATE(_LPTIM2_K, LPTIM2_K, MUX(MUX_LPTIM2), 0, GATE_LPTIM2),
-	STM32_GATE(_LPTIM3_K, LPTIM3_K, MUX(MUX_LPTIM3), 0, GATE_LPTIM3),
-	STM32_GATE(_LPTIM4_K, LPTIM4_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM4),
-	STM32_GATE(_LPTIM5_K, LPTIM5_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM5),
-	STM32_GATE(_VREF, VREF, _PCLK3, 0, GATE_VREF),
-	STM32_GATE(_DTS, TMPSENS, _PCLK3, 0, GATE_DTS),
-	STM32_GATE(_PMBCTRL, PMBCTRL, _PCLK3, 0, GATE_HDP),
-	STM32_GATE(_HDP, HDP, _PCLK3, 0, GATE_PMBCTRL),
-	STM32_GATE(_STGENRO, STGENRO, _PCLK4, 0, GATE_DCMIPP),
-	STM32_GATE(_DCMIPP_K, DCMIPP_K, MUX(MUX_DCMIPP), 0, GATE_DCMIPP),
-	STM32_GATE(_DMAMUX1, DMAMUX1, _CKAXI, 0, GATE_DMAMUX1),
-	STM32_GATE(_DMAMUX2, DMAMUX2, _CKAXI, 0, GATE_DMAMUX2),
-	STM32_GATE(_DMA3, DMA3, _CKAXI, 0, GATE_DMAMUX2),
-	STM32_GATE(_ADC1_K, ADC1_K, MUX(MUX_ADC1), 0, GATE_ADC1),
-	STM32_GATE(_ADC2_K, ADC2_K, MUX(MUX_ADC2), 0, GATE_ADC2),
-	STM32_GATE(_TSC, TSC, _CKAXI, 0, GATE_TSC),
-	STM32_GATE(_AXIMC, AXIMC, _CKAXI, 0, GATE_AXIMC),
-	STM32_GATE(_CRC1, CRC1, _CKAXI, 0, GATE_ETH1TX),
-	STM32_GATE(_ETH1CK, ETH1CK_K, MUX(MUX_ETH1), 0, GATE_ETH1CK),
-	STM32_GATE(_ETH1TX, ETH1TX, _CKAXI, 0, GATE_ETH1TX),
-	STM32_GATE(_ETH1RX, ETH1RX, _CKAXI, 0, GATE_ETH1RX),
-	STM32_GATE(_ETH2CK, ETH2CK_K, MUX(MUX_ETH2), 0, GATE_ETH2CK),
-	STM32_GATE(_ETH2TX, ETH2TX, _CKAXI, 0, GATE_ETH2TX),
-	STM32_GATE(_ETH2RX, ETH2RX, _CKAXI, 0, GATE_ETH2RX),
-	STM32_GATE(_ETH2MAC, ETH2MAC, _CKAXI, 0, GATE_ETH2MAC),
-#endif
 };
 
 static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB];
@@ -1986,6 +2017,7 @@
 	.nb_osci_data	= ARRAY_SIZE(stm32mp13_osc_data),
 	.gate_refcounts	= refcounts_mp13,
 	.pdata		= &stm32mp13_clock_pdata,
+	.ops_array	= ops_array_mp13,
 };
 
 static int stm32mp1_init_clock_tree(void)
@@ -2072,8 +2104,6 @@
 	return 0;
 }
 
-#define LSEDRV_MEDIUM_HIGH 2
-
 static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
 					  struct stm32_osci_dt_cfg *osci)
 {
@@ -2241,7 +2271,8 @@
 {
 	size_t i = 0U;
 
-	for (i = _PLL1; i < pdata->npll; i++) {
+	/* PLL1 is not configurable with device tree */
+	for (i = _PLL2; i < pdata->npll; i++) {
 		struct stm32_pll_dt_cfg *pll = &pdata->pll[i];
 		char name[RCC_PLL_NAME_SIZE];
 		int subnode = 0;
@@ -2301,32 +2332,47 @@
 	return 0;
 }
 
-int stm32mp1_clk_init(void)
+void stm32mp1_clk_rcc_regs_lock(void)
 {
-	return 0;
+	clk_stm32_rcc_regs_lock();
 }
 
-int stm32mp1_clk_probe(void)
+void stm32mp1_clk_rcc_regs_unlock(void)
 {
-	uintptr_t base = RCC_BASE;
+	clk_stm32_rcc_regs_unlock();
+}
+
+int stm32mp1_clk_init(void)
+{
 	int ret;
 
-	ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
+	/* compute the PLL1 settings, not read in device tree */
+	ret = clk_compute_pll1_settings(PLL1_NOMINAL_FREQ_IN_KHZ);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_stm32_init(&stm32mp13_clock_data, base);
+	ret = stm32mp1_init_clock_tree();
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = stm32mp1_init_clock_tree();
+	clk_stm32_enable_critical_clocks();
+
+	return 0;
+}
+
+int stm32mp1_clk_probe(void)
+{
+	uintptr_t base = RCC_BASE;
+	int ret;
+
+	ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
 	if (ret != 0) {
 		return ret;
 	}
 
-	clk_stm32_enable_critical_clocks();
+	ret = clk_stm32_init(&stm32mp13_clock_data, base);
 
-	return 0;
+	return ret;
 }
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index c9c3c5f..3d352af 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -27,6 +27,71 @@
 
 #include <platform_def.h>
 
+enum stm32mp1_pllcfg {
+	PLLCFG_M,
+	PLLCFG_N,
+	PLL_DIV_MN_NB,
+	PLLCFG_P = PLL_DIV_MN_NB,
+	PLLCFG_Q,
+	PLLCFG_R,
+	PLLCFG_O,
+	PLLCFG_NB
+};
+
+#define PLL_DIV_MN_NB	2
+#define PLL_DIV_PQR_NB	3
+
+enum stm32mp1_pllcsg {
+	PLLCSG_MOD_PER,
+	PLLCSG_INC_STEP,
+	PLLCSG_SSCG_MODE,
+	PLLCSG_NB
+};
+
+struct stm32_pll_dt_cfg {
+	bool status;
+	uint32_t src;
+	uint32_t cfg[PLLCFG_NB];
+	uint32_t frac;
+	bool csg_enabled;
+	uint32_t csg[PLLCSG_NB];
+};
+
+struct stm32_clk_platdata {
+	uint32_t npll;
+	struct stm32_pll_dt_cfg *pll;
+	uint32_t nclksrc;
+	uint32_t *clksrc;
+	uint32_t nclkdiv;
+	uint32_t *clkdiv;
+	bool lse_css;
+};
+
+struct stm32_clk_priv {
+	uintptr_t base;
+	const struct mux_cfg *parents;
+	const uint32_t nb_parents;
+	const struct div_cfg *div;
+	const uint32_t nb_div;
+	void *pdata;
+};
+
+static struct stm32_clk_priv *stm32_clock_data;
+
+static struct stm32_clk_priv *clk_stm32_get_priv(void)
+{
+	return stm32_clock_data;
+}
+
+static int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base)
+{
+	stm32_clock_data = priv;
+
+	priv->base = base;
+
+	return 0;
+}
+
 #define MAX_HSI_HZ		64000000
 #define USB_PHY_48_MHZ		48000000
 
@@ -39,6 +104,199 @@
 #define HSIDIV_TIMEOUT		TIMEOUT_US_200MS
 #define OSCRDY_TIMEOUT		TIMEOUT_US_1S
 
+struct mux_cfg {
+	uint16_t offset;
+	uint8_t shift;
+	uint8_t width;
+	uint8_t bitrdy;
+};
+
+struct div_cfg {
+	uint16_t offset;
+	uint8_t shift;
+	uint8_t width;
+	uint8_t bitrdy;
+};
+
+#define DIV_NO_BIT_RDY UINT8_MAX
+
+#define DIV_CFG(_id, _offset, _shift, _width,  _bitrdy)\
+	[(_id)] = {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_width),\
+		.bitrdy	= (_bitrdy),\
+	}
+
+static const struct div_cfg dividers_mp15[] = {
+	DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 31),
+	DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 31),
+	DIV_CFG(DIV_MCU, RCC_MCUDIVR, 0, 4, 31),
+	DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 31),
+	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_ETHPTP, RCC_ETHCKSELR, 4, 4, DIV_NO_BIT_RDY),
+};
+
+/*
+ * MUX CONFIG
+ */
+
+#define MUX_NO_BIT_RDY		UINT8_MAX
+
+#define MUXRDY_CFG(_id, _offset, _shift, _width,  _bitrdy)\
+	[(_id)] = {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_width),\
+		.bitrdy = (_bitrdy),\
+	}
+
+#define MUX_CFG(_id, _offset, _shift, _width)\
+	MUXRDY_CFG(_id, _offset, _shift, _width,  MUX_NO_BIT_RDY)
+
+static const struct mux_cfg parent_mp15[MUX_NB] = {
+	MUX_CFG(MUX_PLL12,	RCC_RCK12SELR, 0, 2),
+	MUX_CFG(MUX_PLL3,	RCC_RCK3SELR, 0, 2),
+	MUX_CFG(MUX_PLL4,	RCC_RCK4SELR, 0, 2),
+	MUX_CFG(MUX_CKPER,	RCC_CPERCKSELR, 0, 2),
+	MUXRDY_CFG(MUX_MPU,	RCC_MPCKSELR, 0, 2, 31),
+	MUXRDY_CFG(MUX_AXI,	RCC_ASSCKSELR, 0, 3, 31),
+	MUXRDY_CFG(MUX_MCU,	RCC_MSSCKSELR, 0, 2, 31),
+	MUX_CFG(MUX_RTC,	RCC_BDCR, 16, 2),
+	MUX_CFG(MUX_SDMMC12,	RCC_SDMMC12CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI2S23,	RCC_SPI2S23CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI45,	RCC_SPI45CKSELR, 0, 3),
+	MUX_CFG(MUX_I2C12,	RCC_I2C12CKSELR, 0, 3),
+	MUX_CFG(MUX_I2C35,	RCC_I2C35CKSELR, 0, 3),
+	MUX_CFG(MUX_LPTIM23,	RCC_LPTIM23CKSELR, 0, 3),
+	MUX_CFG(MUX_LPTIM45,	RCC_LPTIM45CKSELR, 0, 3),
+	MUX_CFG(MUX_UART24,	RCC_UART24CKSELR, 0, 3),
+	MUX_CFG(MUX_UART35,	RCC_UART35CKSELR, 0, 3),
+	MUX_CFG(MUX_UART78,	RCC_UART78CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI1,	RCC_SAI1CKSELR, 0, 3),
+	MUX_CFG(MUX_ETH,	RCC_ETHCKSELR, 0, 2),
+	MUX_CFG(MUX_I2C46,	RCC_I2C46CKSELR, 0, 3),
+	MUX_CFG(MUX_RNG2,	RCC_RNG2CKSELR, 0, 2),
+	MUX_CFG(MUX_SDMMC3,	RCC_SDMMC3CKSELR, 0, 3),
+	MUX_CFG(MUX_FMC,	RCC_FMCCKSELR, 0, 2),
+	MUX_CFG(MUX_QSPI,	RCC_QSPICKSELR, 0, 2),
+	MUX_CFG(MUX_USBPHY,	RCC_USBCKSELR, 0, 2),
+	MUX_CFG(MUX_USBO,	RCC_USBCKSELR, 4, 1),
+	MUX_CFG(MUX_SPDIF,	RCC_SPDIFCKSELR, 0, 2),
+	MUX_CFG(MUX_SPI2S1,	RCC_SPI2S1CKSELR, 0, 3),
+	MUX_CFG(MUX_CEC,	RCC_CECCKSELR, 0, 2),
+	MUX_CFG(MUX_LPTIM1,	RCC_LPTIM1CKSELR, 0, 3),
+	MUX_CFG(MUX_UART6,	RCC_UART6CKSELR, 0, 3),
+	MUX_CFG(MUX_FDCAN,	RCC_FDCANCKSELR, 0, 2),
+	MUX_CFG(MUX_SAI2,	RCC_SAI2CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI3,	RCC_SAI3CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI4,	RCC_SAI4CKSELR, 0, 3),
+	MUX_CFG(MUX_ADC,	RCC_ADCCKSELR, 0, 2),
+	MUX_CFG(MUX_DSI,	RCC_DSICKSELR, 0, 1),
+	MUX_CFG(MUX_RNG1,	RCC_RNG1CKSELR, 0, 2),
+	MUX_CFG(MUX_STGEN,	RCC_STGENCKSELR, 0, 2),
+	MUX_CFG(MUX_UART1,	RCC_UART1CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI6,	RCC_SPI6CKSELR, 0, 3),
+	MUX_CFG(MUX_MCO1,	RCC_MCO1CFGR, 0, 3),
+	MUX_CFG(MUX_MCO2,	RCC_MCO2CFGR, 0, 3),
+};
+
+#define MASK_WIDTH_SHIFT(_width, _shift) \
+	GENMASK(((_width) + (_shift) - 1U), (_shift))
+
+int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id)
+{
+	const struct mux_cfg *mux;
+	uint32_t mask;
+
+	if (mux_id >= priv->nb_parents) {
+		panic();
+	}
+
+	mux = &priv->parents[mux_id];
+
+	mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+	return (mmio_read_32(priv->base + mux->offset) & mask) >> mux->shift;
+}
+
+static int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel)
+{
+	const struct mux_cfg *mux = &priv->parents[pid];
+	uintptr_t address = priv->base + mux->offset;
+	uint32_t mask;
+	uint64_t timeout;
+
+	mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+	mmio_clrsetbits_32(address, mask, (sel << mux->shift) & mask);
+
+	if (mux->bitrdy == MUX_NO_BIT_RDY) {
+		return 0;
+	}
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+
+	mask = BIT(mux->bitrdy);
+
+	while ((mmio_read_32(address) & mask) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t val)
+{
+	uint32_t data = val & CMD_DATA_MASK;
+	int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
+	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
+
+	return clk_mux_set_parent(priv, mux, sel);
+}
+
+int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value)
+{
+	const struct div_cfg *divider;
+	uintptr_t address;
+	uint64_t timeout;
+	uint32_t mask;
+
+	if (div_id >= priv->nb_div) {
+		panic();
+	}
+
+	divider = &priv->div[div_id];
+	address = priv->base + divider->offset;
+
+	mask = MASK_WIDTH_SHIFT(divider->width, divider->shift);
+	mmio_clrsetbits_32(address, mask, (value << divider->shift) & mask);
+
+	if (divider->bitrdy == DIV_NO_BIT_RDY) {
+		return 0;
+	}
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	mask = BIT(divider->bitrdy);
+
+	while ((mmio_read_32(address) & mask) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
 const char *stm32mp_osc_node_label[NB_OSC] = {
 	[_LSI] = "clk-lsi",
 	[_LSE] = "clk-lse",
@@ -206,23 +464,6 @@
 	CLKDIV_NB
 };
 
-enum stm32mp1_pllcfg {
-	PLLCFG_M,
-	PLLCFG_N,
-	PLLCFG_P,
-	PLLCFG_Q,
-	PLLCFG_R,
-	PLLCFG_O,
-	PLLCFG_NB
-};
-
-enum stm32mp1_pllcsg {
-	PLLCSG_MOD_PER,
-	PLLCSG_INC_STEP,
-	PLLCSG_SSCG_MODE,
-	PLLCSG_NB
-};
-
 enum stm32mp1_plltype {
 	PLL_800,
 	PLL_1600,
@@ -537,7 +778,18 @@
 };
 
 /* Define characteristic of PLL according type */
-#define DIVN_MIN	24
+#define POST_DIVM_MIN	8000000U
+#define POST_DIVM_MAX	16000000U
+#define DIVM_MIN	0U
+#define DIVM_MAX	63U
+#define DIVN_MIN	24U
+#define DIVN_MAX	99U
+#define DIVP_MIN	0U
+#define DIVP_MAX	127U
+#define FRAC_MAX	8192U
+#define VCO_MIN		800000000U
+#define VCO_MAX		1600000000U
+
 static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
 	[PLL_800] = {
 		.refclk_min = 4,
@@ -1327,6 +1579,11 @@
 	uint32_t value;
 	uintptr_t rcc_base = stm32mp_rcc_base();
 
+	/* Do not reconfigure LSE if it is already ON */
+	if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_LSEON) == RCC_BDCR_LSEON) {
+		return;
+	}
+
 	if (digbyp) {
 		mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_DIGBYP);
 	}
@@ -1360,7 +1617,7 @@
 static void stm32mp1_lse_wait(void)
 {
 	if (stm32mp1_osc_wait(true, RCC_BDCR, RCC_BDCR_LSERDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1369,7 +1626,7 @@
 	stm32mp1_ls_osc_set(enable, RCC_RDLSICR, RCC_RDLSICR_LSION);
 
 	if (stm32mp1_osc_wait(enable, RCC_RDLSICR, RCC_RDLSICR_LSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1387,7 +1644,7 @@
 
 	stm32mp1_hs_ocs_set(true, RCC_OCENR_HSEON);
 	if (stm32mp1_osc_wait(true, RCC_OCRDYR, RCC_OCRDYR_HSERDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 
 	if (css) {
@@ -1406,7 +1663,7 @@
 {
 	stm32mp1_hs_ocs_set(enable, RCC_OCENR_CSION);
 	if (stm32mp1_osc_wait(enable, RCC_OCRDYR, RCC_OCRDYR_CSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1414,7 +1671,7 @@
 {
 	stm32mp1_hs_ocs_set(enable, RCC_OCENR_HSION);
 	if (stm32mp1_osc_wait(enable, RCC_OCRDYR, RCC_OCRDYR_HSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1454,7 +1711,7 @@
 	}
 
 	if (hsidiv == 4U) {
-		ERROR("Invalid clk-hsi frequency\n");
+		EARLY_ERROR("Invalid clk-hsi frequency\n");
 		return -1;
 	}
 
@@ -1467,7 +1724,7 @@
 
 static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
 				    unsigned int clksrc,
-				    uint32_t *pllcfg, int plloff)
+				    uint32_t *pllcfg, uint32_t fracv)
 {
 	const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
 	uintptr_t rcc_base = stm32mp_rcc_base();
@@ -1476,8 +1733,7 @@
 	uintptr_t clksrc_address = rcc_base + (clksrc >> 4);
 	unsigned long refclk;
 	uint32_t ifrge = 0U;
-	uint32_t src, value, fracv = 0;
-	void *fdt;
+	uint32_t src, value;
 
 	/* Check PLL output */
 	if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) {
@@ -1516,10 +1772,6 @@
 	}
 
 	/* Fractional configuration */
-	if (fdt_get_address(&fdt) == 1) {
-		fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
-	}
-
 	value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
 	value |= RCC_PLLNFRACR_FRACLE;
 	if (mmio_read_32(rcc_base + pll->pllxfracr) != value) {
@@ -1561,8 +1813,8 @@
 	/* Wait PLL lock */
 	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("PLL%u start failed @ 0x%lx: 0x%x\n",
-			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			EARLY_ERROR("PLL%u start failed @ 0x%lx: 0x%x\n",
+				    pll_id, pllxcr, mmio_read_32(pllxcr));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1590,8 +1842,8 @@
 	/* Wait PLL stopped */
 	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) != 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("PLL%u stop failed @ 0x%lx: 0x%x\n",
-			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			EARLY_ERROR("PLL%u stop failed @ 0x%lx: 0x%x\n",
+				    pll_id, pllxcr, mmio_read_32(pllxcr));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1683,190 +1935,270 @@
 			RCC_PLLNCR_SSCG_CTRL);
 }
 
-static int stm32mp1_set_clksrc(unsigned int clksrc)
+static int clk_compute_pll1_settings(unsigned long input_freq,
+				     uint32_t freq_khz,
+				     uint32_t *pllcfg, uint32_t *fracv)
 {
-	uintptr_t clksrc_address = stm32mp_rcc_base() + (clksrc >> 4);
-	uint64_t timeout;
+	unsigned long long best_diff = ULLONG_MAX;
+	unsigned int divm;
 
-	mmio_clrsetbits_32(clksrc_address, RCC_SELR_SRC_MASK,
-			   clksrc & RCC_SELR_SRC_MASK);
+	/* Following parameters have always the same value */
+	pllcfg[PLLCFG_Q] = 0U;
+	pllcfg[PLLCFG_R] = 0U;
+	pllcfg[PLLCFG_O] = PQR(1, 0, 0);
 
-	timeout = timeout_init_us(CLKSRC_TIMEOUT);
-	while ((mmio_read_32(clksrc_address) & RCC_SELR_SRCRDY) == 0U) {
-		if (timeout_elapsed(timeout)) {
-			ERROR("CLKSRC %x start failed @ 0x%lx: 0x%x\n", clksrc,
-			      clksrc_address, mmio_read_32(clksrc_address));
-			return -ETIMEDOUT;
+	for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
+		unsigned long post_divm = input_freq / divm;
+		unsigned int divp;
+
+		if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
+			continue;
+		}
+
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			unsigned long long output_freq = freq_khz * 1000ULL;
+			unsigned long long freq;
+			unsigned long long divn;
+			unsigned long long frac;
+			unsigned int i;
+
+			freq = output_freq * divm * (divp + 1U);
+
+			divn = (freq / input_freq) - 1U;
+			if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
+				continue;
+			}
+
+			frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
+
+			/* 2 loops to refine the fractional part */
+			for (i = 2U; i != 0U; i--) {
+				unsigned long long diff;
+				unsigned long long vco;
+
+				if (frac > FRAC_MAX) {
+					break;
+				}
+
+				vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
+
+				if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
+					frac++;
+					continue;
+				}
+
+				freq = vco / (divp + 1U);
+				if (output_freq < freq) {
+					diff = freq - output_freq;
+				} else {
+					diff = output_freq - freq;
+				}
+
+				if (diff < best_diff)  {
+					pllcfg[PLLCFG_M] = divm - 1U;
+					pllcfg[PLLCFG_N] = (uint32_t)divn;
+					pllcfg[PLLCFG_P] = divp;
+					*fracv = (uint32_t)frac;
+
+					if (diff == 0U) {
+						return 0;
+					}
+
+					best_diff = diff;
+				}
+
+				frac++;
+			}
 		}
 	}
 
+	if (best_diff == ULLONG_MAX) {
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-static int stm32mp1_set_clkdiv(unsigned int clkdiv, uintptr_t address)
+static int clk_get_pll1_settings(uint32_t clksrc, uint32_t freq_khz,
+				 uint32_t *pllcfg, uint32_t *fracv)
 {
-	uint64_t timeout;
+	unsigned long input_freq = 0UL;
 
-	mmio_clrsetbits_32(address, RCC_DIVR_DIV_MASK,
-			   clkdiv & RCC_DIVR_DIV_MASK);
+	assert(pllcfg != NULL);
+	assert(fracv != NULL);
 
-	timeout = timeout_init_us(CLKDIV_TIMEOUT);
-	while ((mmio_read_32(address) & RCC_DIVR_DIVRDY) == 0U) {
-		if (timeout_elapsed(timeout)) {
-			ERROR("CLKDIV %x start failed @ 0x%lx: 0x%x\n",
-			      clkdiv, address, mmio_read_32(address));
-			return -ETIMEDOUT;
-		}
+	switch (clksrc) {
+	case CLK_PLL12_HSI:
+		input_freq = stm32mp_clk_get_rate(CK_HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = stm32mp_clk_get_rate(CK_HSE);
+		break;
+	default:
+		break;
 	}
 
-	return 0;
+	if (input_freq == 0UL) {
+		panic();
+	}
+
+	return clk_compute_pll1_settings(input_freq, freq_khz, pllcfg, fracv);
 }
 
-static void stm32mp1_mco_csg(uint32_t clksrc, uint32_t clkdiv)
+static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv)
 {
-	uintptr_t clksrc_address = stm32mp_rcc_base() + (clksrc >> 4);
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
 
-	/*
-	 * Binding clksrc :
-	 *      bit15-4 offset
-	 *      bit3:   disable
-	 *      bit2-0: MCOSEL[2:0]
-	 */
-	if ((clksrc & 0x8U) != 0U) {
-		mmio_clrbits_32(clksrc_address, RCC_MCOCFG_MCOON);
-	} else {
-		mmio_clrsetbits_32(clksrc_address,
-				   RCC_MCOCFG_MCOSRC_MASK,
-				   clksrc & RCC_MCOCFG_MCOSRC_MASK);
-		mmio_clrsetbits_32(clksrc_address,
-				   RCC_MCOCFG_MCODIV_MASK,
-				   clkdiv << RCC_MCOCFG_MCODIV_SHIFT);
-		mmio_setbits_32(clksrc_address, RCC_MCOCFG_MCOON);
+	for (i = 0U; i < pdata->nclkdiv; i++) {
+		uint32_t div_id, div_n;
+		uint32_t val;
+		int ret;
+
+		val = pdata->clkdiv[i] & CMD_DATA_MASK;
+		div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT;
+		div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
+
+		ret = clk_stm32_set_div(priv, div_id, div_n);
+		if (ret != 0) {
+			return ret;
+		}
 	}
+
+	return 0;
 }
 
-static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css)
+static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
 {
-	uintptr_t address = stm32mp_rcc_base() + RCC_BDCR;
+	uint32_t sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
+	uint32_t enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
+	unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
+	struct stm32_clk_platdata *pdata = priv->pdata;
 
-	if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) ||
-	    (clksrc != (uint32_t)CLK_RTC_DISABLED)) {
-		mmio_clrsetbits_32(address,
-				   RCC_BDCR_RTCSRC_MASK,
-				   (clksrc & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
+	if (binding_id == RTC) {
+		uintptr_t address = stm32mp_rcc_base() + RCC_BDCR;
 
-		mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
-	}
+		if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) || (enable != 0U)) {
+			mmio_clrsetbits_32(address, RCC_BDCR_RTCSRC_MASK,
+					   (sel & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
 
-	if (lse_css) {
-		mmio_setbits_32(address, RCC_BDCR_LSECSSON);
+			mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
+			/* Configure LSE CSS */
+			if (pdata->lse_css) {
+				mmio_setbits_32(priv->base + RCC_BDCR, RCC_BDCR_LSECSSON);
+			}
+		}
 	}
+
+	return 0;
 }
 
-static void stm32mp1_pkcs_config(uint32_t pkcs)
+static int stm32_clk_configure_by_addr_val(struct stm32_clk_priv *priv,
+					   uint32_t data)
 {
-	uintptr_t address = stm32mp_rcc_base() + ((pkcs >> 4) & 0xFFFU);
-	uint32_t value = pkcs & 0xFU;
-	uint32_t mask = 0xFU;
+	uint32_t addr = data >> CLK_ADDR_SHIFT;
+	uint32_t val = data & CLK_ADDR_VAL_MASK;
 
-	if ((pkcs & BIT(31)) != 0U) {
-		mask <<= 4;
-		value <<= 4;
-	}
+	mmio_setbits_32(priv->base + addr, val);
 
-	mmio_clrsetbits_32(address, mask, value);
+	return 0;
 }
 
-static int clk_get_pll_settings_from_dt(int plloff, unsigned int *pllcfg,
-					uint32_t *fracv, uint32_t *csg,
-					bool *csg_set)
+static int stm32_clk_source_configure(struct stm32_clk_priv *priv)
 {
-	void *fdt;
-	int ret;
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	bool ckper_disabled = false;
+	uint32_t i;
 
-	if (fdt_get_address(&fdt) == 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
+	for (i = 0U; i < pdata->nclksrc; i++) {
+		uint32_t val = pdata->clksrc[i];
+		uint32_t cmd, cmd_data;
+		int ret;
 
-	ret = fdt_read_uint32_array(fdt, plloff, "cfg", (uint32_t)PLLCFG_NB,
-				    pllcfg);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
+		if (val & CMD_ADDR_BIT) {
+			ret = stm32_clk_configure_by_addr_val(priv, val & ~CMD_ADDR_BIT);
+			if (ret != 0) {
+				return ret;
+			}
+
+			continue;
+		}
+
+		if (val == (uint32_t)CLK_CKPER_DISABLED) {
+			ckper_disabled = true;
+			continue;
+		}
+
+		cmd = (val & CMD_MASK) >> CMD_SHIFT;
+		cmd_data = val & ~CMD_MASK;
+
+		switch (cmd) {
+		case CMD_MUX:
+			ret = stm32_clk_configure_mux(priv, cmd_data);
+			break;
+
+		case CMD_CLK:
+			ret = stm32_clk_configure_clk(priv, cmd_data);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret != 0) {
+			return ret;
+		}
 	}
 
-	*fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
+	/*
+	 * CKPER is source for some peripheral clocks
+	 * (FMC-NAND / QPSI-NOR) and switching source is allowed
+	 * only if previous clock is still ON
+	 * => deactivate CKPER only after switching clock
+	 */
+	if (!ckper_disabled) {
+		return 0;
+	}
 
-	ret = fdt_read_uint32_array(fdt, plloff, "csg", (uint32_t)PLLCSG_NB,
-				    csg);
+	return stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED);
+}
 
-	*csg_set = (ret == 0);
+static int stm32mp1_pll_configure_src(struct stm32_clk_priv *priv, int pll_idx)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_pll_dt_cfg *pll_conf = &pdata->pll[pll_idx];
 
-	if (ret == -FDT_ERR_NOTFOUND) {
-		ret = 0;
+	if (!pll_conf->status) {
+		return 0;
 	}
 
-	return ret;
+	return stm32_clk_configure_mux(priv, pll_conf->src);
 }
 
 int stm32mp1_clk_init(void)
 {
-	uintptr_t rcc_base = stm32mp_rcc_base();
-	uint32_t pllfracv[_PLL_NB];
-	uint32_t pllcsg[_PLL_NB][PLLCSG_NB];
-	unsigned int clksrc[CLKSRC_NB];
-	unsigned int clkdiv[CLKDIV_NB];
-	unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
-	int plloff[_PLL_NB];
-	int ret, len;
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_pll_dt_cfg *pll_conf = pdata->pll;
+	int ret;
 	enum stm32mp1_pll_id i;
-	bool pllcsg_set[_PLL_NB];
-	bool pllcfg_valid[_PLL_NB];
-	bool lse_css = false;
 	bool pll3_preserve = false;
 	bool pll4_preserve = false;
 	bool pll4_bootrom = false;
-	const fdt32_t *pkcs_cell;
-	void *fdt;
 	int stgen_p = stm32mp1_clk_get_parent(STGEN_K);
 	int usbphy_p = stm32mp1_clk_get_parent(USBPHY_K);
+	uint32_t usbreg_bootrom = 0U;
 
-	if (fdt_get_address(&fdt) == 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB,
-					clksrc);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB,
-					clkdiv);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
-		char name[12];
-
-		snprintf(name, sizeof(name), "st,pll@%u", i);
-		plloff[i] = fdt_rcc_subnode_offset(name);
-
-		pllcfg_valid[i] = fdt_check_node(plloff[i]);
-		if (!pllcfg_valid[i]) {
-			continue;
-		}
-
-		ret = clk_get_pll_settings_from_dt(plloff[i], pllcfg[i],
-						   &pllfracv[i], pllcsg[i],
-						   &pllcsg_set[i]);
+	if (!pll_conf[_PLL1].status) {
+		ret = clk_get_pll1_settings(pll_conf[_PLL2].src, PLL1_NOMINAL_FREQ_IN_KHZ,
+					    pll_conf[_PLL1].cfg, &pll_conf[_PLL1].frac);
 		if (ret != 0) {
 			return ret;
 		}
-	}
 
-	stm32mp1_mco_csg(clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]);
-	stm32mp1_mco_csg(clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]);
+		pll_conf[_PLL1].status = true;
+		pll_conf[_PLL1].src = pll_conf[_PLL2].src;
+	}
 
 	/*
 	 * Switch ON oscillator found in device-tree.
@@ -1882,7 +2214,7 @@
 
 		bypass = fdt_clk_read_bool(name, "st,bypass");
 		digbyp = fdt_clk_read_bool(name, "st,digbypass");
-		lse_css = fdt_clk_read_bool(name, "st,css");
+		pdata->lse_css = fdt_clk_read_bool(name, "st,css");
 		lsedrv = fdt_clk_read_uint32_default(name, "st,drive",
 						     LSEDRV_MEDIUM_HIGH);
 		stm32mp1_lse_enable(bypass, digbyp, lsedrv);
@@ -1903,36 +2235,28 @@
 	stm32mp1_csi_set(true);
 
 	/* Come back to HSI */
-	ret = stm32mp1_set_clksrc(CLK_MPU_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_MPU_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clksrc(CLK_AXI_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_AXI_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clksrc(CLK_MCU_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_MCU_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-
-	if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) &
+	if ((mmio_read_32(priv->base + RCC_MP_RSTSCLRR) &
 	     RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) {
-		if (pllcfg_valid[_PLL3]) {
-			pll3_preserve =
-				stm32mp1_check_pll_conf(_PLL3,
-							clksrc[CLKSRC_PLL3],
-							pllcfg[_PLL3],
-							plloff[_PLL3]);
-		}
-
-		if (pllcfg_valid[_PLL4]) {
-			pll4_preserve =
-				stm32mp1_check_pll_conf(_PLL4,
-							clksrc[CLKSRC_PLL4],
-							pllcfg[_PLL4],
-							plloff[_PLL4]);
-		}
+		pll3_preserve = stm32mp1_check_pll_conf(_PLL3,
+							pll_conf[_PLL3].src,
+							pll_conf[_PLL3].cfg,
+							pll_conf[_PLL3].frac);
+		pll4_preserve = stm32mp1_check_pll_conf(_PLL4,
+							pll_conf[_PLL4].src,
+							pll_conf[_PLL4].cfg,
+							pll_conf[_PLL4].frac);
 	}
 	/* Don't initialize PLL4, when used by BOOTROM */
 	if ((stm32mp_get_boot_itf_selected() ==
@@ -1964,58 +2288,27 @@
 		stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
 	}
 
-	/* Select DIV */
-	/* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */
-	mmio_write_32(rcc_base + RCC_MPCKDIVR,
-		      clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK);
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc_base + RCC_AXIDIVR);
+	/* Configure dividers */
+	ret = stm32_clk_dividers_configure(priv);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc_base + RCC_APB4DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB5], rcc_base + RCC_APB5DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_MCU], rcc_base + RCC_MCUDIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc_base + RCC_APB1DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB2], rcc_base + RCC_APB2DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB3], rcc_base + RCC_APB3DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* No ready bit for RTC */
-	mmio_write_32(rcc_base + RCC_RTCDIVR,
-		      clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK);
 
 	/* Configure PLLs source */
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL12]);
+	ret = stm32mp1_pll_configure_src(priv, _PLL1);
 	if (ret != 0) {
 		return ret;
 	}
 
 	if (!pll3_preserve) {
-		ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL3]);
+		ret = stm32mp1_pll_configure_src(priv, _PLL3);
 		if (ret != 0) {
 			return ret;
 		}
 	}
 
 	if (!pll4_preserve) {
-		ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL4]);
+		ret = stm32mp1_pll_configure_src(priv, _PLL4);
 		if (ret != 0) {
 			return ret;
 		}
@@ -2028,34 +2321,34 @@
 			continue;
 		}
 
-		if (!pllcfg_valid[i]) {
+		if (!pll_conf[i].status) {
 			continue;
 		}
 
 		if ((i == _PLL4) && pll4_bootrom) {
 			/* Set output divider if not done by the Bootrom */
-			stm32mp1_pll_config_output(i, pllcfg[i]);
+			stm32mp1_pll_config_output(i, pll_conf[i].cfg);
 			continue;
 		}
 
-		ret = stm32mp1_pll_config(i, pllcfg[i], pllfracv[i]);
+		ret = stm32mp1_pll_config(i, pll_conf[i].cfg, pll_conf[i].frac);
 		if (ret != 0) {
 			return ret;
 		}
 
-		if (pllcsg_set[i]) {
-			stm32mp1_pll_csg(i, pllcsg[i]);
+		if (pll_conf[i].csg_enabled) {
+			stm32mp1_pll_csg(i, pll_conf[i].csg);
 		}
 
 		stm32mp1_pll_start(i);
 	}
 	/* Wait and start PLLs output when ready */
 	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
-		if (!pllcfg_valid[i]) {
+		if (!pll_conf[i].status) {
 			continue;
 		}
 
-		ret = stm32mp1_pll_output(i, pllcfg[i][PLLCFG_O]);
+		ret = stm32mp1_pll_output(i, pll_conf[i].cfg[PLLCFG_O]);
 		if (ret != 0) {
 			return ret;
 		}
@@ -2065,69 +2358,32 @@
 		stm32mp1_lse_wait();
 	}
 
-	/* Configure with expected clock source */
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MPU]);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_AXI]);
-	if (ret != 0) {
-		return ret;
+	if (pll4_bootrom) {
+		usbreg_bootrom = mmio_read_32(priv->base + RCC_USBCKSELR);
 	}
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MCU]);
+
+	/* Configure with expected clock source */
+	ret = stm32_clk_source_configure(priv);
 	if (ret != 0) {
-		return ret;
+		panic();
 	}
-	stm32mp1_set_rtcsrc(clksrc[CLKSRC_RTC], lse_css);
-
-	/* Configure PKCK */
-	pkcs_cell = fdt_rcc_read_prop("st,pkcs", &len);
-	if (pkcs_cell != NULL) {
-		bool ckper_disabled = false;
-		uint32_t j;
-		uint32_t usbreg_bootrom = 0U;
-
-		if (pll4_bootrom) {
-			usbreg_bootrom = mmio_read_32(rcc_base + RCC_USBCKSELR);
-		}
-
-		for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
-			uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]);
-
-			if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
-				ckper_disabled = true;
-				continue;
-			}
-			stm32mp1_pkcs_config(pkcs);
-		}
-
-		/*
-		 * CKPER is source for some peripheral clocks
-		 * (FMC-NAND / QPSI-NOR) and switching source is allowed
-		 * only if previous clock is still ON
-		 * => deactivated CKPER only after switching clock
-		 */
-		if (ckper_disabled) {
-			stm32mp1_pkcs_config(CLK_CKPER_DISABLED);
-		}
 
-		if (pll4_bootrom) {
-			uint32_t usbreg_value, usbreg_mask;
-			const struct stm32mp1_clk_sel *sel;
+	if (pll4_bootrom) {
+		uint32_t usbreg_value, usbreg_mask;
+		const struct stm32mp1_clk_sel *sel;
 
-			sel = clk_sel_ref(_USBPHY_SEL);
-			usbreg_mask = (uint32_t)sel->msk << sel->src;
-			sel = clk_sel_ref(_USBO_SEL);
-			usbreg_mask |= (uint32_t)sel->msk << sel->src;
+		sel = clk_sel_ref(_USBPHY_SEL);
+		usbreg_mask = (uint32_t)sel->msk << sel->src;
+		sel = clk_sel_ref(_USBO_SEL);
+		usbreg_mask |= (uint32_t)sel->msk << sel->src;
 
-			usbreg_value = mmio_read_32(rcc_base + RCC_USBCKSELR) &
-				       usbreg_mask;
-			usbreg_bootrom &= usbreg_mask;
-			if (usbreg_bootrom != usbreg_value) {
-				VERBOSE("forbidden new USB clk path\n");
-				VERBOSE("vs bootrom on USB boot\n");
-				return -FDT_ERR_BADVALUE;
-			}
+		usbreg_value = mmio_read_32(priv->base + RCC_USBCKSELR) &
+			       usbreg_mask;
+		usbreg_bootrom &= usbreg_mask;
+		if (usbreg_bootrom != usbreg_value) {
+			EARLY_ERROR("forbidden new USB clk path\n");
+			EARLY_ERROR("vs bootrom on USB boot\n");
+			return -FDT_ERR_BADVALUE;
 		}
 	}
 
@@ -2139,7 +2395,7 @@
 	stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
 
 	/* Software Self-Refresh mode (SSR) during DDR initilialization */
-	mmio_clrsetbits_32(rcc_base + RCC_DDRITFCR,
+	mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
 			   RCC_DDRITFCR_DDRCKMOD_MASK,
 			   RCC_DDRITFCR_DDRCKMOD_SSR <<
 			   RCC_DDRITFCR_DDRCKMOD_SHIFT);
@@ -2326,6 +2582,17 @@
 }
 #endif /* STM32MP_SHARED_RESOURCES */
 
+void stm32mp1_clk_mcuss_protect(bool enable)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	if (enable) {
+		mmio_setbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
+	} else {
+		mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
+	}
+}
+
 static void sync_earlyboot_clocks_state(void)
 {
 	unsigned int idx;
@@ -2355,8 +2622,199 @@
 	.get_parent	= stm32mp1_clk_get_parent,
 };
 
+struct stm32_pll_dt_cfg mp15_pll[_PLL_NB];
+uint32_t mp15_clksrc[MUX_NB];
+uint32_t mp15_clkdiv[DIV_NB];
+
+struct stm32_clk_platdata stm32mp15_clock_pdata = {
+	.pll		= mp15_pll,
+	.npll		= _PLL_NB,
+	.clksrc		= mp15_clksrc,
+	.nclksrc	= MUX_NB,
+	.clkdiv		= mp15_clkdiv,
+	.nclkdiv	= DIV_NB,
+};
+
+static struct stm32_clk_priv stm32mp15_clock_data = {
+	.base		= RCC_BASE,
+	.parents	= parent_mp15,
+	.nb_parents	= ARRAY_SIZE(parent_mp15),
+	.div		= dividers_mp15,
+	.nb_div		= ARRAY_SIZE(dividers_mp15),
+	.pdata		= &stm32mp15_clock_pdata,
+};
+
+static int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name,
+				       uint32_t *tab, uint32_t *nb)
+{
+	const fdt32_t *cell;
+	int len = 0;
+	uint32_t i;
+
+	cell = fdt_getprop(fdt, node, name, &len);
+	if (cell == NULL) {
+		*nb = 0U;
+		return 0;
+	}
+
+	for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		tab[i] = fdt32_to_cpu(cell[i]);
+	}
+
+	*nb = (uint32_t)len / sizeof(uint32_t);
+
+	return 0;
+}
+
+#define RCC_PLL_NAME_SIZE 12
+
+static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	int err;
+
+	err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, &pll->cfg[PLLCFG_M]);
+	if (err != 0) {
+		return err;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLLCSG_NB, pll->csg);
+	if (err == 0) {
+		pll->csg_enabled = true;
+	} else if (err == -FDT_ERR_NOTFOUND) {
+		pll->csg_enabled = false;
+	} else {
+		return err;
+	}
+
+	pll->status = true;
+
+	pll->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0);
+
+	pll->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
+
+	return 0;
+}
+
+static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	int err;
+
+	err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB,
+				    &pll->cfg[PLLCFG_P]);
+	if (err != 0) {
+		return err;
+	}
+
+	pll->cfg[PLLCFG_O] = PQR(1, 1, 1);
+
+	return 0;
+}
+
+static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	const fdt32_t *cuint;
+	int subnode_pll;
+	int subnode_vco;
+	int err;
+
+	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
+	if (cuint == NULL) {
+		/* Case of no pll is defined */
+		return 0;
+	}
+
+	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_pll < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_vco < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	err = clk_stm32_load_vco_config(fdt, subnode_vco, pll);
+	if (err != 0) {
+		return err;
+	}
+
+	err = clk_stm32_load_output_config(fdt, subnode_pll, pll);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
+{
+	size_t i = 0U;
+
+	for (i = _PLL1; i < pdata->npll; i++) {
+		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+		char name[RCC_PLL_NAME_SIZE];
+		int subnode;
+		int err;
+
+		snprintf(name, sizeof(name), "st,pll@%u", i);
+
+		subnode = fdt_subnode_offset(fdt, node, name);
+		if (!fdt_check_node(subnode)) {
+			continue;
+		}
+
+		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
+		if (err != 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
+{
+	void *fdt = NULL;
+	int node;
+	uint32_t err;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		panic();
+	}
+
+	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+
 int stm32mp1_clk_probe(void)
 {
+	uintptr_t base = RCC_BASE;
+	int ret;
+
 #if defined(IMAGE_BL32)
 	if (!fdt_get_rcc_secure_state()) {
 		mmio_write_32(stm32mp_rcc_base() + RCC_TZCR, 0U);
@@ -2365,6 +2823,16 @@
 
 	stm32mp1_osc_init();
 
+	ret = stm32_clk_parse_fdt(&stm32mp15_clock_pdata);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_stm32_init(&stm32mp15_clock_data, base);
+	if (ret != 0) {
+		return ret;
+	}
+
 	sync_earlyboot_clocks_state();
 
 	clk_register(&stm32mp_clk_ops);
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 379547f..69922fd 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -335,6 +335,19 @@
 }
 
 /*******************************************************************************
+ * This function returns the STGEN counter value.
+ ******************************************************************************/
+static unsigned long long stm32mp_stgen_get_counter(void)
+{
+#ifdef __aarch64__
+	return mmio_read_64(STGEN_BASE + CNTCV_OFF);
+#else
+	return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
+		mmio_read_32(STGEN_BASE + CNTCVL_OFF));
+#endif
+}
+
+/*******************************************************************************
  * This function configures and restores the STGEN counter depending on the
  * connected clock.
  ******************************************************************************/
@@ -350,9 +363,11 @@
 	}
 
 	mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
-	counter = stm32mp_stgen_get_counter() * rate / cntfid0;
 
-	stgen_set_counter(counter);
+	if (cntfid0 != 0U) {
+		counter = stm32mp_stgen_get_counter() * rate / cntfid0;
+		stgen_set_counter(counter);
+	}
 	mmio_write_32(STGEN_BASE + CNTFID_OFF, rate);
 	mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
 
@@ -363,32 +378,13 @@
 }
 
 /*******************************************************************************
- * This function returns the STGEN counter value.
+ * This function restores CPU generic timer rate from the STGEN clock rate.
  ******************************************************************************/
-unsigned long long stm32mp_stgen_get_counter(void)
+void stm32mp_stgen_restore_rate(void)
 {
-#ifdef __aarch64__
-	return mmio_read_64(STGEN_BASE + CNTCV_OFF);
-#else
-	return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
-		mmio_read_32(STGEN_BASE + CNTCVL_OFF));
-#endif
-}
+	unsigned long rate;
 
-/*******************************************************************************
- * This function restores the STGEN counter value.
- * It takes a first input value as a counter backup value to be restored and a
- * offset in ms to be added.
- ******************************************************************************/
-void stm32mp_stgen_restore_counter(unsigned long long value,
-				   unsigned long long offset_in_ms)
-{
-	unsigned long long cnt;
+	rate = mmio_read_32(STGEN_BASE + CNTFID_OFF);
 
-	cnt = value + ((offset_in_ms *
-			mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U);
-
-	mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
-	stgen_set_counter(cnt);
-	mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
+	write_cntfrq_el0((u_register_t)rate);
 }
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index a4a64ca..44d7c09 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -282,6 +282,7 @@
 
 	clk_disable(clock);
 
+#if STM32MP13 || STM32MP15
 	if (status == DT_SECURE) {
 		stm32mp_register_secure_gpio(bank, pin);
 #if !IMAGE_BL2
@@ -294,6 +295,9 @@
 		set_gpio_secure_cfg(bank, pin, false);
 #endif
 	}
+#else /* !STM32MP13 && !STM32MP15 */
+	set_gpio_secure_cfg(bank, pin, true);
+#endif /* STM32MP13 || STM32MP15 */
 }
 
 void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
@@ -321,3 +325,74 @@
 		 GPIO_ALTERNATE_(0), DT_DISABLED);
 	set_gpio_secure_cfg(bank, pin, stm32_gpio_is_secure_at_reset(bank));
 }
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	clk_enable(clock);
+
+	if (level == GPIO_LEVEL_HIGH) {
+		mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin));
+	} else {
+		mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin + 16U));
+	}
+
+	VERBOSE("GPIO %u level set to 0x%x\n", bank,
+		mmio_read_32(base + GPIO_IDR_OFFSET));
+
+	clk_disable(clock);
+}
+
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+	enum gpio_level level = GPIO_LEVEL_LOW;
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	clk_enable(clock);
+
+	if (mmio_read_32(base + GPIO_IDR_OFFSET) & BIT(pin)) {
+		level = GPIO_LEVEL_HIGH;
+	}
+
+	VERBOSE("GPIO %u get level 0x%x\n", bank,
+		mmio_read_32(base + GPIO_IDR_OFFSET));
+
+	clk_disable(clock);
+
+	return level;
+}
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status)
+{
+	uint32_t mode = GPIO_MODE_OUTPUT;
+	uint32_t od = 0U;
+	uint32_t pull = GPIO_NO_PULL;
+
+	VERBOSE("GPIO %u:%u set config to 0x%x\n", bank, pin, config);
+
+	if (config & GPIOF_DIR_IN) {
+		mode = GPIO_MODE_INPUT;
+	}
+
+	if (config & GPIOF_OUT_INIT_HIGH) {
+		od = 1U;
+	}
+
+	if (config & GPIOF_PULL_UP) {
+		pull |= GPIO_PULL_UP;
+	}
+
+	if (config & GPIOF_PULL_DOWN) {
+		pull |= GPIO_PULL_DOWN;
+	}
+
+	set_gpio(bank, pin, mode, GPIO_TYPE_PUSH_PULL, GPIO_SPEED_LOW,
+		 pull, od, GPIO_ALTERNATE_(0), status);
+}
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index be722f3..66988d7 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -129,7 +129,11 @@
 #define DT_SDMMC2_COMPAT		"st,stm32-sdmmc2"
 #endif
 
+#if STM32MP13 || STM32MP15
 #define SDMMC_FIFO_SIZE			64U
+#else
+#define SDMMC_FIFO_SIZE			1024U
+#endif
 
 #define STM32MP_MMC_INIT_FREQ			U(400000)	/*400 KHz*/
 #define STM32MP_SD_NORMAL_SPEED_MAX_FREQ	U(25000000)	/*25 MHz*/
diff --git a/fdts/cca_cot_descriptors.dtsi b/fdts/cca_cot_descriptors.dtsi
index d52431b..821f600 100644
--- a/fdts/cca_cot_descriptors.dtsi
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -136,30 +136,12 @@
 	images {
 		compatible = "arm, img-descs";
 
-		fw_config {
-			image-id = <FW_CONFIG_ID>;
-			parent = <&cca_content_cert>;
-			hash = <&fw_config_hash>;
-		};
-
 		hw_config {
 			image-id = <HW_CONFIG_ID>;
 			parent = <&cca_content_cert>;
 			hash = <&hw_config_hash>;
 		};
 
-		tb_fw_hash {
-			image-id = <BL2_IMAGE_ID>;
-			parent = <&cca_content_cert>;
-			hash = <&tb_fw_hash>;
-		};
-
-		tb_fw_config {
-			image-id = <TB_FW_CONFIG_ID>;
-			parent = <&cca_content_cert>;
-			hash = <&tb_fw_config_hash>;
-		};
-
 		bl31_image {
 			image-id = <BL31_IMAGE_ID>;
 			parent = <&cca_content_cert>;
diff --git a/fdts/dualroot_cot_descriptors.dtsi b/fdts/dualroot_cot_descriptors.dtsi
new file mode 100644
index 0000000..459a1dd
--- /dev/null
+++ b/fdts/dualroot_cot_descriptors.dtsi
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tools_share/dualroot_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		trusted_boot_fw_cert: trusted_boot_fw_cert {
+			root-certificate;
+			image-id =<TRUSTED_BOOT_FW_CERT_ID>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tb_fw_hash: tb_fw_hash {
+				oid = TRUSTED_BOOT_FW_HASH_OID;
+			};
+			tb_fw_config_hash: tb_fw_config_hash {
+				oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID;
+			};
+			hw_config_hash: hw_config_hash {
+				oid = HW_CONFIG_HASH_OID;
+			};
+			fw_config_hash: fw_config_hash {
+				oid = FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_key_cert: trusted_key_cert {
+			root-certificate;
+			image-id = <TRUSTED_KEY_CERT_ID>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			trusted_world_pk: trusted_world_pk {
+				oid = TRUSTED_WORLD_PK_OID;
+			};
+		};
+
+		scp_fw_key_cert: scp_fw_key_cert {
+			image-id = <SCP_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			scp_fw_content_pk: scp_fw_content_pk {
+				oid = SCP_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		scp_fw_content_cert: scp_fw_content_cert {
+			image-id = <SCP_FW_CONTENT_CERT_ID>;
+			parent = <&scp_fw_key_cert>;
+			signing-key = <&scp_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			scp_fw_hash: scp_fw_hash {
+				oid = SCP_FW_HASH_OID;
+			};
+		};
+
+		soc_fw_key_cert: soc_fw_key_cert {
+			image-id = <SOC_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+			soc_fw_content_pk: soc_fw_content_pk {
+				oid = SOC_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		soc_fw_content_cert: soc_fw_content_cert {
+			image-id = <SOC_FW_CONTENT_CERT_ID>;
+			parent = <&soc_fw_key_cert>;
+			signing-key = <&soc_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			soc_fw_hash: soc_fw_hash {
+				oid = SOC_AP_FW_HASH_OID;
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = SOC_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_os_fw_key_cert: trusted_os_fw_key_cert {
+			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_content_pk: tos_fw_content_pk {
+				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&trusted_os_fw_key_cert>;
+			signing-key = <&tos_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_extra1_hash: tos_fw_extra1_hash {
+				oid = TRUSTED_OS_FW_EXTRA1_HASH_OID;
+			};
+			tos_fw_extra2_hash: tos_fw_extra2_hash {
+				oid = TRUSTED_OS_FW_EXTRA2_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			root-certificate;
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+			};
+		};
+
+#if defined(SPD_spmd)
+		sip_sp_content_cert: sip_sp_content_cert {
+			image-id = <SIP_SP_CONTENT_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			sp_pkg1_hash: sp_pkg1_hash {
+				oid = SP_PKG1_HASH_OID;
+			};
+			sp_pkg2_hash: sp_pkg2_hash {
+				oid = SP_PKG2_HASH_OID;
+			};
+			sp_pkg3_hash: sp_pkg3_hash {
+				oid = SP_PKG3_HASH_OID;
+			};
+			sp_pkg4_hash: sp_pkg4_hash {
+				oid = SP_PKG4_HASH_OID;
+			};
+		};
+
+		plat_sp_content_cert: plat_sp_content_cert {
+			root-certificate;
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			sp_pkg5_hash: sp_pkg5_hash {
+				oid = SP_PKG5_HASH_OID;
+			};
+			sp_pkg6_hash: sp_pkg6_hash {
+				oid = SP_PKG6_HASH_OID;
+			};
+			sp_pkg7_hash: sp_pkg7_hash {
+				oid = SP_PKG7_HASH_OID;
+			};
+			sp_pkg8_hash: sp_pkg8_hash {
+				oid = SP_PKG8_HASH_OID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&trusted_boot_fw_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		scp_bl2_image {
+			image-id = <SCP_BL2_IMAGE_ID>;
+			parent = <&scp_fw_content_cert>;
+			hash = <&scp_fw_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&soc_fw_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&soc_fw_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		bl32_extra1_image {
+			image-id = <BL32_EXTRA1_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra1_hash>;
+		};
+
+		bl32_extra2_image {
+			image-id = <BL32_EXTRA2_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra2_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <NT_FW_CONFIG_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+
+#if defined(SPD_spmd)
+		sp_pkg1 {
+			image-id = <SP_PKG1_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg1_hash>;
+		};
+
+		sp_pkg2 {
+			image-id = <SP_PKG2_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg2_hash>;
+		};
+
+		sp_pkg3 {
+			image-id = <SP_PKG3_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg3_hash>;
+		};
+
+		sp_pkg4 {
+			image-id = <SP_PKG4_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg4_hash>;
+		};
+
+		sp_pkg5 {
+			image-id = <SP_PKG5_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg5_hash>;
+		};
+
+		sp_pkg6 {
+			image-id = <SP_PKG6_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg6_hash>;
+		};
+
+		sp_pkg7 {
+			image-id = <SP_PKG7_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg7_hash>;
+		};
+
+		sp_pkg8 {
+			image-id = <SP_PKG8_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg8_hash>;
+		};
+#endif
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	trusted_nv_counter: trusted_nv_counter {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_counter: non_trusted_nv_counter {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts
index 5a82c46..653c75f 100644
--- a/fdts/fvp-foundation-gicv2-psci.dts
+++ b/fdts/fvp-foundation-gicv2-psci.dts
@@ -26,7 +26,9 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index e1249d4..2827297 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -26,7 +26,9 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 7a7d461..08fbbb9 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -190,7 +190,6 @@
 		CLK_AXI_PLL2P
 		CLK_MLAHBS_PLL3
 		CLK_CKPER_HSE
-		CLK_RTC_LSE
 		CLK_SDMMC1_PLL4P
 		CLK_SDMMC2_PLL4P
 		CLK_STGEN_HSE
@@ -212,16 +211,9 @@
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
 		DIV(DIV_APB6, 1)
-		DIV(DIV_RTC, 0)
 	>;
 
 	st,pll_vco {
-		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
-			src = < CLK_PLL12_HSE >;
-			divmn = < 2 80 >;
-			frac = < 0x800 >;
-		};
-
 		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
 			src = <CLK_PLL12_HSE>;
 			divmn = <2 65>;
@@ -240,19 +232,6 @@
 		};
 	};
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1:st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-
-		st,pll = < &pll1_cfg1 >;
-
-		pll1_cfg1: pll1_cfg1 {
-			st,pll_vco = < &pll1_vco_1300Mhz >;
-			st,pll_div_pqr = < 0 1 1 >;
-		};
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
 	pll2:st,pll@1 {
 		compatible = "st,stm32mp1-pll";
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
index d583672..6f478d4 100644
--- a/fdts/stm32mp15-fw-config.dtsi
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include <common/tbbr/tbbr_img_def.h>
@@ -14,12 +14,9 @@
 
 #define DDR_NS_BASE	STM32MP_DDR_BASE
 #ifdef AARCH32_SP_OPTEE
-/* OP-TEE reserved shared memory: located at DDR top or null size */
-#define DDR_SHARE_SIZE	STM32MP_DDR_SHMEM_SIZE
-#define DDR_SHARE_BASE	(STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
-/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
+/* OP-TEE secure memory: located at DDR top */
 #define DDR_SEC_SIZE	STM32MP_DDR_S_SIZE
-#define DDR_SEC_BASE	(DDR_SHARE_BASE - DDR_SEC_SIZE)
+#define DDR_SEC_BASE	(STM32MP_DDR_BASE + (DDR_SIZE - DDR_SEC_SIZE))
 #define DDR_NS_SIZE	(DDR_SEC_BASE - DDR_NS_BASE)
 #else /* !AARCH32_SP_OPTEE */
 #define DDR_NS_SIZE	DDR_SIZE
@@ -70,10 +67,6 @@
 		memory-ranges = <
 			DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
 			DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
-#if STM32MP15_OPTEE_RSV_SHM
-			DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)
-#endif
 			>;
 #else
 		memory-ranges = <
diff --git a/fdts/stm32mp151a-prtt1a.dts b/fdts/stm32mp151a-prtt1a.dts
index 3634620..9742dcb 100644
--- a/fdts/stm32mp151a-prtt1a.dts
+++ b/fdts/stm32mp151a-prtt1a.dts
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * Copyright (C) 2023, Protonic Holland - All Rights Reserved
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
  * Author: David Jander <david@protonic.nl>
  */
 /dts-v1/;
@@ -123,7 +124,7 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts
index f0da350..7135970 100644
--- a/fdts/stm32mp157a-avenger96.dts
+++ b/fdts/stm32mp157a-avenger96.dts
@@ -175,29 +175,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -228,42 +208,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_480Mhz: pll4-vco-480Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 39>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <1 39 3 11 4 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_480Mhz>;
+			st,pll_div_pqr = <3 11 4>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index d7bcc84..d85221b 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -194,29 +194,8 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
-		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -247,42 +226,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp157c-odyssey-som.dtsi b/fdts/stm32mp157c-odyssey-som.dtsi
index a0be718..e5d41fc 100644
--- a/fdts/stm32mp157c-odyssey-som.dtsi
+++ b/fdts/stm32mp157c-odyssey-som.dtsi
@@ -207,29 +207,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -260,42 +240,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
index 5138868..12846db 100644
--- a/fdts/stm32mp15xx-dhcom-som.dtsi
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -193,29 +193,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_PLL4P
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		1 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -246,42 +226,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 1)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_600Mhz: pll4-vco-600hz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 49>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <1 49 5 11 11 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_600Mhz>;
+			st,pll_div_pqr = <5 11 11>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dhcor-som.dtsi b/fdts/stm32mp15xx-dhcor-som.dtsi
index 8d829a4..2ebfb2d 100644
--- a/fdts/stm32mp15xx-dhcor-som.dtsi
+++ b/fdts/stm32mp15xx-dhcor-som.dtsi
@@ -4,7 +4,7 @@
  * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  * Copyright (C) 2020 Marek Vasut <marex@denx.de>
  * Copyright (C) 2022 DH electronics GmbH
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include "stm32mp15-pinctrl.dtsi"
@@ -188,29 +188,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -241,42 +221,84 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
-	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */
+	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */ /* @TOCHECK */
+	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 5 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index d8b7c48..bac9e05 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -198,29 +198,8 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
-		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -251,42 +230,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index ef4c3c0..6e27b41 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -185,29 +185,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -238,41 +218,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
diff --git a/fdts/tbbr_cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
index ac39e4e..d11e2be 100644
--- a/fdts/tbbr_cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -190,12 +190,6 @@
 			hash = <&hw_config_hash>;
 		};
 
-		tb_fw_config {
-			image-id = <TB_FW_CONFIG_ID>;
-			parent = <&trusted_boot_fw_cert>;
-			hash = <&tb_fw_config_hash>;
-		};
-
 		scp_bl2_image {
 			image-id = <SCP_BL2_IMAGE_ID>;
 			parent = <&scp_fw_content_cert>;
diff --git a/fdts/tc.dts b/fdts/tc-base.dtsi
similarity index 67%
rename from fdts/tc.dts
rename to fdts/tc-base.dtsi
index 63f6c3d..2e03be2 100644
--- a/fdts/tc.dts
+++ b/fdts/tc-base.dtsi
@@ -4,15 +4,37 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/dts-v1/;
+/* If SCMI power domain control is enabled */
+#if TC_SCMI_PD_CTRL_EN
+#define GPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 1)
+#define DPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 2)
+#endif /* TC_SCMI_PD_CTRL_EN */
+
+/* Use SCMI controlled clocks */
+#if TC_DPU_USE_SCMI_CLK
+#define DPU_CLK_ATTR1								\
+	clocks = <&scmi_clk 0>;							\
+	clock-names = "aclk"
+
+#define DPU_CLK_ATTR2								\
+	clocks = <&scmi_clk 1>;							\
+	clock-names = "pxclk"
 
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include "platform_def.h"
-#include "tc_vers.dtsi"
-#if TARGET_FLAVOUR_FVP
-#include "tc_fvp.dtsi"
-#endif /* TARGET_FLAVOUR_FVP */
+#define DPU_CLK_ATTR3								\
+	clocks = <&scmi_clk 2>;							\
+	clock-names = "pxclk"							\
+/* Use fixed clocks */
+#else /* !TC_DPU_USE_SCMI_CLK */
+#define DPU_CLK_ATTR1								\
+	clocks = <&dpu_aclk>;							\
+	clock-names = "aclk"
+
+#define DPU_CLK_ATTR2								\
+	clocks = <&dpu_pixel_clk>, <&dpu_aclk>;					\
+	clock-names = "pxclk", "aclk"
+
+#define DPU_CLK_ATTR3 DPU_CLK_ATTR2
+#endif /* !TC_DPU_USE_SCMI_CLK */
 
 / {
 	compatible = "arm,tc";
@@ -25,7 +47,6 @@
 	};
 
 	chosen {
-		stdout-path = STDOUT_PATH;
 		/*
 		 * Add some dummy entropy for Linux so it
 		 * doesn't delay the boot waiting for it.
@@ -70,26 +91,6 @@
 				core7 {
 					cpu = <&CPU7>;
 				};
-#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
-				core8 {
-					cpu = <&CPU8>;
-				};
-				core9 {
-					cpu = <&CPU9>;
-				};
-				core10 {
-					cpu = <&CPU10>;
-				};
-				core11 {
-					cpu = <&CPU11>;
-				};
-				core12 {
-					cpu = <&CPU12>;
-				};
-				core13 {
-					cpu = <&CPU13>;
-				};
-#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 			};
 		};
 
@@ -170,13 +171,6 @@
 			reg = <0x200>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-#if TARGET_PLATFORM <= 2
-			clocks = <&scmi_dvfs 0>;
-			capacity-dmips-mhz = <LIT_CAPACITY>;
-#elif TARGET_PLATFORM == 3
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-#endif /* TARGET_PLATFORM == 3 */
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -187,13 +181,6 @@
 			reg = <0x300>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-#if TARGET_PLATFORM <= 2
-			clocks = <&scmi_dvfs 0>;
-			capacity-dmips-mhz = <LIT_CAPACITY>;
-#elif TARGET_PLATFORM == 3
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-#endif /* TARGET_PLATFORM == 3 */
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -228,13 +215,6 @@
 			reg = <0x600>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-#if TARGET_PLATFORM <= 2
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-#elif TARGET_PLATFORM == 3
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-#endif /* TARGET_PLATFORM == 3 */
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -245,84 +225,9 @@
 			reg = <0x700>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-#else
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
-		CPU8:cpu@800 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x800>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU9:cpu@900 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x900>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG2_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU10:cpu@A00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xA00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG2_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU11:cpu@B00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xB00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG2_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU12:cpu@C00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xC00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 3>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU13:cpu@D00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xD00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 3>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
 			amu = <&amu>;
 			supports-mpmm;
 		};
-#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 	};
 
 	reserved-memory {
@@ -363,13 +268,6 @@
 	cpu-pmu {
 		compatible = "arm,armv8-pmuv3";
 		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
-				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>
-#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
-				    ,<&CPU8>,  <&CPU9>,  <&CPU10>, <&CPU11>,
-				     <&CPU12>, <&CPU13>
-#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
-		;
 	};
 
 	sram: sram@6000000 {
@@ -380,58 +278,54 @@
 		#size-cells = <1>;
 		ranges = <0 0x0 PLAT_ARM_NSRAM_BASE PLAT_ARM_NSRAM_SIZE>;
 
-		cpu_scp_scmi_mem: scp-shmem@0 {
+		cpu_scp_scmi_a2p: scp-shmem@0 {
 			compatible = "arm,scmi-shmem";
 			reg = <0x0 0x80>;
 		};
 	};
 
-	mbox_db_rx: mhu@MHU_RX_ADDR() {
-		compatible = "arm,mhuv2-rx","arm,primecell";
-		reg = <0x0 MHU_RX_ADDR(0x) 0x0 0x1000>;
+	mbox_db_rx: mhu@MHU_RX_ADDR {
+		compatible = MHU_RX_COMPAT;
+		reg = <0x0 ADDRESSIFY(MHU_RX_ADDR) 0x0 MHU_OFFSET>;
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
-		#mbox-cells = <2>;
-		interrupts = <GIC_SPI INT_MBOX_RX IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "mhu_rx";
-		mhu-protocol = "doorbell";
-		arm,mhuv2-protocols = <0 1>;
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = MHU_RX_INT_NAME;
 	};
 
-	mbox_db_tx: mhu@MHU_TX_ADDR() {
-		compatible = "arm,mhuv2-tx","arm,primecell";
-		reg = <0x0 MHU_TX_ADDR(0x) 0x0 0x1000>;
+	mbox_db_tx: mhu@MHU_TX_ADDR {
+		compatible = MHU_TX_COMPAT;
+		reg = <0x0 ADDRESSIFY(MHU_TX_ADDR) 0x0 MHU_OFFSET>;
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
-		#mbox-cells = <2>;
-		interrupt-names = "mhu_tx";
-		mhu-protocol = "doorbell";
-		arm,mhuv2-protocols = <0 1>;
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupt-names = MHU_TX_INT_NAME;
 	};
 
-	scmi {
-		compatible = "arm,scmi";
-		mbox-names = "tx", "rx";
-		mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0 >;
-		shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>;
-		#address-cells = <1>;
-		#size-cells = <0>;
+	firmware {
+		scmi {
+			compatible = "arm,scmi";
+			mbox-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 #if TC_SCMI_PD_CTRL_EN
-		scmi_devpd: protocol@11 {
-			reg = <0x11>;
-			#power-domain-cells = <1>;
-		};
+			scmi_devpd: protocol@11 {
+				reg = <0x11>;
+				#power-domain-cells = <1>;
+			};
 #endif /* TC_SCMI_PD_CTRL_EN */
 
-		scmi_dvfs: protocol@13 {
-			reg = <0x13>;
-			#clock-cells = <1>;
-		};
+			scmi_dvfs: protocol@13 {
+				reg = <0x13>;
+				#clock-cells = <1>;
+			};
 
-		scmi_clk: protocol@14 {
-			reg = <0x14>;
-			#clock-cells = <1>;
+			scmi_clk: protocol@14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
 		};
 	};
 
@@ -486,6 +380,22 @@
 		status = "okay";
 	};
 
+#if !TC_DPU_USE_SCMI_CLK
+	dpu_aclk: dpu_aclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-output-names = "fpga:dpu_aclk";
+	};
+
+	dpu_pixel_clk: dpu-pixel-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-output-names = "pxclk";
+	};
+#endif /* !TC_DPU_USE_SCMI_CLK */
+
 	vencoder {
 		compatible = "drm,virtual-encoder";
 		port {
@@ -502,13 +412,10 @@
 
 	};
 
-	ethernet@18000000 {
-		compatible = ETH_COMPATIBLE;
+	ethernet: ethernet@18000000 {
 		reg = <0x0 0x18000000 0x0 0x10000>;
 		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
 
-		/* FPGA only but will work on FVP. Keep for simplicity */
-		phy-mode = "mii";
 		reg-io-width = <2>;
 		smsc,irq-push-pull;
 	};
@@ -536,12 +443,11 @@
 		regulator-always-on;
 	};
 
-	mmci@1c050000 {
+	mmci: mmci@1c050000 {
 		compatible = "arm,pl180", "arm,primecell";
 		reg = <0x0 0x001c050000 0x0 0x1000>;
 		interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-		MMC_REMOVABLE;
 		wp-gpios = <&sysreg 1 0>;
 		bus-width = <4>;
 		max-frequency = <25000000>;
@@ -576,9 +482,14 @@
 		scmi-perf-domain = <3>;
 #endif /* TC_SCMI_PD_CTRL_EN */
 
-#if TC_IOMMU_EN
-		iommus = <&smmu_700 0x200>;
-#endif /* TC_IOMMU_EN */
+		pbha {
+			int-id-override = <0 0x22>, <2 0x23>, <4 0x23>, <7 0x22>,
+					  <8 0x22>, <9 0x22>, <10 0x22>, <11 0x22>,
+					  <12 0x22>, <13 0x22>, <16 0x22>, <17 0x32>,
+					  <18 0x32>, <19 0x22>, <20 0x22>, <21 0x32>,
+					  <22 0x32>, <24 0x22>, <28 0x32>;
+			propagate-bits = <0x0f>;
+		};
 	};
 
 	power_model_simple {
@@ -593,7 +504,18 @@
 		thermal-zone = "";
 	};
 
-#if TC_IOMMU_EN
+	smmu_600: smmu@2ce00000 {
+		compatible = "arm,smmu-v3";
+		reg = <0 0x2ce00000 0 0x20000>;
+		interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 76 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 77 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+		#iommu-cells = <1>;
+		status = "disabled";
+	};
+
 	smmu_700: iommu@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
@@ -603,23 +525,29 @@
 			     <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>;
 		interrupt-names = "eventq", "cmdq-sync", "gerror";
 		dma-coherent;
+		status = "disabled";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		#iommu-cells = <1>;
+		compatible = "arm,smmu-v3";
+		reg = <HI(0x4002a00000) LO(0x4002a00000) 0x0 0x5000000>;
+		interrupts = <GIC_SPI 481 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 482 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 483 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "eventq", "cmdq-sync", "gerror";
+		dma-coherent;
+		status = "disabled";
 	};
-#endif /* TC_IOMMU_EN */
 
-	dp0: display@DPU_ADDR() {
+	dp0: display@DPU_ADDR {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "arm,mali-d71";
-		reg = <HI(DPU_ADDR(0x)) LO(DPU_ADDR(0x)) 0 0x20000>;
+		reg = <HI(ADDRESSIFY(DPU_ADDR)) LO(ADDRESSIFY(DPU_ADDR)) 0 0x20000>;
 		interrupts = <GIC_SPI DPU_IRQ IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "DPU";
 		DPU_CLK_ATTR1;
-#if TC_IOMMU_EN
-		iommus = <&smmu_700 0x100>;
-#endif /* TC_IOMMU_EN */
-#if  TC_SCMI_PD_CTRL_EN && (TARGET_PLATFORM != 3)
-		power-domains = <&scmi_devpd DPU_SCMI_PD_IDX>;
-#endif /*  TC_SCMI_PD_CTRL_EN && (TARGET_PLATFORM != 3) */
 
 		pl0: pipeline@0 {
 			reg = <0>;
@@ -699,38 +627,6 @@
 		compatible = "arm,embedded-trace-extension";
 		cpu = <&CPU7>;
 	};
-
-#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
-	ete8 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU8>;
-	};
-
-	ete9 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU9>;
-	};
-
-	ete10 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU10>;
-	};
-
-	ete11 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU11>;
-	};
-
-	ete12 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU12>;
-	};
-
-	ete13 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU13>;
-	};
-#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 
 	trbe {
 		compatible = "arm,trace-buffer-extension";
diff --git a/fdts/tc-common.dtsi b/fdts/tc-common.dtsi
new file mode 100644
index 0000000..c331193
--- /dev/null
+++ b/fdts/tc-common.dtsi
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define PASTER(x, y)		x ## y
+#define EVALUATOR(x, y)		PASTER(x, y)
+#define ADDRESSIFY(addr)	EVALUATOR(0x, addr)
diff --git a/fdts/tc-fpga.dtsi b/fdts/tc-fpga.dtsi
new file mode 100644
index 0000000..73f4743
--- /dev/null
+++ b/fdts/tc-fpga.dtsi
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define GIC_CTRL_ADDR		30000000
+#define GIC_GICR_OFFSET		0x1000000
+#define UART_OFFSET		0x10000
+/* 1440x3200@120 framebuffer */
+#define VENCODER_TIMING_CLK 836000000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <1440>;							\
+	vactive = <3200>;							\
+	hfront-porch = <136>;							\
+	hback-porch = <296>;							\
+	hsync-len = <160>;							\
+	vfront-porch = <3>;							\
+	vback-porch = <217>;							\
+	vsync-len = <10>
+
+/ {
+	chosen {
+		stdout-path = "serial0:38400n8";
+	};
+
+	ethernet: ethernet@18000000 {
+		compatible = "smsc,lan9115";
+		phy-mode = "mii";
+	};
+
+	mmci: mmci@1c050000 {
+		non-removable;
+	};
+};
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
new file mode 100644
index 0000000..9f3a9ac
--- /dev/null
+++ b/fdts/tc-fvp.dtsi
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define GIC_CTRL_ADDR		2c010000
+#define GIC_GICR_OFFSET		0x200000
+#define UART_OFFSET		0x1000
+
+#ifdef TC_RESOLUTION_1920X1080P60
+
+#define VENCODER_TIMING_CLK 148500000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <1920>;							\
+	vactive = <1080>;							\
+	hfront-porch = <88>;							\
+	hback-porch = <148>;							\
+	hsync-len = <44>;							\
+	vfront-porch = <4>;							\
+	vback-porch = <36>;							\
+	vsync-len = <5>
+
+#else /* TC_RESOLUTION_640X480P60 */
+
+#define VENCODER_TIMING_CLK 25175000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <640>;							\
+	vactive = <480>;							\
+	hfront-porch = <16>;							\
+	hback-porch = <48>;							\
+	hsync-len = <96>;							\
+	vfront-porch = <10>;							\
+	vback-porch = <33>;							\
+	vsync-len = <2>
+
+#endif
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	ethernet: ethernet@18000000 {
+		compatible = "smsc,lan91c111";
+	};
+
+	mmci: mmci@1c050000 {
+		cd-gpios = <&sysreg 0 0>;
+	};
+
+	rtc@1c170000 {
+		compatible = "arm,pl031", "arm,primecell";
+		reg = <0x0 0x1C170000 0x0 0x1000>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&soc_refclk>;
+		clock-names = "apb_pclk";
+	};
+
+	kmi@1c060000 {
+		compatible = "arm,pl050", "arm,primecell";
+		reg = <0x0 0x001c060000 0x0 0x1000>;
+		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "KMIREFCLK", "apb_pclk";
+	};
+
+	kmi@1c070000 {
+		compatible = "arm,pl050", "arm,primecell";
+		reg = <0x0 0x001c070000 0x0 0x1000>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "KMIREFCLK", "apb_pclk";
+	};
+
+	virtio_block@1c130000 {
+		compatible = "virtio,mmio";
+		reg = <0x0 0x1c130000 0x0 0x200>;
+		/* spec lists this wrong */
+		interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
new file mode 100644
index 0000000..4946aca
--- /dev/null
+++ b/fdts/tc2.dts
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <platform_def.h>
+
+#if TARGET_FLAVOUR_FVP
+#define LIT_CAPACITY			406
+#define MID_CAPACITY			912
+#else /* TARGET_FLAVOUR_FPGA */
+#define LIT_CAPACITY			280
+#define MID_CAPACITY			775
+/* this is an area optimized configuration of the big core */
+#define BIG2_CAPACITY			930
+#endif /* TARGET_FLAVOUR_FPGA */
+#define BIG_CAPACITY			1024
+
+#define MHU_TX_ADDR			45000000 /* hex */
+#define MHU_TX_COMPAT			"arm,mhuv2-tx","arm,primecell"
+#define MHU_TX_INT_NAME			"mhu_tx"
+
+#define MHU_RX_ADDR			45010000 /* hex */
+#define MHU_RX_COMPAT			"arm,mhuv2-rx","arm,primecell"
+#define MHU_OFFSET			0x1000
+#define MHU_MBOX_CELLS			2
+#define MHU_RX_INT_NUM			317
+#define MHU_RX_INT_NAME			"mhu_rx"
+
+#define MPAM_ADDR			0x1 0x00010000 /* 0x1_0001_0000 */
+#define UARTCLK_FREQ			5000000
+
+#define DPU_ADDR			2cc00000
+#define DPU_IRQ				69
+
+#include "tc-common.dtsi"
+#if TARGET_FLAVOUR_FVP
+#include "tc-fvp.dtsi"
+#else
+#include "tc-fpga.dtsi"
+#endif /* TARGET_FLAVOUR_FVP */
+#include "tc-base.dtsi"
+
+/ {
+	cpus {
+#if TARGET_FLAVOUR_FPGA
+		cpu-map {
+			cluster0 {
+				core8 {
+					cpu = <&CPU8>;
+				};
+				core9 {
+					cpu = <&CPU9>;
+				};
+				core10 {
+					cpu = <&CPU10>;
+				};
+				core11 {
+					cpu = <&CPU11>;
+				};
+				core12 {
+					cpu = <&CPU12>;
+				};
+				core13 {
+					cpu = <&CPU13>;
+				};
+			};
+		};
+#endif
+
+		CPU2:cpu@200 {
+			clocks = <&scmi_dvfs 0>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
+		};
+
+		CPU3:cpu@300 {
+			clocks = <&scmi_dvfs 0>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
+		};
+
+		CPU6:cpu@600 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU7:cpu@700 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+#if TARGET_FLAVOUR_FPGA
+		CPU8:cpu@800 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x800>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU9:cpu@900 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x900>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU10:cpu@A00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xA00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU11:cpu@B00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xB00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU12:cpu@C00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xC00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 3>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU13:cpu@D00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xD00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 3>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+#endif
+	};
+
+#if TARGET_FLAVOUR_FPGA
+	ete8 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU8>;
+	};
+
+	ete9 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU9>;
+	};
+
+	ete10 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU10>;
+	};
+
+	ete11 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU11>;
+	};
+
+	ete12 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU12>;
+	};
+
+	ete13 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU13>;
+	};
+#endif /* TARGET_FLAVOUR_FPGA */
+
+	cpu-pmu {
+#if TARGET_FLAVOUR_FPGA
+		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
+				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>,
+				     <&CPU8>,  <&CPU9>,  <&CPU10>, <&CPU11>,
+				     <&CPU12>, <&CPU13>;
+#else
+		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
+				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>;
+#endif
+	};
+
+	cmn-pmu {
+		compatible = "arm,ci-700";
+		reg = <0x0 0x50000000 0x0 0x10000000>;
+		interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	mbox_db_rx: mhu@MHU_RX_ADDR {
+		arm,mhuv2-protocols = <0 1>;
+	};
+
+	mbox_db_tx: mhu@MHU_TX_ADDR {
+		arm,mhuv2-protocols = <0 1>;
+	};
+
+	firmware {
+		/*
+		 * TC2 does not have a P2A channel, but wiring one was needed to make Linux work
+		 * (by chance). At the time the SCMI driver did not support bidirectional
+		 * mailboxes so as a workaround, the A2P channel was wired for TX communication
+		 * and the synchronous replies would be read asyncrhonously as if coming from
+		 * the P2A channel, while being the actual A2P channel.
+		 *
+		 * This will not work with kernels > 5.15, but keep it around to keep TC2
+		 * working with its target kernel. Newer kernels will still work, but SCMI
+		 * won't as they check that the two regions are distinct.
+		 */
+		scmi {
+			mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0>;
+			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_a2p>;
+		};
+	};
+
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	dp0: display@DPU_ADDR {
+#if TC_SCMI_PD_CTRL_EN
+		power-domains = <&scmi_devpd (PLAT_MAX_CPUS_PER_CLUSTER + 2)>;
+#endif
+		iommus = <&smmu_700 0x100>;
+	};
+
+	gpu: gpu@2d000000 {
+		iommus = <&smmu_700 0x200>;
+	};
+};
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
new file mode 100644
index 0000000..c741be0
--- /dev/null
+++ b/fdts/tc3.dts
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <platform_def.h>
+
+#define LIT_CAPACITY			239
+#define MID_CAPACITY			686
+#define BIG_CAPACITY			1024
+
+#define MHU_TX_ADDR			46040000 /* hex */
+#define MHU_TX_COMPAT			"arm,mhuv3"
+#define MHU_TX_INT_NAME			""
+
+#define MHU_RX_ADDR			46140000 /* hex */
+#define MHU_RX_COMPAT			"arm,mhuv3"
+#define MHU_OFFSET			0x10000
+#define MHU_MBOX_CELLS			3
+#define MHU_RX_INT_NUM			300
+#define MHU_RX_INT_NAME			"combined-mbx"
+
+#define MPAM_ADDR			0x0 0x5f010000 /* 0x5f01_0000 */
+#define UARTCLK_FREQ			3750000
+
+#if TARGET_FLAVOUR_FVP
+#define DPU_ADDR			4000000000
+#define DPU_IRQ				579
+#elif TARGET_FLAVOUR_FPGA
+#define DPU_ADDR			2cc00000
+#define DPU_IRQ				69
+#endif
+
+#include "tc-common.dtsi"
+#if TARGET_FLAVOUR_FVP
+#include "tc-fvp.dtsi"
+#else
+#include "tc-fpga.dtsi"
+#endif /* TARGET_FLAVOUR_FVP */
+#include "tc-base.dtsi"
+
+/ {
+	cpus {
+		CPU2:cpu@200 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU3:cpu@300 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU6:cpu@600 {
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+		};
+
+		CPU7:cpu@700 {
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+		};
+	};
+
+	cpu-pmu {
+		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
+				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>;
+	};
+
+	cs-pmu@0 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
+	};
+
+	cs-pmu@1 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(1) 0x0 0xffc>;
+	};
+
+	cs-pmu@2 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(2) 0x0 0xffc>;
+	};
+
+	cs-pmu@3 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
+	};
+
+	sram: sram@6000000 {
+		cpu_scp_scmi_p2a: scp-shmem@80 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x80 0x80>;
+		};
+	};
+
+	firmware {
+		scmi {
+			mboxes = <&mbox_db_tx 0 0 0 &mbox_db_rx 0 0 0 &mbox_db_rx 0 0 1>;
+			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_p2a>;
+		};
+	};
+
+#if TARGET_FLAVOUR_FVP
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		status = "okay";
+	};
+#else
+	smmu_600: smmu@2ce00000 {
+		status = "okay";
+	};
+#endif
+
+	dp0: display@DPU_ADDR {
+#if TARGET_FLAVOUR_FVP
+		iommus = <&smmu_700_dpu 0x000>, <&smmu_700_dpu 0x100>,
+			 <&smmu_700_dpu 0x200>, <&smmu_700_dpu 0x600>;
+#else /* TARGET_FLAVOUR_FPGA */
+		iommus = <&smmu_600 0>, <&smmu_600 1>, <&smmu_600 2>, <&smmu_600 3>,
+			 <&smmu_600 4>, <&smmu_600 5>, <&smmu_600 6>, <&smmu_600 7>,
+			 <&smmu_600 8>, <&smmu_600 9>;
+#endif
+	};
+
+	gpu: gpu@2d000000 {
+#if TARGET_FLAVOUR_FVP
+		iommus = <&smmu_700 0x200>;
+#endif
+	};
+};
diff --git a/fdts/tc_fvp.dtsi b/fdts/tc_fvp.dtsi
deleted file mode 100644
index 42f3818..0000000
--- a/fdts/tc_fvp.dtsi
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/ {
-	rtc@1c170000 {
-		compatible = "arm,pl031", "arm,primecell";
-		reg = <0x0 0x1C170000 0x0 0x1000>;
-		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&soc_refclk>;
-		clock-names = "apb_pclk";
-	};
-
-	kmi@1c060000 {
-		compatible = "arm,pl050", "arm,primecell";
-		reg = <0x0 0x001c060000 0x0 0x1000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
-		clock-names = "KMIREFCLK", "apb_pclk";
-	};
-
-	kmi@1c070000 {
-		compatible = "arm,pl050", "arm,primecell";
-		reg = <0x0 0x001c070000 0x0 0x1000>;
-		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
-		clock-names = "KMIREFCLK", "apb_pclk";
-	};
-
-	virtio_block@1c130000 {
-		compatible = "virtio,mmio";
-		reg = <0x0 0x1c130000 0x0 0x200>;
-		/* spec lists this wrong */
-		interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
-	};
-};
diff --git a/fdts/tc_vers.dtsi b/fdts/tc_vers.dtsi
deleted file mode 100644
index 43fafd5..0000000
--- a/fdts/tc_vers.dtsi
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-
-/* If SCMI power domain control is enabled */
-#if TC_SCMI_PD_CTRL_EN
-#define GPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 1)
-#define DPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 2)
-#endif /* TC_SCMI_PD_CTRL_EN */
-
-/* All perf is normalized against the big core */
-#define BIG_CAPACITY		1024
-
-#if TARGET_PLATFORM <= 2
-#if TARGET_FLAVOUR_FVP
-#define LIT_CAPACITY		406
-#define MID_CAPACITY		912
-#else /* TARGET_FLAVOUR_FPGA */
-#define LIT_CAPACITY		280
-#define MID_CAPACITY		775
-/* this is an area optimized configuration of the big core */
-#define BIG2_CAPACITY		930
-#endif /* TARGET_FLAVOUR_FPGA */
-
-#define INT_MBOX_RX		317
-#define MHU_TX_ADDR(pref)	pref##45000000 /* hex */
-#define MHU_RX_ADDR(pref)	pref##45010000 /* hex */
-#define MPAM_ADDR		0x1 0x00010000 /* 0x1_0001_0000 */
-#define UARTCLK_FREQ		5000000
-#elif TARGET_PLATFORM == 3
-
-#define LIT_CAPACITY		239
-#define MID_CAPACITY		686
-
-#define INT_MBOX_RX		300
-#define MHU_TX_ADDR(pref)	pref##46040000 /* hex */
-#define MHU_RX_ADDR(pref)	pref##46140000 /* hex */
-#define MPAM_ADDR		0x0 0x5f010000 /* 0x5f01_0000 */
-#define UARTCLK_FREQ		3750000
-#endif /* TARGET_PLATFORM == 3 */
-
-#if TARGET_FLAVOUR_FVP
-#define STDOUT_PATH		"serial0:115200n8"
-#define GIC_CTRL_ADDR		2c010000
-#define GIC_GICR_OFFSET		0x200000
-#define UART_OFFSET		0x1000
-#define VENCODER_TIMING_CLK 25175000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
-	hactive = <640>;							\
-	vactive = <480>;							\
-	hfront-porch = <16>;							\
-	hback-porch = <48>;							\
-	hsync-len = <96>;							\
-	vfront-porch = <10>;							\
-	vback-porch = <33>;							\
-	vsync-len = <2>
-#define ETH_COMPATIBLE		"smsc,lan91c111"
-#define MMC_REMOVABLE		cd-gpios = <&sysreg 0 0>
-#if TARGET_PLATFORM <= 2
-#define DPU_ADDR(pref)		pref##2cc00000
-#define DPU_IRQ			69
-#else /* TARGET_PLATFORM >= 3 */
-#define DPU_ADDR(pref)		pref##4000000000
-#define DPU_IRQ			579
-#endif /* TARGET_PLATFORM >= 3 */
-
-#else /* TARGET_FLAVOUR_FPGA */
-
-#define STDOUT_PATH		"serial0:38400n8"
-#define GIC_CTRL_ADDR		30000000
-#define GIC_GICR_OFFSET		0x1000000
-#define UART_OFFSET		0x10000
-/* 1440x3200@120 framebuffer */
-#define VENCODER_TIMING_CLK 836000000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
-	hactive = <1440>;							\
-	vactive = <3200>;							\
-	hfront-porch = <136>;							\
-	hback-porch = <296>;							\
-	hsync-len = <160>;							\
-	vfront-porch = <3>;							\
-	vback-porch = <217>;							\
-	vsync-len = <10>
-#define ETH_COMPATIBLE		"smsc,lan9115"
-#define MMC_REMOVABLE		non-removable
-#define DPU_ADDR(pref)		pref##2cc00000
-#define DPU_IRQ			69
-#endif /* TARGET_FLAVOUR_FPGA */
-
-/* Use SCMI controlled clocks */
-#if TC_DPU_USE_SCMI_CLK
-#define DPU_CLK_ATTR1								\
-	clocks = <&scmi_clk 0>;							\
-	clock-names = "aclk"
-
-#define DPU_CLK_ATTR2								\
-	clocks = <&scmi_clk 1>;							\
-	clock-names = "pxclk"
-
-#define DPU_CLK_ATTR3								\
-	clocks = <&scmi_clk 2>;							\
-	clock-names = "pxclk"							\
-/* Use fixed clocks */
-#else /* !TC_DPU_USE_SCMI_CLK */
-#define DPU_CLK_ATTR1								\
-	clocks = <&dpu_aclk>;							\
-	clock-names = "aclk"
-
-#define DPU_CLK_ATTR2								\
-	clocks = <&dpu_pixel_clk>, <&dpu_aclk>;					\
-	clock-names = "pxclk", "aclk"
-
-#define DPU_CLK_ATTR3 DPU_CLK_ATTR2
-#endif /* !TC_DPU_USE_SCMI_CLK */
-
-/ {
-#if TARGET_PLATFORM <= 2
-	cmn-pmu {
-		compatible = "arm,ci-700";
-		reg = <0x0 0x50000000 0x0 0x10000000>;
-		interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>;
-	};
-#endif /* TARGET_PLATFORM <= 2 */
-
-#if !TC_DPU_USE_SCMI_CLK
-	dpu_aclk: dpu_aclk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <VENCODER_TIMING_CLK>;
-		clock-output-names = "fpga:dpu_aclk";
-	};
-
-	dpu_pixel_clk: dpu-pixel-clk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <VENCODER_TIMING_CLK>;
-		clock-output-names = "pxclk";
-	};
-#endif /* !TC_DPU_USE_SCMI_CLK */
-};
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 7e759d81..d32ead4 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -111,18 +111,18 @@
 #define ID_DFR0_PERFMON_PMUV3P5		U(6)
 #define ID_DFR0_COPTRC_SHIFT		U(12)
 #define ID_DFR0_COPTRC_MASK		U(0xf)
-#define ID_DFR0_COPTRC_SUPPORTED	U(1)
+#define COPTRC_IMPLEMENTED		U(1)
 #define ID_DFR0_COPTRC_LENGTH		U(4)
 #define ID_DFR0_TRACEFILT_SHIFT		U(28)
 #define ID_DFR0_TRACEFILT_MASK		U(0xf)
-#define ID_DFR0_TRACEFILT_SUPPORTED	U(1)
+#define TRACEFILT_IMPLEMENTED		U(1)
 #define ID_DFR0_TRACEFILT_LENGTH	U(4)
 
 /* ID_DFR1_EL1 definitions */
 #define ID_DFR1_MTPMU_SHIFT	U(0)
 #define ID_DFR1_MTPMU_MASK	U(0xf)
-#define ID_DFR1_MTPMU_SUPPORTED	U(1)
-#define ID_DFR1_MTPMU_DISABLED	U(15)
+#define MTPMU_IMPLEMENTED	U(1)
+#define MTPMU_NOT_IMPLEMENTED	U(15)
 
 /* ID_MMFR3 definitions */
 #define ID_MMFR3_PAN_SHIFT	U(16)
@@ -141,14 +141,13 @@
 #define ID_PFR0_AMU_SHIFT	U(20)
 #define ID_PFR0_AMU_LENGTH	U(4)
 #define ID_PFR0_AMU_MASK	U(0xf)
-#define ID_PFR0_AMU_NOT_SUPPORTED	U(0x0)
 #define ID_PFR0_AMU_V1		U(0x1)
 #define ID_PFR0_AMU_V1P1	U(0x2)
 
 #define ID_PFR0_DIT_SHIFT	U(24)
 #define ID_PFR0_DIT_LENGTH	U(4)
 #define ID_PFR0_DIT_MASK	U(0xf)
-#define ID_PFR0_DIT_SUPPORTED	(U(1) << ID_PFR0_DIT_SHIFT)
+#define DIT_IMPLEMENTED		(U(1) << ID_PFR0_DIT_SHIFT)
 
 /* ID_PFR1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -166,7 +165,7 @@
 /* ID_PFR2 definitions */
 #define ID_PFR2_SSBS_SHIFT	U(4)
 #define ID_PFR2_SSBS_MASK	U(0xf)
-#define SSBS_UNAVAILABLE	U(0)
+#define SSBS_NOT_IMPLEMENTED	U(0)
 
 /* SCTLR definitions */
 #define SCTLR_RES1_DEF		((U(1) << 23) | (U(1) << 22) | (U(1) << 4) | \
@@ -796,7 +795,21 @@
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
-#define CLUSTERPWRDN	p15, 0, c15, c3, 6
+#define CLUSTERPWRDN		p15, 0, c15, c3, 6
+#define CLUSTERPMCR		p15, 0, c15, c5, 0
+#define CLUSTERPMCNTENSET	p15, 0, c15, c5, 1
+#define CLUSTERPMCCNTR		p15, 0, c15, c6, 0
+#define CLUSTERPMOVSSET		p15, 0, c15, c5, 3
+#define CLUSTERPMOVSCLR		p15, 0, c15, c5, 4
+#define CLUSTERPMSELR		p15, 0, c15, c5, 5
+#define CLUSTERPMXEVTYPER	p15, 0,	c15, c6, 1
+#define CLUSTERPMXEVCNTR	p15, 0, c15, c6, 2
+
+/* CLUSTERPMCR register definitions */
+#define CLUSTERPMCR_E_BIT	BIT(0)
+#define CLUSTERPMCR_N_SHIFT	U(11)
+#define CLUSTERPMCR_N_MASK	U(0x1f)
+
 
 /* CLUSTERPWRDN register definitions */
 #define DSU_CLUSTER_PWR_OFF	0
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index 734a6b5..8e39529 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -12,132 +12,112 @@
 #include <arch_helpers.h>
 #include <common/feat_detect.h>
 
-#define ISOLATE_FIELD(reg, feat)					\
-	((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
+#define ISOLATE_FIELD(reg, feat, mask)						\
+	((unsigned int)(((reg) >> (feat)) & mask))
 
-static inline bool is_armv7_gentimer_present(void)
-{
-	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER) != 0U;
-}
-
-static inline bool is_armv8_2_ttcnp_present(void)
-{
-	return ISOLATE_FIELD(read_id_mmfr4(), ID_MMFR4_CNP) != 0U;
-}
-
-static unsigned int read_feat_amu_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_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_PFR0_AMU_V1;
+#define CREATE_FEATURE_SUPPORTED(name, read_func, 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();							\
 }
 
-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_PFR0_AMU_V1P1;
+#define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
+static inline bool is_ ## name ## _present(void)				\
+{										\
+	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
+		? true : false;							\
 }
 
-static inline unsigned int read_feat_trf_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_TRACEFILT);
-}
-
-static inline bool is_feat_trf_supported(void)
-{
-	if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
+#define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard)		\
+CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)			\
+CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
 
-	if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
 
-	return read_feat_trf_id_field() != 0U;
-}
-
-static inline unsigned int read_feat_coptrc_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_COPTRC);
-}
+/*
+ * +----------------------------+
+ * |	Features supported	|
+ * +----------------------------+
+ * |	GENTIMER		|
+ * +----------------------------+
+ * |	FEAT_TTCNP		|
+ * +----------------------------+
+ * |	FEAT_AMU		|
+ * +----------------------------+
+ * |	FEAT_AMUV1P1		|
+ * +----------------------------+
+ * |	FEAT_TRF		|
+ * +----------------------------+
+ * |	FEAT_SYS_REG_TRACE 	|
+ * +----------------------------+
+ * |	FEAT_DIT		|
+ * +----------------------------+
+ * |	FEAT_PAN		|
+ * +----------------------------+
+ * |	FEAT_SSBS		|
+ * +----------------------------+
+ * |	FEAT_PMUV3		|
+ * +----------------------------+
+ * |	FEAT_MTPMU		|
+ * +----------------------------+
+ */
 
-static inline bool is_feat_sys_reg_trace_supported(void)
+/* GENTIMER */
+static inline bool is_armv7_gentimer_present(void)
 {
-	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_coptrc_id_field() != 0U;
+	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER_SHIFT,
+			    ID_PFR1_GENTIMER_MASK) != 0U;
 }
 
-static inline unsigned int read_feat_dit_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT);
-}
+/* FEAT_TTCNP: Translation table common not private */
+CREATE_FEATURE_PRESENT(feat_ttcnp, id_mmfr4, ID_MMFR4_CNP_SHIFT,
+		      ID_MMFR4_CNP_MASK, 1U)
 
-static inline bool is_feat_dit_supported(void)
-{
-	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_AMU: Activity Monitors Extension */
+CREATE_FEATURE_FUNCS(feat_amu, id_pfr0, ID_PFR0_AMU_SHIFT,
+		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1, ENABLE_FEAT_AMU)
 
-	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+/* FEAT_AMUV1P1: AMU Extension v1.1 */
+CREATE_FEATURE_FUNCS(feat_amuv1p1, id_pfr0, ID_PFR0_AMU_SHIFT,
+		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
 
-	return read_feat_dit_id_field() != 0U;
-}
+/* FEAT_TRF: Tracefilter */
+CREATE_FEATURE_FUNCS(feat_trf, id_dfr0, ID_DFR0_TRACEFILT_SHIFT,
+		    ID_DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS)
 
-static inline unsigned int read_feat_pan_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_mmfr3(), ID_MMFR3_PAN);
-}
+/* FEAT_SYS_REG_TRACE */
+CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_dfr0, ID_DFR0_COPTRC_SHIFT,
+		    ID_DFR0_COPTRC_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS)
 
-static inline bool is_feat_pan_supported(void)
-{
-	if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_DIT: Data independent timing */
+CREATE_FEATURE_FUNCS(feat_dit, id_pfr0, ID_PFR0_DIT_SHIFT,
+		    ID_PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT)
 
-	if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+/* FEAT_PAN: Privileged access never */
+CREATE_FEATURE_FUNCS(feat_pan, id_mmfr3, ID_MMFR3_PAN_SHIFT,
+		    ID_MMFR3_PAN_MASK, 1U, ENABLE_FEAT_PAN)
 
-	return read_feat_pan_id_field() != 0U;
-}
+/* FEAT_SSBS: Speculative store bypass safe */
+CREATE_FEATURE_PRESENT(feat_ssbs, id_pfr2, ID_PFR2_SSBS_SHIFT,
+		      ID_PFR2_SSBS_MASK, 1U)
 
-static inline bool is_feat_pan_present(void)
-{
-	return  read_feat_pan_id_field() != 0U;
-}
+/* FEAT_PMUV3 */
+CREATE_FEATURE_PRESENT(feat_pmuv3, id_dfr0, ID_DFR0_PERFMON_SHIFT,
+		      ID_DFR0_PERFMON_MASK, 3U)
 
-static inline unsigned int is_feat_ssbs_present(void)
+/* FEAT_MTPMU */
+static inline bool is_feat_mtpmu_present(void)
 {
-	return ((read_id_pfr2() >> ID_PFR2_SSBS_SHIFT) &
-		ID_PFR2_SSBS_MASK) != SSBS_UNAVAILABLE;
+	unsigned int mtpmu = ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU_SHIFT,
+			    ID_DFR1_MTPMU_MASK);
+	return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED);
 }
+CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU)
 
 /*
  * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch
@@ -159,7 +139,6 @@
 static inline bool is_feat_spe_supported(void) { return false; }
 static inline bool is_feat_rng_supported(void) { return false; }
 static inline bool is_feat_gcs_supported(void) { return false; }
-static inline bool is_feat_mte_supported(void) { return false; }
 static inline bool is_feat_mte2_supported(void) { return false; }
 static inline bool is_feat_mpam_supported(void) { return false; }
 static inline bool is_feat_hcx_supported(void) { return false; }
@@ -180,29 +159,4 @@
 static inline bool is_feat_ebep_present(void) { return false; }
 static inline bool is_feat_sebep_present(void) { return false; }
 
-static inline unsigned int read_feat_pmuv3_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_PERFMON);
-}
-
-static inline unsigned int read_feat_mtpmu_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU);
-}
-
-static inline bool is_feat_mtpmu_supported(void)
-{
-	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	unsigned int mtpmu = read_feat_mtpmu_id_field();
-
-	return mtpmu != 0U && mtpmu != ID_DFR1_MTPMU_DISABLED;
-}
-
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 3244d3b..adc96ae 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -354,6 +354,14 @@
  * DynamIQ Shared Unit power management
  */
 DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
+DEFINE_COPROCR_RW_FUNCS(clusterpmcr, CLUSTERPMCR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmcntenset, CLUSTERPMCNTENSET)
+DEFINE_COPROCR_RW_FUNCS(clusterpmccntr, CLUSTERPMCCNTR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmovsset, CLUSTERPMOVSSET)
+DEFINE_COPROCR_RW_FUNCS(clusterpmovsclr, CLUSTERPMOVSCLR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmselr, CLUSTERPMSELR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmxevcntr, CLUSTERPMXEVCNTR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmxevtyper, CLUSTERPMXEVTYPER)
 
 /*
  * RNDR is AArch64 only, so just provide a placeholder here to make the
diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index 3ba86e9..bccd2a7 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -241,4 +241,13 @@
 	cmp     \temp, \bot
 	bhs     div2
 	.endm
+
+	/*
+	 * Helper macro to instruction adr <reg>, <symbol> where <symbol> is
+	 * within the range +/- 4 GB.
+	 */
+	.macro adr_l, dst, sym
+	adrp	\dst, \sym
+	add	\dst, \dst, :lo12:\sym
+	.endm
 #endif /* ASM_MACROS_S */
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 697eb82..41eeabb 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,7 +76,7 @@
 	orr	r0, r0, #(NSACR_RESET_VAL | NSACR_ENABLE_FP_ACCESS)
 	ldcopr	r1, ID_DFR0
 	ubfx	r1, r1, #ID_DFR0_COPTRC_SHIFT, #ID_DFR0_COPTRC_LENGTH
-	cmp	r1, #ID_DFR0_COPTRC_SUPPORTED
+	cmp	r1, #COPTRC_IMPLEMENTED
 	bne	1f
 	orr	r0, r0, #NSTRCDIS_BIT
 1:
@@ -143,7 +143,7 @@
 		      SDCR_SCCD_BIT) & ~SDCR_TTRF_BIT)
 	ldcopr	r1, ID_DFR0
 	ubfx	r1, r1, #ID_DFR0_TRACEFILT_SHIFT, #ID_DFR0_TRACEFILT_LENGTH
-	cmp	r1, #ID_DFR0_TRACEFILT_SUPPORTED
+	cmp	r1, #TRACEFILT_IMPLEMENTED
 	bne	1f
 	orr	r0, r0, #SDCR_TTRF_BIT
 1:
@@ -182,7 +182,7 @@
 	 */
 	ldcopr	r0, ID_PFR0
 	and	r0, r0, #(ID_PFR0_DIT_MASK << ID_PFR0_DIT_SHIFT)
-	cmp	r0, #ID_PFR0_DIT_SUPPORTED
+	cmp	r0, #DIT_IMPLEMENTED
 	bne	1f
 	mrs	r0, cpsr
 	orr	r0, r0, #CPSR_DIT_BIT
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 8a4c071..df0dcc3 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -131,7 +131,6 @@
 #define MPAMVPM6_EL2		S3_4_C10_C6_6
 #define MPAMVPM7_EL2		S3_4_C10_C6_7
 #define MPAMVPMV_EL2		S3_4_C10_C4_1
-#define TRFCR_EL2		S3_4_C1_C2_1
 #define VNCR_EL2		S3_4_C2_C2_0
 #define PMSCR_EL2		S3_4_C9_C9_0
 #define TFSR_EL2		S3_4_C5_C6_0
@@ -180,7 +179,6 @@
 
 #define ID_AA64PFR0_AMU_SHIFT			U(44)
 #define ID_AA64PFR0_AMU_MASK			ULL(0xf)
-#define ID_AA64PFR0_AMU_NOT_SUPPORTED		U(0x0)
 #define ID_AA64PFR0_AMU_V1			ULL(0x1)
 #define ID_AA64PFR0_AMU_V1P1			U(0x2)
 
@@ -192,8 +190,8 @@
 
 #define ID_AA64PFR0_SVE_SHIFT			U(32)
 #define ID_AA64PFR0_SVE_MASK			ULL(0xf)
-#define ID_AA64PFR0_SVE_SUPPORTED		ULL(0x1)
 #define ID_AA64PFR0_SVE_LENGTH			U(4)
+#define SVE_IMPLEMENTED				ULL(0x1)
 
 #define ID_AA64PFR0_SEL2_SHIFT			U(36)
 #define ID_AA64PFR0_SEL2_MASK			ULL(0xf)
@@ -204,23 +202,21 @@
 #define ID_AA64PFR0_DIT_SHIFT			U(48)
 #define ID_AA64PFR0_DIT_MASK			ULL(0xf)
 #define ID_AA64PFR0_DIT_LENGTH			U(4)
-#define ID_AA64PFR0_DIT_SUPPORTED		U(1)
+#define DIT_IMPLEMENTED				ULL(1)
 
 #define ID_AA64PFR0_CSV2_SHIFT			U(56)
 #define ID_AA64PFR0_CSV2_MASK			ULL(0xf)
 #define ID_AA64PFR0_CSV2_LENGTH			U(4)
-#define ID_AA64PFR0_CSV2_2_SUPPORTED		ULL(0x2)
-#define ID_AA64PFR0_CSV2_3_SUPPORTED		ULL(0x3)
+#define CSV2_2_IMPLEMENTED			ULL(0x2)
+#define CSV2_3_IMPLEMENTED			ULL(0x3)
 
 #define ID_AA64PFR0_FEAT_RME_SHIFT		U(52)
 #define ID_AA64PFR0_FEAT_RME_MASK		ULL(0xf)
 #define ID_AA64PFR0_FEAT_RME_LENGTH		U(4)
-#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED	U(0)
-#define ID_AA64PFR0_FEAT_RME_V1			U(1)
+#define RME_NOT_IMPLEMENTED			ULL(0)
 
 #define ID_AA64PFR0_RAS_SHIFT			U(28)
 #define ID_AA64PFR0_RAS_MASK			ULL(0xf)
-#define ID_AA64PFR0_RAS_NOT_SUPPORTED		ULL(0x0)
 #define ID_AA64PFR0_RAS_LENGTH			U(4)
 
 /* Exception level handling */
@@ -231,17 +227,18 @@
 /* ID_AA64DFR0_EL1.TraceVer definitions */
 #define ID_AA64DFR0_TRACEVER_SHIFT	U(4)
 #define ID_AA64DFR0_TRACEVER_MASK	ULL(0xf)
-#define ID_AA64DFR0_TRACEVER_SUPPORTED	ULL(1)
 #define ID_AA64DFR0_TRACEVER_LENGTH	U(4)
+
 #define ID_AA64DFR0_TRACEFILT_SHIFT	U(40)
 #define ID_AA64DFR0_TRACEFILT_MASK	U(0xf)
-#define ID_AA64DFR0_TRACEFILT_SUPPORTED	U(1)
 #define ID_AA64DFR0_TRACEFILT_LENGTH	U(4)
+#define TRACEFILT_IMPLEMENTED		ULL(1)
+
 #define ID_AA64DFR0_PMUVER_LENGTH	U(4)
 #define ID_AA64DFR0_PMUVER_SHIFT	U(8)
 #define ID_AA64DFR0_PMUVER_MASK		U(0xf)
 #define ID_AA64DFR0_PMUVER_PMUV3	U(1)
-#define ID_AA64DFR0_PMUVER_PMUV3P7	U(7)
+#define ID_AA64DFR0_PMUVER_PMUV3P8	U(8)
 #define ID_AA64DFR0_PMUVER_IMP_DEF	U(0xf)
 
 /* ID_AA64DFR0_EL1.SEBEP definitions */
@@ -252,24 +249,24 @@
 /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
 #define ID_AA64DFR0_PMS_SHIFT		U(32)
 #define ID_AA64DFR0_PMS_MASK		ULL(0xf)
-#define ID_AA64DFR0_SPE_SUPPORTED	ULL(0x1)
-#define ID_AA64DFR0_SPE_NOT_SUPPORTED   ULL(0x0)
+#define SPE_IMPLEMENTED			ULL(0x1)
+#define SPE_NOT_IMPLEMENTED		ULL(0x0)
 
 /* ID_AA64DFR0_EL1.TraceBuffer definitions */
 #define ID_AA64DFR0_TRACEBUFFER_SHIFT		U(44)
 #define ID_AA64DFR0_TRACEBUFFER_MASK		ULL(0xf)
-#define ID_AA64DFR0_TRACEBUFFER_SUPPORTED	ULL(1)
+#define TRACEBUFFER_IMPLEMENTED			ULL(1)
 
 /* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */
 #define ID_AA64DFR0_MTPMU_SHIFT		U(48)
 #define ID_AA64DFR0_MTPMU_MASK		ULL(0xf)
-#define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
-#define ID_AA64DFR0_MTPMU_DISABLED	ULL(15)
+#define MTPMU_IMPLEMENTED		ULL(1)
+#define MTPMU_NOT_IMPLEMENTED		ULL(15)
 
 /* ID_AA64DFR0_EL1.BRBE definitions */
 #define ID_AA64DFR0_BRBE_SHIFT		U(52)
 #define ID_AA64DFR0_BRBE_MASK		ULL(0xf)
-#define ID_AA64DFR0_BRBE_SUPPORTED	ULL(1)
+#define BRBE_IMPLEMENTED		ULL(1)
 
 /* ID_AA64DFR1_EL1 definitions */
 #define ID_AA64DFR1_EBEP_SHIFT		U(48)
@@ -295,8 +292,8 @@
 
 #define ID_AA64ISAR1_SB_SHIFT		U(36)
 #define ID_AA64ISAR1_SB_MASK		ULL(0xf)
-#define ID_AA64ISAR1_SB_SUPPORTED	ULL(0x1)
-#define ID_AA64ISAR1_SB_NOT_SUPPORTED	ULL(0x0)
+#define SB_IMPLEMENTED			ULL(0x1)
+#define SB_NOT_IMPLEMENTED		ULL(0x0)
 
 /* ID_AA64ISAR2_EL1 definitions */
 #define ID_AA64ISAR2_EL1		S3_0_C0_C6_2
@@ -324,52 +321,41 @@
 
 #define ID_AA64MMFR0_EL1_ECV_SHIFT		U(60)
 #define ID_AA64MMFR0_EL1_ECV_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_ECV_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_ECV_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR0_EL1_ECV_SELF_SYNCH	ULL(0x2)
+#define ID_AA64MMFR0_EL1_ECV_SELF_SYNCH		ULL(0x2)
+#define ECV_IMPLEMENTED				ULL(0x1)
 
 #define ID_AA64MMFR0_EL1_FGT_SHIFT		U(56)
 #define ID_AA64MMFR0_EL1_FGT_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_FGT_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR0_EL1_FGT_NOT_SUPPORTED	ULL(0x0)
+#define FGT_IMPLEMENTED				ULL(0x1)
+#define FGT_NOT_IMPLEMENTED			ULL(0x0)
 
 #define ID_AA64MMFR0_EL1_TGRAN4_SHIFT		U(28)
 #define ID_AA64MMFR0_EL1_TGRAN4_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN4_52B_SUPPORTED	ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED	ULL(0xf)
 
 #define ID_AA64MMFR0_EL1_TGRAN64_SHIFT		U(24)
 #define ID_AA64MMFR0_EL1_TGRAN64_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN64_NOT_SUPPORTED	ULL(0xf)
 
 #define ID_AA64MMFR0_EL1_TGRAN16_SHIFT		U(20)
 #define ID_AA64MMFR0_EL1_TGRAN16_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED	ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN16_52B_SUPPORTED	ULL(0x2)
+#define TGRAN16_IMPLEMENTED			ULL(0x1)
 
 /* ID_AA64MMFR1_EL1 definitions */
 #define ID_AA64MMFR1_EL1_TWED_SHIFT		U(32)
 #define ID_AA64MMFR1_EL1_TWED_MASK		ULL(0xf)
-#define ID_AA64MMFR1_EL1_TWED_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR1_EL1_TWED_NOT_SUPPORTED	ULL(0x0)
+#define TWED_IMPLEMENTED			ULL(0x1)
 
 #define ID_AA64MMFR1_EL1_PAN_SHIFT		U(20)
 #define ID_AA64MMFR1_EL1_PAN_MASK		ULL(0xf)
-#define ID_AA64MMFR1_EL1_PAN_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR1_EL1_PAN_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR1_EL1_PAN2_SUPPORTED		ULL(0x2)
-#define ID_AA64MMFR1_EL1_PAN3_SUPPORTED		ULL(0x3)
+#define PAN_IMPLEMENTED				ULL(0x1)
+#define PAN2_IMPLEMENTED			ULL(0x2)
+#define PAN3_IMPLEMENTED			ULL(0x3)
 
 #define ID_AA64MMFR1_EL1_VHE_SHIFT		U(8)
 #define ID_AA64MMFR1_EL1_VHE_MASK		ULL(0xf)
 
 #define ID_AA64MMFR1_EL1_HCX_SHIFT		U(40)
 #define ID_AA64MMFR1_EL1_HCX_MASK		ULL(0xf)
-#define ID_AA64MMFR1_EL1_HCX_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED	ULL(0x0)
+#define HCX_IMPLEMENTED				ULL(0x1)
 
 /* ID_AA64MMFR2_EL1 definitions */
 #define ID_AA64MMFR2_EL1			S3_0_C0_C7_2
@@ -389,9 +375,7 @@
 
 #define ID_AA64MMFR2_EL1_NV_SHIFT		U(24)
 #define ID_AA64MMFR2_EL1_NV_MASK		ULL(0xf)
-#define ID_AA64MMFR2_EL1_NV_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR2_EL1_NV_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR2_EL1_NV2_SUPPORTED		ULL(0x2)
+#define NV2_IMPLEMENTED				ULL(0x2)
 
 /* ID_AA64MMFR3_EL1 definitions */
 #define ID_AA64MMFR3_EL1			S3_0_C0_C7_3
@@ -415,11 +399,11 @@
 
 #define ID_AA64PFR1_EL1_BT_SHIFT	U(0)
 #define ID_AA64PFR1_EL1_BT_MASK		ULL(0xf)
-#define BTI_IMPLEMENTED		ULL(1)	/* The BTI mechanism is implemented */
+#define BTI_IMPLEMENTED			ULL(1)	/* The BTI mechanism is implemented */
 
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
-#define SSBS_UNAVAILABLE	ULL(0)	/* No architectural SSBS support */
+#define SSBS_NOT_IMPLEMENTED		ULL(0)	/* No architectural SSBS support */
 
 #define ID_AA64PFR1_EL1_MTE_SHIFT	U(8)
 #define ID_AA64PFR1_EL1_MTE_MASK	ULL(0xf)
@@ -435,8 +419,7 @@
 #define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
 #define GCS_IMPLEMENTED			ULL(1)
 
-#define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED	ULL(0x1)
-#define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED	ULL(0x0)
+#define RNG_TRAP_IMPLEMENTED		ULL(0x1)
 
 /* ID_AA64PFR2_EL1 definitions */
 #define ID_AA64PFR2_EL1_MTEPERM_SHIFT		U(0)
@@ -469,9 +452,9 @@
 #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)
+#define SME_IMPLEMENTED				ULL(0x1)
+#define SME2_IMPLEMENTED			ULL(0x2)
+#define SME_NOT_IMPLEMENTED			ULL(0x0)
 
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -1103,11 +1086,11 @@
 /* ID_AA64SMFR0_EL1 definitions */
 #define ID_AA64SMFR0_EL1_SME_FA64_SHIFT		U(63)
 #define ID_AA64SMFR0_EL1_SME_FA64_MASK		U(0x1)
-#define ID_AA64SMFR0_EL1_SME_FA64_SUPPORTED	U(0x1)
+#define SME_FA64_IMPLEMENTED			U(0x1)
 #define ID_AA64SMFR0_EL1_SME_VER_SHIFT		U(55)
 #define ID_AA64SMFR0_EL1_SME_VER_MASK		ULL(0xf)
-#define ID_AA64SMFR0_EL1_SME_INST_SUPPORTED	ULL(0x0)
-#define ID_AA64SMFR0_EL1_SME2_INST_SUPPORTED	ULL(0x1)
+#define SME_INST_IMPLEMENTED			ULL(0x0)
+#define SME2_INST_IMPLEMENTED			ULL(0x1)
 
 /* SMCR_ELx definitions */
 #define SMCR_ELX_LEN_SHIFT		U(0)
@@ -1337,6 +1320,8 @@
 #define GPTBR_EL3			S3_6_C2_C1_4
 
 #define SCXTNUM_EL2			S3_4_C13_C0_7
+#define SCXTNUM_EL1			S3_0_C13_C0_7
+#define SCXTNUM_EL0			S3_3_C13_C0_7
 
 /*******************************************************************************
  * RAS system registers
@@ -1401,6 +1386,8 @@
 #define RGSR_EL1		S3_0_C1_C0_5
 #define GCR_EL1			S3_0_C1_C0_6
 
+#define GCR_EL1_RRND_BIT	(UL(1) << 16)
+
 /*******************************************************************************
  * Armv8.5 - Random Number Generator Registers
  ******************************************************************************/
@@ -1433,18 +1420,23 @@
 #define HFGWTR_EL2_INIT_VAL	ULL(0xC4000000000000)
 
 /*******************************************************************************
- * FEAT_TCR2 - Extended Translation Control Register
+ * FEAT_TCR2 - Extended Translation Control Registers
  ******************************************************************************/
+#define TCR2_EL1		S3_0_C2_C0_3
 #define TCR2_EL2		S3_4_C2_C0_3
 
 /*******************************************************************************
- * Permission indirection and overlay
+ * Permission indirection and overlay Registers
  ******************************************************************************/
 
+#define PIRE0_EL1		S3_0_C10_C2_2
 #define PIRE0_EL2		S3_4_C10_C2_2
+#define PIR_EL1			S3_0_C10_C2_3
 #define PIR_EL2			S3_4_C10_C2_3
+#define POR_EL1			S3_0_C10_C2_4
 #define POR_EL2			S3_4_C10_C2_4
 #define S2PIR_EL2		S3_4_C10_C2_5
+#define S2POR_EL1		S3_0_C10_C2_5
 
 /*******************************************************************************
  * FEAT_GCS - Guarded Control Stack Registers
@@ -1452,10 +1444,19 @@
 #define GCSCR_EL2		S3_4_C2_C5_0
 #define GCSPR_EL2		S3_4_C2_C5_1
 #define GCSCR_EL1		S3_0_C2_C5_0
+#define GCSCRE0_EL1		S3_0_C2_C5_2
+#define GCSPR_EL1		S3_0_C2_C5_1
+#define GCSPR_EL0		S3_3_C2_C5_1
 
 #define GCSCR_EXLOCK_EN_BIT	(UL(1) << 6)
 
 /*******************************************************************************
+ * FEAT_TRF - Trace Filter Control Registers
+ ******************************************************************************/
+#define TRFCR_EL2		S3_4_C1_C2_1
+#define TRFCR_EL1		S3_0_C1_C2_1
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
@@ -1481,4 +1482,17 @@
 /* alternative system register encoding for the "sb" speculation barrier */
 #define SYSREG_SB			S0_3_C3_C0_7
 
+#define CLUSTERPMCR_EL1			S3_0_C15_C5_0
+#define CLUSTERPMCNTENSET_EL1		S3_0_C15_C5_1
+#define CLUSTERPMCCNTR_EL1		S3_0_C15_C6_0
+#define CLUSTERPMOVSSET_EL1		S3_0_C15_C5_3
+#define CLUSTERPMOVSCLR_EL1		S3_0_C15_C5_4
+#define CLUSTERPMSELR_EL1		S3_0_C15_C5_5
+#define CLUSTERPMXEVTYPER_EL1		S3_0_C15_C6_1
+#define CLUSTERPMXEVCNTR_EL1		S3_0_C15_C6_2
+
+#define CLUSTERPMCR_E_BIT		BIT(0)
+#define CLUSTERPMCR_N_SHIFT		U(11)
+#define CLUSTERPMCR_N_MASK		U(0x1f)
+
 #endif /* ARCH_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index de59d45..ddc1c80 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -12,27 +12,125 @@
 #include <arch_helpers.h>
 #include <common/feat_detect.h>
 
-#define ISOLATE_FIELD(reg, feat)					\
-	((unsigned int)(((reg) >> (feat)) & ID_REG_FIELD_MASK))
+#define ISOLATE_FIELD(reg, feat, mask)						\
+	((unsigned int)(((reg) >> (feat)) & mask))
 
-#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);				\
+#define CREATE_FEATURE_SUPPORTED(name, read_func, 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();							\
 }
 
-#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)
+#define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
+static inline bool is_ ## name ## _present(void)				\
+{										\
+	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
+		? true : false; 						\
+}
+
+#define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard)		\
+CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)			\
+CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
+
+
+/* +----------------------------+
+ * |	Features supported	|
+ * +----------------------------+
+ * |	GENTIMER		|
+ * +----------------------------+
+ * |	FEAT_PAN		|
+ * +----------------------------+
+ * |	FEAT_VHE		|
+ * +----------------------------+
+ * |	FEAT_TTCNP		|
+ * +----------------------------+
+ * |	FEAT_UAO		|
+ * +----------------------------+
+ * |	FEAT_PACQARMA3		|
+ * +----------------------------+
+ * |	FEAT_PAUTH		|
+ * +----------------------------+
+ * |	FEAT_TTST		|
+ * +----------------------------+
+ * |	FEAT_BTI		|
+ * +----------------------------+
+ * |	FEAT_MTE2		|
+ * +----------------------------+
+ * |	FEAT_SSBS		|
+ * +----------------------------+
+ * |	FEAT_NMI		|
+ * +----------------------------+
+ * |	FEAT_GCS		|
+ * +----------------------------+
+ * |	FEAT_EBEP		|
+ * +----------------------------+
+ * |	FEAT_SEBEP		|
+ * +----------------------------+
+ * |	FEAT_SEL2		|
+ * +----------------------------+
+ * |	FEAT_TWED		|
+ * +----------------------------+
+ * |	FEAT_FGT		|
+ * +----------------------------+
+ * |	FEAT_EC/ECV2		|
+ * +----------------------------+
+ * |	FEAT_RNG		|
+ * +----------------------------+
+ * |	FEAT_TCR2		|
+ * +----------------------------+
+ * |	FEAT_S2POE		|
+ * +----------------------------+
+ * |	FEAT_S1POE		|
+ * +----------------------------+
+ * |	FEAT_S2PIE		|
+ * +----------------------------+
+ * |	FEAT_S1PIE		|
+ * +----------------------------+
+ * |	FEAT_AMU/AMUV1P1	|
+ * +----------------------------+
+ * |	FEAT_MPAM		|
+ * +----------------------------+
+ * |	FEAT_HCX		|
+ * +----------------------------+
+ * |	FEAT_RNG_TRAP		|
+ * +----------------------------+
+ * |	FEAT_RME		|
+ * +----------------------------+
+ * |	FEAT_SB			|
+ * +----------------------------+
+ * |	FEAT_CSV2/CSV3		|
+ * +----------------------------+
+ * |	FEAT_SPE		|
+ * +----------------------------+
+ * |	FEAT_SVE		|
+ * +----------------------------+
+ * |	FEAT_RAS		|
+ * +----------------------------+
+ * |	FEAT_DIT		|
+ * +----------------------------+
+ * |	FEAT_SYS_REG_TRACE	|
+ * +----------------------------+
+ * |	FEAT_TRF		|
+ * +----------------------------+
+ * |	FEAT_NV/NV2		|
+ * +----------------------------+
+ * |	FEAT_BRBE		|
+ * +----------------------------+
+ * |	FEAT_TRBE		|
+ * +----------------------------+
+ * |	FEAT_SME/SME2		|
+ * +----------------------------+
+ * |	FEAT_PMUV3		|
+ * +----------------------------+
+ * |	FEAT_MTPMU		|
+ * +----------------------------+
+ */
 
 static inline bool is_armv7_gentimer_present(void)
 {
@@ -40,38 +138,28 @@
 	return true;
 }
 
+/* FEAT_PAN: Privileged access never */
 CREATE_FEATURE_FUNCS(feat_pan, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_PAN_SHIFT,
-		     ENABLE_FEAT_PAN)
-static inline bool is_feat_pan_present(void)
-{
-	return read_feat_pan_id_field() != 0U;
-}
+		     ID_AA64MMFR1_EL1_PAN_MASK, 1U, ENABLE_FEAT_PAN)
 
+/* FEAT_VHE: Virtualization Host Extensions */
 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)
-{
-	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
-		ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
-}
+		     ID_AA64MMFR1_EL1_VHE_MASK, 1U, ENABLE_FEAT_VHE)
 
-static inline bool is_feat_uao_present(void)
-{
-	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_UAO_SHIFT) &
-		ID_AA64MMFR2_EL1_UAO_MASK) != 0U;
-}
+/* FEAT_TTCNP: Translation table common not private */
+CREATE_FEATURE_PRESENT(feat_ttcnp, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_CNP_SHIFT,
+			ID_AA64MMFR2_EL1_CNP_MASK, 1U)
 
-static inline bool is_feat_pacqarma3_present(void)
-{
-	uint64_t mask_id_aa64isar2 =
-			(ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
-			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
+/* FEAT_UAO: User access override */
+CREATE_FEATURE_PRESENT(feat_uao, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_UAO_SHIFT,
+			ID_AA64MMFR2_EL1_UAO_MASK, 1U)
 
-	/* If any of the fields is not zero, QARMA3 algorithm is present */
-	return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
-}
+/* If any of the fields is not zero, QARMA3 algorithm is present */
+CREATE_FEATURE_PRESENT(feat_pacqarma3, id_aa64isar2_el1, 0,
+			((ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
+			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT)), 1U)
 
+/* PAUTH */
 static inline bool is_armv8_3_pauth_present(void)
 {
 	uint64_t mask_id_aa64isar1 =
@@ -88,89 +176,81 @@
 		is_feat_pacqarma3_present());
 }
 
-static inline bool is_armv8_4_ttst_present(void)
-{
-	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
-		ID_AA64MMFR2_EL1_ST_MASK) == 1U;
-}
-
-static inline bool is_armv8_5_bti_present(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
-		ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
-}
+/* FEAT_TTST: Small translation tables */
+CREATE_FEATURE_PRESENT(feat_ttst, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_ST_SHIFT,
+			ID_AA64MMFR2_EL1_ST_MASK, 1U)
 
-static inline unsigned int get_armv8_5_mte_support(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
-		ID_AA64PFR1_EL1_MTE_MASK);
-}
+/* FEAT_BTI: Branch target identification */
+CREATE_FEATURE_PRESENT(feat_bti, id_aa64pfr1_el1, ID_AA64PFR1_EL1_BT_SHIFT,
+			ID_AA64PFR1_EL1_BT_MASK, BTI_IMPLEMENTED)
 
-static inline bool is_feat_ssbs_present(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SSBS_SHIFT) &
-		ID_AA64PFR1_EL1_SSBS_MASK) != SSBS_UNAVAILABLE;
-}
+/* FEAT_MTE2: Memory tagging extension */
+CREATE_FEATURE_FUNCS(feat_mte2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
+		     ID_AA64PFR1_EL1_MTE_MASK, MTE_IMPLEMENTED_ELX, ENABLE_FEAT_MTE2)
 
-static inline bool is_feat_nmi_present(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_NMI_SHIFT) &
-		ID_AA64PFR1_EL1_NMI_MASK) == NMI_IMPLEMENTED;
-}
+/* FEAT_SSBS: Speculative store bypass safe */
+CREATE_FEATURE_PRESENT(feat_ssbs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SSBS_SHIFT,
+			ID_AA64PFR1_EL1_SSBS_MASK, 1U)
 
-static inline bool is_feat_gcs_present(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_GCS_SHIFT) &
-		ID_AA64PFR1_EL1_GCS_MASK) == GCS_IMPLEMENTED;
-}
+/* FEAT_NMI: Non-maskable interrupts */
+CREATE_FEATURE_PRESENT(feat_nmi, id_aa64pfr1_el1, ID_AA64PFR1_EL1_NMI_SHIFT,
+			ID_AA64PFR1_EL1_NMI_MASK, NMI_IMPLEMENTED)
 
-static inline bool is_feat_ebep_present(void)
-{
-	return ((read_id_aa64dfr1_el1() >> ID_AA64DFR1_EBEP_SHIFT) &
-		ID_AA64DFR1_EBEP_MASK) == EBEP_IMPLEMENTED;
-}
+/* FEAT_EBEP */
+CREATE_FEATURE_PRESENT(feat_ebep, id_aa64dfr1_el1, ID_AA64DFR1_EBEP_SHIFT,
+			ID_AA64DFR1_EBEP_MASK, EBEP_IMPLEMENTED)
 
-static inline bool is_feat_sebep_present(void)
-{
-	return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_SEBEP_SHIFT) &
-		ID_AA64DFR0_SEBEP_MASK) == SEBEP_IMPLEMENTED;
-}
+/* FEAT_SEBEP */
+CREATE_FEATURE_PRESENT(feat_sebep, id_aa64dfr0_el1, ID_AA64DFR0_SEBEP_SHIFT,
+			ID_AA64DFR0_SEBEP_MASK, SEBEP_IMPLEMENTED)
 
-CREATE_FEATURE_FUNCS(feat_mte, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
-		     ENABLE_FEAT_MTE)
-CREATE_FEATURE_FUNCS_VER(feat_mte2, read_feat_mte_id_field, MTE_IMPLEMENTED_ELX,
-		     ENABLE_FEAT_MTE2)
+/* FEAT_SEL2: Secure EL2 */
 CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
-		     ENABLE_FEAT_SEL2)
+		     ID_AA64PFR0_SEL2_MASK, 1U, ENABLE_FEAT_SEL2)
+
+/* FEAT_TWED: Delayed trapping of WFE */
 CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
-		     ENABLE_FEAT_TWED)
+		     ID_AA64MMFR1_EL1_TWED_MASK, 1U, ENABLE_FEAT_TWED)
+
+/* FEAT_FGT: Fine-grained traps */
 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)
+		     ID_AA64MMFR0_EL1_FGT_MASK, 1U, ENABLE_FEAT_FGT)
+
+/* FEAT_ECV: Enhanced Counter Virtualization */
 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)
+		     ID_AA64MMFR0_EL1_ECV_MASK, 1U, ENABLE_FEAT_ECV)
+CREATE_FEATURE_FUNCS(feat_ecv_v2, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
+		     ID_AA64MMFR0_EL1_ECV_MASK, ID_AA64MMFR0_EL1_ECV_SELF_SYNCH, ENABLE_FEAT_ECV)
 
+/* FEAT_RNG: Random number generator */
 CREATE_FEATURE_FUNCS(feat_rng, id_aa64isar0_el1, ID_AA64ISAR0_RNDR_SHIFT,
-		     ENABLE_FEAT_RNG)
+		     ID_AA64ISAR0_RNDR_MASK, 1U, ENABLE_FEAT_RNG)
+
+/* FEAT_TCR2: Support TCR2_ELx regs */
 CREATE_FEATURE_FUNCS(feat_tcr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_TCRX_SHIFT,
-		     ENABLE_FEAT_TCR2)
+		     ID_AA64MMFR3_EL1_TCRX_MASK, 1U, ENABLE_FEAT_TCR2)
 
+/* FEAT_S2POE */
 CREATE_FEATURE_FUNCS(feat_s2poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2POE_SHIFT,
-		     ENABLE_FEAT_S2POE)
+		     ID_AA64MMFR3_EL1_S2POE_MASK, 1U, ENABLE_FEAT_S2POE)
+
+/* FEAT_S1POE */
 CREATE_FEATURE_FUNCS(feat_s1poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1POE_SHIFT,
-		     ENABLE_FEAT_S1POE)
+		     ID_AA64MMFR3_EL1_S1POE_MASK, 1U, ENABLE_FEAT_S1POE)
+
 static inline bool is_feat_sxpoe_supported(void)
 {
 	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
 }
 
+/* FEAT_S2PIE */
 CREATE_FEATURE_FUNCS(feat_s2pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2PIE_SHIFT,
-		     ENABLE_FEAT_S2PIE)
+		     ID_AA64MMFR3_EL1_S2PIE_MASK, 1U, ENABLE_FEAT_S2PIE)
+
+/* FEAT_S1PIE */
 CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
-		     ENABLE_FEAT_S1PIE)
+		     ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
+
 static inline bool is_feat_sxpie_supported(void)
 {
 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
@@ -178,13 +258,15 @@
 
 /* FEAT_GCS: Guarded Control Stack */
 CREATE_FEATURE_FUNCS(feat_gcs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_GCS_SHIFT,
-		     ENABLE_FEAT_GCS)
+		     ID_AA64PFR1_EL1_GCS_MASK, 1U, ENABLE_FEAT_GCS)
 
 /* 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)
+		     ID_AA64PFR0_AMU_MASK, 1U, ENABLE_FEAT_AMU)
+
+/* FEAT_AMUV1P1: AMU Extension v1.1 */
+CREATE_FEATURE_FUNCS(feat_amuv1p1, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
+		     ID_AA64PFR0_AMU_MASK, ID_AA64PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
 
 /*
  * Return MPAM version:
@@ -195,46 +277,32 @@
  * 0x11: v1.1 Armv8.4 or later
  *
  */
-static inline unsigned int read_feat_mpam_version(void)
+static inline bool is_feat_mpam_present(void)
 {
-	return (unsigned int)((((read_id_aa64pfr0_el1() >>
+	unsigned int ret = (unsigned int)((((read_id_aa64pfr0_el1() >>
 		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
-				((read_id_aa64pfr1_el1() >>
-		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
+		((read_id_aa64pfr1_el1() >> ID_AA64PFR1_MPAM_FRAC_SHIFT)
+			& ID_AA64PFR1_MPAM_FRAC_MASK));
+	return ret;
 }
 
-CREATE_FEATURE_FUNCS_VER(feat_mpam, read_feat_mpam_version, 1U,
-			 ENABLE_FEAT_MPAM)
+CREATE_FEATURE_SUPPORTED(feat_mpam, is_feat_mpam_present, ENABLE_FEAT_MPAM)
 
 /* FEAT_HCX: Extended Hypervisor Configuration Register */
 CREATE_FEATURE_FUNCS(feat_hcx, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_HCX_SHIFT,
-		     ENABLE_FEAT_HCX)
+		     ID_AA64MMFR1_EL1_HCX_MASK, 1U, ENABLE_FEAT_HCX)
 
-static inline bool is_feat_rng_trap_present(void)
-{
-	return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
-			ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
-			== ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
-}
+/* FEAT_RNG_TRAP: Trapping support */
+CREATE_FEATURE_PRESENT(feat_rng_trap, id_aa64pfr1_el1, ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
+		      ID_AA64PFR1_EL1_RNDR_TRAP_MASK, RNG_TRAP_IMPLEMENTED)
 
-static inline unsigned int get_armv9_2_feat_rme_support(void)
-{
-	/*
-	 * Return the RME version, zero if not supported.  This function can be
-	 * used as both an integer value for the RME version or compared to zero
-	 * to detect RME presence.
-	 */
-	return (unsigned int)(read_id_aa64pfr0_el1() >>
-		ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
-}
+/* Return the RME version, zero if not supported. */
+CREATE_FEATURE_FUNCS(feat_rme, id_aa64pfr0_el1, ID_AA64PFR0_FEAT_RME_SHIFT,
+		    ID_AA64PFR0_FEAT_RME_MASK, 1U, ENABLE_RME)
 
-/*********************************************************************************
- * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
- ********************************************************************************/
-static inline unsigned int read_feat_sb_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
-}
+/* FEAT_SB: Speculation barrier instruction */
+CREATE_FEATURE_PRESENT(feat_sb, id_aa64isar1_el1, ID_AA64ISAR1_SB_SHIFT,
+		       ID_AA64ISAR1_SB_MASK, 1U)
 
 /*
  * FEAT_CSV2: Cache Speculation Variant 2. This checks bit fields[56-59]
@@ -248,109 +316,94 @@
  *          implemented.
  * 0b0011 - Feature FEAT_CSV2_3 is implemented.
  */
-static inline unsigned int read_feat_csv2_id_field(void)
-{
-	return (unsigned int)(read_id_aa64pfr0_el1() >>
-		ID_AA64PFR0_CSV2_SHIFT) & ID_AA64PFR0_CSV2_MASK;
-}
 
-CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
-			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
-CREATE_FEATURE_FUNCS_VER(feat_csv2_3, read_feat_csv2_id_field,
-			 ID_AA64PFR0_CSV2_3_SUPPORTED, ENABLE_FEAT_CSV2_3)
+CREATE_FEATURE_FUNCS(feat_csv2_2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT,
+		     ID_AA64PFR0_CSV2_MASK, CSV2_2_IMPLEMENTED, ENABLE_FEAT_CSV2_2)
+CREATE_FEATURE_FUNCS(feat_csv2_3, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT,
+		     ID_AA64PFR0_CSV2_MASK, CSV2_3_IMPLEMENTED, ENABLE_FEAT_CSV2_3)
 
 /* FEAT_SPE: Statistical Profiling Extension */
 CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
-		     ENABLE_SPE_FOR_NS)
+		     ID_AA64DFR0_PMS_MASK, 1U, ENABLE_SPE_FOR_NS)
 
 /* FEAT_SVE: Scalable Vector Extension */
 CREATE_FEATURE_FUNCS(feat_sve, id_aa64pfr0_el1, ID_AA64PFR0_SVE_SHIFT,
-		     ENABLE_SVE_FOR_NS)
+		     ID_AA64PFR0_SVE_MASK, 1U, ENABLE_SVE_FOR_NS)
 
 /* FEAT_RAS: Reliability, Accessibility, Serviceability */
-CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1,
-		     ID_AA64PFR0_RAS_SHIFT, ENABLE_FEAT_RAS)
+CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1, ID_AA64PFR0_RAS_SHIFT,
+		     ID_AA64PFR0_RAS_MASK, 1U, ENABLE_FEAT_RAS)
 
 /* FEAT_DIT: Data Independent Timing instructions */
-CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1,
-		     ID_AA64PFR0_DIT_SHIFT, ENABLE_FEAT_DIT)
+CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1, ID_AA64PFR0_DIT_SHIFT,
+		     ID_AA64PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT)
 
-CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1,
-		     ID_AA64DFR0_TRACEVER_SHIFT, ENABLE_SYS_REG_TRACE_FOR_NS)
+/* FEAT_SYS_REG_TRACE */
+CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1, ID_AA64DFR0_TRACEVER_SHIFT,
+		    ID_AA64DFR0_TRACEVER_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS)
 
 /* FEAT_TRF: TraceFilter */
 CREATE_FEATURE_FUNCS(feat_trf, id_aa64dfr0_el1, ID_AA64DFR0_TRACEFILT_SHIFT,
-		     ENABLE_TRF_FOR_NS)
+		     ID_AA64DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS)
 
 /* 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)
+CREATE_FEATURE_FUNCS(feat_nv, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT,
+		     ID_AA64MMFR2_EL1_NV_MASK, 1U, 0U)
+CREATE_FEATURE_FUNCS(feat_nv2, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT,
+		     ID_AA64MMFR2_EL1_NV_MASK, NV2_IMPLEMENTED, CTX_INCLUDE_NEVE_REGS)
 
 /* FEAT_BRBE: Branch Record Buffer Extension */
 CREATE_FEATURE_FUNCS(feat_brbe, id_aa64dfr0_el1, ID_AA64DFR0_BRBE_SHIFT,
-		     ENABLE_BRBE_FOR_NS)
+		     ID_AA64DFR0_BRBE_MASK, 1U, ENABLE_BRBE_FOR_NS)
 
 /* FEAT_TRBE: Trace Buffer Extension */
 CREATE_FEATURE_FUNCS(feat_trbe, id_aa64dfr0_el1, ID_AA64DFR0_TRACEBUFFER_SHIFT,
-		     ENABLE_TRBE_FOR_NS)
+		     ID_AA64DFR0_TRACEBUFFER_MASK, 1U, ENABLE_TRBE_FOR_NS)
 
-static inline unsigned int read_feat_sme_fa64_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64smfr0_el1(),
-			     ID_AA64SMFR0_EL1_SME_FA64_SHIFT);
-}
+/* FEAT_SME_FA64: Full A64 Instruction support in streaming SVE mode */
+CREATE_FEATURE_PRESENT(feat_sme_fa64, id_aa64smfr0_el1, ID_AA64SMFR0_EL1_SME_FA64_SHIFT,
+		    ID_AA64SMFR0_EL1_SME_FA64_MASK, 1U)
+
 /* 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)
+		     ID_AA64PFR1_EL1_SME_MASK, 1U, ENABLE_SME_FOR_NS)
+
+CREATE_FEATURE_FUNCS(feat_sme2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
+		     ID_AA64PFR1_EL1_SME_MASK, SME2_IMPLEMENTED, ENABLE_SME2_FOR_NS)
 
 /*******************************************************************************
  * Function to get hardware granularity support
  ******************************************************************************/
 
-static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
+static inline bool is_feat_tgran4K_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT);
+	unsigned int tgranx = ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT, ID_REG_FIELD_MASK);
+	return (tgranx < 8U);
 }
 
-static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN16_SHIFT);
-}
+CREATE_FEATURE_PRESENT(feat_tgran16K, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_TGRAN16_SHIFT,
+		       ID_AA64MMFR0_EL1_TGRAN16_MASK, TGRAN16_IMPLEMENTED)
 
-static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
+static inline bool is_feat_tgran64K_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT);
+	unsigned int tgranx = ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT, ID_REG_FIELD_MASK);
+	return (tgranx < 8U);
 }
 
-static inline unsigned int read_feat_pmuv3_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT);
-}
+/* FEAT_PMUV3 */
+CREATE_FEATURE_PRESENT(feat_pmuv3, id_aa64dfr0_el1, ID_AA64DFR0_PMUVER_SHIFT,
+		      ID_AA64DFR0_PMUVER_MASK, 1U)
 
-static inline unsigned int read_feat_mtpmu_id_field(void)
+/* FEAT_MTPMU */
+static inline bool is_feat_mtpmu_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT);
+	unsigned int mtpmu = ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT,
+					   ID_AA64DFR0_MTPMU_MASK);
+	return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED);
 }
 
-static inline bool is_feat_mtpmu_supported(void)
-{
-	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	unsigned int mtpmu = read_feat_mtpmu_id_field();
-
-	return (mtpmu != 0U) && (mtpmu != ID_AA64DFR0_MTPMU_DISABLED);
-}
+CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU)
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 6356cab..1e2f84b 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -284,6 +284,7 @@
 DEFINE_SYSREG_RW_FUNCS(elr_el2)
 DEFINE_SYSREG_RW_FUNCS(elr_el3)
 DEFINE_SYSREG_RW_FUNCS(mdccsr_el0)
+DEFINE_SYSREG_RW_FUNCS(mdccint_el1)
 DEFINE_SYSREG_RW_FUNCS(dbgdtrrx_el0)
 DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
 DEFINE_SYSREG_RW_FUNCS(sp_el1)
@@ -504,6 +505,7 @@
 
 DEFINE_SYSREG_READ_FUNC(isr_el1)
 
+DEFINE_SYSREG_RW_FUNCS(mdscr_el1)
 DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
 DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
 DEFINE_SYSREG_RW_FUNCS(hstr_el2)
@@ -567,6 +569,8 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el2, SCXTNUM_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el1, SCXTNUM_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el0, SCXTNUM_EL0)
 
 /* Armv8.1 VHE Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
@@ -576,6 +580,7 @@
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
 
 /* Armv8.2 RAS Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(disr_el1, DISR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(vdisr_el2, VDISR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(vsesr_el2, VSESR_EL2)
 
@@ -603,6 +608,7 @@
 
 /* Armv8.4 FEAT_TRF Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(trfcr_el2, TRFCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(trfcr_el1, TRFCR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(vncr_el2, VNCR_EL2)
 
 /* Armv8.5 MTE Registers */
@@ -634,23 +640,39 @@
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
 
 /* FEAT_TCR2 Register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el1, TCR2_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
 
 /* FEAT_SxPIE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el1, PIRE0_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el1, PIR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
 
 /* FEAT_SxPOE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(por_el1, POR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(s2por_el1, S2POR_EL1)
 
 /* FEAT_GCS Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el2, GCSCR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el2, GCSPR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el1, GCSCR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcscre0_el1, GCSCRE0_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
 
-/* DynamIQ Shared Unit power management */
+/* DynamIQ Control registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcntenset_el1, CLUSTERPMCNTENSET_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmccntr_el1, CLUSTERPMCCNTR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmovsset_el1, CLUSTERPMOVSSET_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmovsclr_el1, CLUSTERPMOVSCLR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmselr_el1, CLUSTERPMSELR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmxevcntr_el1, CLUSTERPMXEVCNTR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmxevtyper_el1, CLUSTERPMXEVTYPER_EL1)
 
 /* CPU Power/Performance Management registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(cpuppmcr_el3, CPUPPMCR_EL3)
@@ -704,24 +726,86 @@
 }
 
 /*
- * TLBIPAALLOS instruction
- * (TLB Inivalidate GPT Information by PA,
- * All Entries, Outer Shareable)
+ * TLBI PAALLOS instruction
+ * (TLB Invalidate GPT Information by PA, All Entries, Outer Shareable)
  */
 static inline void tlbipaallos(void)
 {
-	__asm__("SYS #6,c8,c1,#4");
+	__asm__("sys #6, c8, c1, #4");
 }
 
 /*
- * Invalidate TLBs of GPT entries by Physical address, last level.
+ * TLBI RPALOS instructions
+ * (TLB Range Invalidate GPT Information by PA, Last level, Outer Shareable)
  *
- * @pa: the starting address for the range
- *      of invalidation
- * @size: size of the range of invalidation
+ * command SIZE, bits [47:44] field:
+ * 0b0000	4KB
+ * 0b0001	16KB
+ * 0b0010	64KB
+ * 0b0011	2MB
+ * 0b0100	32MB
+ * 0b0101	512MB
+ * 0b0110	1GB
+ * 0b0111	16GB
+ * 0b1000	64GB
+ * 0b1001	512GB
  */
-void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
+#define TLBI_SZ_4K		0UL
+#define TLBI_SZ_16K		1UL
+#define TLBI_SZ_64K		2UL
+#define TLBI_SZ_2M		3UL
+#define TLBI_SZ_32M		4UL
+#define TLBI_SZ_512M		5UL
+#define TLBI_SZ_1G		6UL
+#define TLBI_SZ_16G		7UL
+#define TLBI_SZ_64G		8UL
+#define TLBI_SZ_512G		9UL
 
+#define	TLBI_ADDR_SHIFT		U(12)
+#define	TLBI_SIZE_SHIFT		U(44)
+
+#define TLBIRPALOS(_addr, _size)				\
+{								\
+	u_register_t arg = ((_addr) >> TLBI_ADDR_SHIFT) |	\
+			   ((_size) << TLBI_SIZE_SHIFT);	\
+	__asm__("sys #6, c8, c4, #7, %0" : : "r" (arg));	\
+}
+
+/* Note: addr must be aligned to 4KB */
+static inline void tlbirpalos_4k(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_4K);
+}
+
+/* Note: addr must be aligned to 16KB */
+static inline void tlbirpalos_16k(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_16K);
+}
+
+/* Note: addr must be aligned to 64KB */
+static inline void tlbirpalos_64k(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_64K);
+}
+
+/* Note: addr must be aligned to 2MB */
+static inline void tlbirpalos_2m(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_2M);
+}
+
+/* Note: addr must be aligned to 32MB */
+static inline void tlbirpalos_32m(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_32M);
+}
+
+/* Note: addr must be aligned to 512MB */
+static inline void tlbirpalos_512m(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_512M);
+}
 
 /* Previously defined accessor functions with incomplete register names  */
 
@@ -742,8 +826,32 @@
 #define read_cpacr()		read_cpacr_el1()
 #define write_cpacr(_v)		write_cpacr_el1(_v)
 
+#define read_clusterpwrdn()		read_clusterpwrdn_el1()
+#define write_clusterpwrdn(_v)		write_clusterpwrdn_el1(_v)
+
+#define read_clusterpmcr()		read_clusterpmcr_el1()
+#define write_clusterpmcr(_v)		write_clusterpmcr_el1(_v)
+
+#define read_clusterpmcntenset()	read_clusterpmcntenset_el1()
+#define write_clusterpmcntenset(_v)	write_clusterpmcntenset_el1(_v)
+
+#define read_clusterpmccntr()		read_clusterpmccntr_el1()
+#define write_clusterpmccntr(_v)	write_clusterpmccntr_el1(_v)
+
+#define read_clusterpmovsset()		read_clusterpmovsset_el1()
+#define write_clusterpmovsset(_v)	write_clusterpmovsset_el1(_v)
+
+#define read_clusterpmovsclr()		read_clusterpmovsclr_el1()
+#define write_clusterpmovsclr(_v)	write_clusterpmovsclr_el1(_v)
+
+#define read_clusterpmselr()		read_clusterpmselr_el1()
+#define write_clusterpmselr(_v)		write_clusterpmselr_el1(_v)
+
+#define read_clusterpmxevcntr()		read_clusterpmxevcntr_el1()
+#define write_clusterpmxevcntr(_v)	write_clusterpmxevcntr_el1(_v)
+
-#define read_clusterpwrdn()	read_clusterpwrdn_el1()
-#define write_clusterpwrdn(_v)	write_clusterpwrdn_el1(_v)
+#define read_clusterpmxevtyper()	read_clusterpmxevtyper_el1()
+#define write_clusterpmxevtyper(_v)	write_clusterpmxevtyper_el1(_v)
 
 #if ERRATA_SPECULATIVE_AT
 /*
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index d09ad0f..ec2acd5 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -317,4 +317,12 @@
 #endif
 	.endm
 
+	/*
+	 * Helper macro to instruction adr <reg>, <symbol> where <symbol> is
+	 * within the range +/- 4 GB.
+	 */
+	.macro adr_l, dst, sym
+	adrp	\dst, \sym
+	add	\dst, \dst, :lo12:\sym
+	.endm
 #endif /* ASM_MACROS_S */
diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S
index 9609c0d..9f82399 100644
--- a/include/arch/aarch64/el2_common_macros.S
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -157,7 +157,7 @@
 	 */
 	mrs	x0, id_aa64pfr0_el1
 	ubfx	x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
-	cmp	x0, #ID_AA64PFR0_DIT_SUPPORTED
+	cmp	x0, #DIT_IMPLEMENTED
 	bne	1f
 	mov	x0, #DIT_BIT
 	msr	DIT, x0
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 26c7578..b4c5c1b 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -88,21 +88,8 @@
 	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
 	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
 	 *  disabled from all ELs in Secure state.
-	 *
-	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
-	 *  privileged debug from S-EL1.
-	 *
-	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
-	 *  access to the powerdown debug registers do not trap to EL3.
-	 *
-	 * 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.
 	 */
-	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
-		      MDCR_SPD32(MDCR_SPD32_DISABLE)) & \
-		    ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT))
-
+	mov_imm	x0, (MDCR_EL3_RESET_VAL | MDCR_SDD_BIT)
 	msr	mdcr_el3, x0
 
 	/* ---------------------------------------------------------------------
@@ -133,7 +120,7 @@
 #if ENABLE_FEAT_DIT > 1
 	cbz	x0, 1f
 #else
-	cmp	x0, #ID_AA64PFR0_DIT_SUPPORTED
+	cmp	x0, #DIT_IMPLEMENTED
 	ASM_ASSERT(eq)
 #endif
 
diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h
index 7cd7e72..3ab88de 100644
--- a/include/bl1/bl1.h
+++ b/include/bl1/bl1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -94,9 +94,5 @@
 		(FWU_SMC_FID_END - FWU_SMC_FID_START + 1),
 		assert_FWU_NUM_SMC_CALLS_mismatch);
 
-/* Utility functions */
-void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			meminfo_t *bl2_mem_layout);
-
 #endif /* __ASSEMBLER__ */
 #endif /* BL1_H */
diff --git a/include/bl31/bl31.h b/include/bl31/bl31.h
index 1d58ef9..ed5374e 100644
--- a/include/bl31/bl31.h
+++ b/include/bl31/bl31.h
@@ -22,6 +22,5 @@
 void bl31_register_rmm_init(int32_t (*func)(void));
 void bl31_warm_entrypoint(void);
 void bl31_main(void);
-void bl31_lib_init(void);
 
 #endif /* BL31_H */
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
index ae61f31..394252b 100644
--- a/include/bl31/sync_handle.h
+++ b/include/bl31/sync_handle.h
@@ -58,6 +58,8 @@
 /* Handler for injecting UNDEF exception to lower EL */
 void inject_undef64(cpu_context_t *ctx);
 
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el);
+
 /* Prototypes for system register emulation handlers provided by platforms. */
 int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
 int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 4c8a17c..647ae85 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -180,8 +180,6 @@
 void dyn_disable_auth(void);
 #endif
 
-extern const char build_message[];
-extern const char version_string[];
 const char *get_version(void);
 
 void print_entry_point_info(const entry_point_info_t *ep_info);
diff --git a/include/common/build_message.h b/include/common/build_message.h
new file mode 100644
index 0000000..b7c2f72
--- /dev/null
+++ b/include/common/build_message.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BUILD_MESSAGE_H
+#define BUILD_MESSAGE_H
+
+static const char build_message[] = "Built : " BUILD_MESSAGE_TIMESTAMP;
+static const char build_version_string[] = BUILD_MESSAGE_VERSION_STRING;
+static const char build_version[] = BUILD_MESSAGE_VERSION;
+
+#endif /* BUILD_MESSAGE_H */
diff --git a/include/common/debug.h b/include/common/debug.h
index 5ea541d..0ddb400 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,6 +91,12 @@
 # define VERBOSE(...)	no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
 #endif
 
+#if EARLY_CONSOLE
+#define EARLY_ERROR(...)	ERROR(__VA_ARGS__)
+#else /* !EARLY_CONSOLE */
+#define EARLY_ERROR(...)	no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
+#endif /* EARLY_CONSOLE */
+
 const char *get_el_str(unsigned int el);
 
 #if ENABLE_BACKTRACE
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
index 88302fd..d6c1a2a 100644
--- a/include/drivers/arm/css/css_mhu_doorbell.h
+++ b/include/drivers/arm/css/css_mhu_doorbell.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,10 @@
 #define SENDER_REG_STAT(_channel)	(0x20 * (_channel))
 #define SENDER_REG_SET(_channel)	((0x20 * (_channel)) + 0xC)
 
+#define MHU_V3_PBX_PDBCW_PAGE_OFFSET		UL(0x1000)
+#define MHU_V3_SENDER_REG_SET(_channel)		(MHU_V3_PBX_PDBCW_PAGE_OFFSET + \
+						 SENDER_REG_SET(_channel))
+
 /* Helper macro to ring doorbell */
 #define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
 		uint32_t db = mmio_read_32(addr) & (preserve_mask);	\
diff --git a/include/drivers/arm/css/dsu.h b/include/drivers/arm/css/dsu.h
new file mode 100644
index 0000000..4d7822b
--- /dev/null
+++ b/include/drivers/arm/css/dsu.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DSU_H
+#define DSU_H
+
+#define PMCR_N_MAX			0x1f
+
+#define save_pmu_reg(state, reg) state->reg = read_##reg()
+
+#define restore_pmu_reg(context, reg) write_##reg(context->reg)
+
+typedef struct cluster_pmu_state{
+	uint64_t clusterpmcr;
+	uint64_t clusterpmcntenset;
+	uint64_t clusterpmccntr;
+	uint64_t clusterpmovsset;
+	uint64_t clusterpmselr;
+	uint64_t clusterpmsevtyper;
+	uint64_t counter_val[PMCR_N_MAX];
+	uint64_t counter_type[PMCR_N_MAX];
+} cluster_pmu_state_t;
+
+static inline unsigned int read_cluster_eventctr_num(void)
+{
+	return ((read_clusterpmcr() >> CLUSTERPMCR_N_SHIFT) &
+			CLUSTERPMCR_N_MASK);
+}
+
+
+void save_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_context);
+
+void restore_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_context);
+
+void cluster_on_dsu_pmu_context_restore(void);
+
+void cluster_off_dsu_pmu_context_save(void);
+
+#endif /* DSU_H */
diff --git a/include/drivers/arm/fvp/fvp_cpu_pwr.h b/include/drivers/arm/fvp/fvp_cpu_pwr.h
new file mode 100644
index 0000000..488be18
--- /dev/null
+++ b/include/drivers/arm/fvp/fvp_cpu_pwr.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_CPU_PWR_H
+#define FVP_CPU_PWR_H
+
+#ifndef __ASSEMBLER__
+#include <stdbool.h>
+#include <stdint.h>
+
+#if __aarch64__
+bool check_cpupwrctrl_el1_is_available(void);
+#endif /* __aarch64__ */
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CPUPWRCTLR_EL1                  S3_0_C15_C2_7
+#define CPUPWRCTLR_EL1_CORE_PWRDN_BIT   U(1)
+
+#endif /* FVP_CPU_PWR_H */
diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h
index bebd9ce..c7c441d 100644
--- a/include/drivers/arm/gicv2.h
+++ b/include/drivers/arm/gicv2.h
@@ -51,7 +51,7 @@
 #define SGIR_TGTLSTFLT_MASK	U(0x3)
 #define SGIR_TGTLST_SHIFT	16
 #define SGIR_TGTLST_MASK	U(0xff)
-#define SGIR_NSATT		(U(0x1) << 16)
+#define SGIR_NSATT		(U(0x1) << 15)
 #define SGIR_INTID_MASK		ULL(0xf)
 
 #define SGIR_TGT_SPECIFIC	U(0)
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index cf6a746..bfda31b 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -588,6 +588,7 @@
 void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
 void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
 unsigned int gicv3_set_pmr(unsigned int mask);
+unsigned int gicv3_deactivate_priority(unsigned int mask);
 
 void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
 				    unsigned int *gic_prod_id,
diff --git a/include/drivers/arm/rse_comms.h b/include/drivers/arm/rse_comms.h
new file mode 100644
index 0000000..e4169a5
--- /dev/null
+++ b/include/drivers/arm/rse_comms.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSE_COMMS_H
+#define RSE_COMMS_H
+
+#include <stdint.h>
+
+int rse_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base);
+
+#endif /* RSE_COMMS_H */
diff --git a/include/drivers/arm/rss_comms.h b/include/drivers/arm/rss_comms.h
deleted file mode 100644
index b96c79f..0000000
--- a/include/drivers/arm/rss_comms.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef RSS_COMMS_H
-#define RSS_COMMS_H
-
-#include <stdint.h>
-
-int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base);
-
-#endif /* RSS_COMMS_H */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-2.h b/include/drivers/auth/mbedtls/mbedtls_config-2.h
deleted file mode 100644
index 01e261a..0000000
--- a/include/drivers/auth/mbedtls/mbedtls_config-2.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2015-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-/*
- * Key algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_RSA			1
-#define TF_MBEDTLS_ECDSA		2
-#define TF_MBEDTLS_RSA_AND_ECDSA	3
-
-#define TF_MBEDTLS_USE_RSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA \
-		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
-#define TF_MBEDTLS_USE_ECDSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA \
-		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
-
-/*
- * Hash algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_SHA256		1
-#define TF_MBEDTLS_SHA384		2
-#define TF_MBEDTLS_SHA512		3
-
-/*
- * Configuration file to build mbed TLS with the required features for
- * Trusted Boot
- */
-
-#define MBEDTLS_PLATFORM_MEMORY
-#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
-#define MBEDTLS_PLATFORM_SNPRINTF_ALT
-
-#define MBEDTLS_PKCS1_V21
-
-#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_ASN1_WRITE_C
-
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_BIGNUM_C
-
-#define MBEDTLS_ERROR_C
-#define MBEDTLS_MD_C
-
-#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
-#define MBEDTLS_OID_C
-
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-
-#define MBEDTLS_PLATFORM_C
-
-#if TF_MBEDTLS_USE_ECDSA
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_NO_INTERNAL_RNG
-#endif
-#if TF_MBEDTLS_USE_RSA
-#define MBEDTLS_RSA_C
-#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-#endif
-
-#define MBEDTLS_SHA256_C
-
-/*
- * If either Trusted Boot or Measured Boot require a stronger algorithm than
- * SHA-256, pull in SHA-512 support.
- */
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) /* TBB hash algo */
-#define	MBEDTLS_SHA512_C
-#else
-   /* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
-#define MBEDTLS_SHA512_C
-#endif
-#endif
-
-#define MBEDTLS_VERSION_C
-
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-
-#if TF_MBEDTLS_USE_AES_GCM
-#define MBEDTLS_AES_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_GCM_C
-#endif
-
-/* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
-
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define MBEDTLS_MPI_MAX_SIZE			256
-#else
-#define MBEDTLS_MPI_MAX_SIZE			512
-#endif
-#else
-#define MBEDTLS_MPI_MAX_SIZE			256
-#endif
-
-/* Memory buffer allocator options */
-#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
-
-/*
- * Prevent the use of 128-bit division which
- * creates dependency on external libraries.
- */
-#define MBEDTLS_NO_UDBL_DIVISION
-
-#ifndef __ASSEMBLER__
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-#include <mbedtls/check_config.h>
-#endif
-
-/*
- * Determine Mbed TLS heap size
- * 13312 = 13*1024
- * 11264 = 11*1024
- * 7168  = 7*1024
- */
-#if TF_MBEDTLS_USE_ECDSA
-#define TF_MBEDTLS_HEAP_SIZE		U(13312)
-#elif TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define TF_MBEDTLS_HEAP_SIZE		U(7168)
-#else
-#define TF_MBEDTLS_HEAP_SIZE		U(11264)
-#endif
-#endif
-
-/*
- * Warn if errors from certain functions are ignored.
- *
- * The warnings are always enabled (where supported) for critical functions
- * where ignoring the return value is almost always a bug. This macro extends
- * the warnings to more functions.
- */
-#define MBEDTLS_CHECK_RETURN_WARNING
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/mbedtls_config-3.h
index 923fc54..37a9288 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config-3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -128,7 +128,6 @@
 #ifndef __ASSEMBLER__
 /* System headers required to build mbed TLS with the current configuration */
 #include <stdlib.h>
-#include <mbedtls/check_config.h>
 #endif
 
 /*
diff --git a/include/drivers/auth/mbedtls/psa_mbedtls_config.h b/include/drivers/auth/mbedtls/psa_mbedtls_config.h
index ad825f0..1001d89 100644
--- a/include/drivers/auth/mbedtls/psa_mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/psa_mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Ltd. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Ltd. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include "mbedtls_config-3.h"
 
 #define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
 
 /*
  * Using PSA crypto API requires an RNG right now. If we don't define the macro
diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h
index b4f2d22..019ae17 100644
--- a/include/drivers/auth/tbbr_cot_common.h
+++ b/include/drivers/auth/tbbr_cot_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020,2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,10 +21,10 @@
 extern auth_param_type_desc_t raw_data;
 
 extern auth_param_type_desc_t tb_fw_hash;
+extern auth_param_type_desc_t hw_config_hash;
 extern auth_param_type_desc_t tb_fw_config_hash;
 extern auth_param_type_desc_t fw_config_hash;
 
 extern const auth_img_desc_t trusted_boot_fw_cert;
-extern const auth_img_desc_t hw_config;
 
 #endif /* TBBR_COT_COMMON_H */
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
index 6452725..8bf3b78 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -280,9 +280,6 @@
 #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))
diff --git a/include/drivers/clk.h b/include/drivers/clk.h
index a18f41f..4db20f8 100644
--- a/include/drivers/clk.h
+++ b/include/drivers/clk.h
@@ -13,15 +13,20 @@
 	int (*enable)(unsigned long id);
 	void (*disable)(unsigned long id);
 	unsigned long (*get_rate)(unsigned long id);
+	int (*set_rate)(unsigned long id, unsigned long rate,
+			unsigned long *orate);
 	int (*get_parent)(unsigned long id);
+	int (*set_parent)(unsigned long id, unsigned long parent_id);
 	bool (*is_enabled)(unsigned long id);
 };
 
 int clk_enable(unsigned long id);
 void clk_disable(unsigned long id);
 unsigned long clk_get_rate(unsigned long id);
+int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate);
 bool clk_is_enabled(unsigned long id);
 int clk_get_parent(unsigned long id);
+int clk_set_parent(unsigned long id, unsigned long parent_id);
 
 void clk_register(const struct clk_ops *ops);
 
diff --git a/include/drivers/fwu/fwu.h b/include/drivers/fwu/fwu.h
index 9f18e22..18e8a31 100644
--- a/include/drivers/fwu/fwu.h
+++ b/include/drivers/fwu/fwu.h
@@ -9,8 +9,15 @@
 
 #include <stdbool.h>
 
+#define FWU_BANK_STATE_ACCEPTED		0xFCU
+#define FWU_BANK_STATE_VALID		0xFEU
+#define FWU_BANK_STATE_INVALID		0xFFU
+
+#define INVALID_BOOT_IDX		0xFFFFFFFFU
+
 void fwu_init(void);
-bool fwu_is_trial_run_state(void);
+uint32_t fwu_get_active_bank_state(void);
+uint32_t fwu_get_alternate_boot_bank(void);
 const struct fwu_metadata *fwu_get_metadata(void);
 
 #endif /* FWU_H */
diff --git a/include/drivers/fwu/fwu_metadata.h b/include/drivers/fwu/fwu_metadata.h
index 2e88de5..b441300 100644
--- a/include/drivers/fwu/fwu_metadata.h
+++ b/include/drivers/fwu/fwu_metadata.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * FWU metadata information as per the specification section 4.1:
- * https://developer.arm.com/documentation/den0118/a/
+ * https://developer.arm.com/documentation/den0118/latest/
  *
  */
 
@@ -14,11 +14,13 @@
 #include <stdint.h>
 #include <tools_share/uuid.h>
 
+#define NR_OF_MAX_FW_BANKS	4
+
 /* Properties of image in a bank */
-struct fwu_image_properties {
+struct fwu_image_bank_info {
 
-	/* UUID of the image in this bank */
-	uuid_t img_uuid;
+	/* GUID of the image in this bank */
+	struct efi_guid img_guid;
 
 	/* [0]: bit describing the image acceptance status –
 	 *      1 means the image is accepted
@@ -34,17 +36,40 @@
 /* Image entry information */
 struct fwu_image_entry {
 
-	/* UUID identifying the image type */
-	uuid_t img_type_uuid;
+	/* GUID identifying the image type */
+	struct efi_guid img_type_guid;
 
-	/* UUID of the storage volume where the image is located */
-	uuid_t location_uuid;
+	/* GUID of the storage volume where the image is located */
+	struct efi_guid location_guid;
 
-	/* Properties of images with img_type_uuid in the different FW banks */
-	struct fwu_image_properties img_props[NR_OF_FW_BANKS];
+	/* Properties of images with img_type_guid in the different FW banks */
+	struct fwu_image_bank_info img_bank_info[NR_OF_FW_BANKS];
 
 } __packed;
 
+/* Firmware Image descriptor */
+struct fwu_fw_store_descriptor {
+
+	/* Number of Banks */
+	uint8_t num_banks;
+
+	/* Reserved */
+	uint8_t reserved;
+
+	/* Number of images per bank */
+	uint16_t num_images;
+
+	/* Size of image_entry(all banks) in bytes */
+	uint16_t img_entry_size;
+
+	/* Size of image bank info structure in bytes */
+	uint16_t bank_info_entry_size;
+
+	/* Array of fwu_image_entry structs */
+	struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
+
+} __packed;
+
 /*
  * FWU metadata filled by the updater and consumed by TF-A for
  * various purposes as below:
@@ -66,8 +91,25 @@
 	/* Previous bank index with which device booted successfully */
 	uint32_t previous_active_index;
 
+	/* Size of the entire metadata in bytes */
+	uint32_t metadata_size;
+
+	/* Offset of the image descriptor structure */
+	uint16_t desc_offset;
+
+	/* Reserved */
+	uint16_t reserved1;
+
+	/* Bank state */
+	uint8_t bank_state[NR_OF_MAX_FW_BANKS];
+
+	/* Reserved */
+	uint32_t reserved2;
+
+#if PSA_FWU_METADATA_FW_STORE_DESC
 	/* Image entry information */
-	struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
+	struct fwu_fw_store_descriptor fw_desc;
+#endif
 
 } __packed;
 
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index 794d613..b44526a 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,51 +43,6 @@
 
 #define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
 
-/*
- * Each event log entry has some metadata (i.e. a string) that identifies
- * what is measured.These macros define these strings.
- * Note that these strings follow the standardization recommendations
- * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
- * where applicable. They should not be changed in the code.
- * Where the SBSG does not make recommendations, we are free to choose any
- * naming convention.
- * The key thing is to choose meaningful strings so that when the TPM event
- * log is used in attestation, the different components can be identified.
- */
-#define EVLOG_BL2_STRING		"BL_2"
-#define EVLOG_BL31_STRING		"SECURE_RT_EL3"
-#if defined(SPD_opteed)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_OPTEE"
-#elif defined(SPD_tspd)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TSPD"
-#elif defined(SPD_tlkd)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TLKD"
-#elif defined(SPD_trusty)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TRUSTY"
-#else
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_UNKNOWN"
-#endif
-#define	EVLOG_BL32_EXTRA1_STRING	"SECURE_RT_EL1_OPTEE_EXTRA1"
-#define	EVLOG_BL32_EXTRA2_STRING	"SECURE_RT_EL1_OPTEE_EXTRA2"
-#define EVLOG_BL33_STRING		"BL_33"
-#define EVLOG_FW_CONFIG_STRING		"FW_CONFIG"
-#define EVLOG_HW_CONFIG_STRING		"HW_CONFIG"
-#define EVLOG_NT_FW_CONFIG_STRING	"NT_FW_CONFIG"
-#define EVLOG_SCP_BL2_STRING		"SYS_CTRL_2"
-#define EVLOG_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
-#define EVLOG_STM32_STRING		"STM32"
-#define EVLOG_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
-#define	EVLOG_TOS_FW_CONFIG_STRING	"TOS_FW_CONFIG"
-#define EVLOG_RMM_STRING 		"RMM"
-#define EVLOG_SP1_STRING		"SP1"
-#define EVLOG_SP2_STRING		"SP2"
-#define EVLOG_SP3_STRING		"SP3"
-#define EVLOG_SP4_STRING		"SP4"
-#define EVLOG_SP5_STRING		"SP5"
-#define EVLOG_SP6_STRING		"SP6"
-#define EVLOG_SP7_STRING		"SP7"
-#define EVLOG_SP8_STRING		"SP8"
-
 typedef struct {
 	unsigned int id;
 	const char *name;
diff --git a/include/drivers/measured_boot/metadata.h b/include/drivers/measured_boot/metadata.h
new file mode 100644
index 0000000..5e17a83
--- /dev/null
+++ b/include/drivers/measured_boot/metadata.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef METADATA_H
+#define METADATA_H
+
+/* Minimum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MIN_SIZE	32U
+/* Maximum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MAX_SIZE	64U
+/* Minimum signer id size that can be requested to store */
+#define SIGNER_ID_MIN_SIZE		MEASUREMENT_VALUE_MIN_SIZE
+/* Maximum signer id size that can be requested to store */
+#define SIGNER_ID_MAX_SIZE		MEASUREMENT_VALUE_MAX_SIZE
+/* The theoretical maximum image version is: "255.255.65535\0" */
+#define VERSION_MAX_SIZE		14U
+/* Example sw_type: "BL_2, BL_33, etc." */
+#define SW_TYPE_MAX_SIZE		32U
+
+/*
+ * Images, measured during the boot process, have some associated metadata.
+ * One of these types of metadata is the image identifier strings. These macros
+ * define these strings. They are used across the different measured boot
+ * backends.
+ * Note that these strings follow the standardization recommendations
+ * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
+ * where applicable. They should not be changed in the code.
+ * Where the SBSG does not make recommendations, we are free to choose any
+ * naming convention.
+ * The key thing is to choose meaningful strings so that when the measured boot
+ * metadata is used in attestation, the different components can be identified.
+ */
+#define MBOOT_BL2_IMAGE_STRING		"BL_2"
+#define MBOOT_BL31_IMAGE_STRING		"SECURE_RT_EL3"
+#if defined(SPD_opteed)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_OPTEE"
+#elif defined(SPD_tspd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TSPD"
+#elif defined(SPD_tlkd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TLKD"
+#elif defined(SPD_trusty)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TRUSTY"
+#elif defined(SPD_spmd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_SPMD"
+#else
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_UNKNOWN"
+#endif /* SPD_opteed */
+#define MBOOT_BL32_EXTRA1_IMAGE_STRING	"SECURE_RT_EL1_OPTEE_EXTRA1"
+#define MBOOT_BL32_EXTRA2_IMAGE_STRING	"SECURE_RT_EL1_OPTEE_EXTRA2"
+#define MBOOT_BL33_IMAGE_STRING		"BL_33"
+#define MBOOT_FW_CONFIG_STRING		"FW_CONFIG"
+#define MBOOT_HW_CONFIG_STRING		"HW_CONFIG"
+#define MBOOT_NT_FW_CONFIG_STRING	"NT_FW_CONFIG"
+#define MBOOT_SCP_BL2_IMAGE_STRING	"SYS_CTRL_2"
+#define MBOOT_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
+#define MBOOT_STM32_STRING		"STM32"
+#define MBOOT_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
+#define MBOOT_TOS_FW_CONFIG_STRING	"TOS_FW_CONFIG"
+#define MBOOT_RMM_IMAGE_STRING		"RMM"
+#define MBOOT_SP1_STRING		"SP1"
+#define MBOOT_SP2_STRING		"SP2"
+#define MBOOT_SP3_STRING		"SP3"
+#define MBOOT_SP4_STRING		"SP4"
+#define MBOOT_SP5_STRING		"SP5"
+#define MBOOT_SP6_STRING		"SP6"
+#define MBOOT_SP7_STRING		"SP7"
+#define MBOOT_SP8_STRING		"SP8"
+
+#endif /* METADATA_H */
diff --git a/include/drivers/measured_boot/rse/dice_prot_env.h b/include/drivers/measured_boot/rse/dice_prot_env.h
new file mode 100644
index 0000000..e5aef51
--- /dev/null
+++ b/include/drivers/measured_boot/rse/dice_prot_env.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DICE_PROT_ENV_H
+#define DICE_PROT_ENV_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <drivers/measured_boot/metadata.h>
+
+#define DPE_INVALID_ID	UINT32_MAX
+
+struct dpe_metadata {
+	unsigned int id;
+	uint32_t cert_id;
+	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+	size_t  signer_id_size;
+	uint8_t version[VERSION_MAX_SIZE];
+	size_t  version_size;
+	uint8_t sw_type[SW_TYPE_MAX_SIZE];
+	size_t  sw_type_size;
+	bool allow_new_context_to_derive;
+	bool retain_parent_context;
+	bool create_certificate;
+	int target_locality;
+	void *pk_oid;
+};
+
+void dpe_init(struct dpe_metadata *metadata);
+
+/* Returns 0 in case of success otherwise -1. */
+int dpe_measure_and_record(struct dpe_metadata *metadata,
+			   uintptr_t data_base, uint32_t data_size,
+			   uint32_t data_id);
+
+int dpe_set_signer_id(struct dpe_metadata *metadata,
+		      const void *pk_oid, const void *pk_ptr, size_t pk_len);
+
+/* Child components inherit their first valid context handle from their parents.
+ * How to share context handle is platform specific.
+ */
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle);
+void plat_dpe_get_context_handle(int *ctx_handle);
+
+#endif /* DICE_PROT_ENV_H */
diff --git a/include/drivers/measured_boot/rse/rse_measured_boot.h b/include/drivers/measured_boot/rse/rse_measured_boot.h
new file mode 100644
index 0000000..2f605d7
--- /dev/null
+++ b/include/drivers/measured_boot/rse/rse_measured_boot.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSE_MEASURED_BOOT_H
+#define RSE_MEASURED_BOOT_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/measured_boot/metadata.h>
+
+#define RSE_MBOOT_INVALID_ID	UINT32_MAX
+
+struct rse_mboot_metadata {
+	unsigned int id;
+	uint8_t slot;
+	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+	size_t  signer_id_size;
+	uint8_t version[VERSION_MAX_SIZE];
+	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 rse_measured_boot_init(struct rse_mboot_metadata *metadata_ptr);
+int rse_mboot_measure_and_record(struct rse_mboot_metadata *metadata_ptr,
+				 uintptr_t data_base, uint32_t data_size,
+				 uint32_t data_id);
+
+int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr,
+			    const void *pk_oid, const void *pk_ptr,
+			    size_t pk_len);
+
+#endif /* RSE_MEASURED_BOOT_H */
diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h
deleted file mode 100644
index 7ab517c..0000000
--- a/include/drivers/measured_boot/rss/rss_measured_boot.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RSS_MEASURED_BOOT_H
-#define RSS_MEASURED_BOOT_H
-
-#include <stdint.h>
-
-#include <common/debug.h>
-#include <measured_boot.h>
-
-#define RSS_MBOOT_INVALID_ID	UINT32_MAX
-
-/*
- * Each boot measurement has some metadata (i.e. a string) that identifies
- * what was measured and how. The sw_type field of the rss_mboot_metadata
- * structure represents the role of the software component that was measured.
- * The below macros define strings suitable for the sw_type.
- * The key thing is to choose meaningful strings so that when the attestation
- * token is verified, then the different components can be identified.
- */
-#define RSS_MBOOT_BL2_STRING		"BL_2"
-#define RSS_MBOOT_BL31_STRING		"SECURE_RT_EL3"
-#define RSS_MBOOT_HW_CONFIG_STRING	"HW_CONFIG"
-#define RSS_MBOOT_FW_CONFIG_STRING	"FW_CONFIG"
-#define RSS_MBOOT_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
-#define RSS_MBOOT_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
-#define RSS_MBOOT_RMM_STRING		"RMM"
-
-
-struct rss_mboot_metadata {
-	unsigned int id;
-	uint8_t slot;
-	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
-	size_t  signer_id_size;
-	uint8_t version[VERSION_MAX_SIZE];
-	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(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);
-
-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/nxp/clk/s32cc/s32cc-clk-drv.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
new file mode 100644
index 0000000..d879f5b
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef S32CC_CLK_DRV_H
+#define S32CC_CLK_DRV_H
+
+int s32cc_init_early_clks(void);
+
+#endif
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
new file mode 100644
index 0000000..633f173
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2024 NXP
+ */
+#ifndef S32CC_CLK_IDS_H
+#define S32CC_CLK_IDS_H
+
+#include <stdint.h>
+#include <lib/utils_def.h>
+
+/**
+ * Clock ID encoding:
+ *     31:30 bits = Type of the clock
+ *     29:0  bits = Clock ID within the clock category
+ */
+#define S32CC_CLK_ID_MASK	GENMASK_64(29U, 0U)
+#define S32CC_CLK_TYPE_MASK	GENMASK_64(31U, 30U)
+#define S32CC_CLK_ID(ID)	(((unsigned long)(ID)) & S32CC_CLK_ID_MASK)
+#define S32CC_CLK_TYPE(ID)	(((unsigned long)(ID)) & S32CC_CLK_TYPE_MASK)
+#define S32CC_CLK(TAG, ID)	(S32CC_CLK_ID(ID) | (S32CC_CLK_TYPE((TAG) << 30U)))
+#define S32CC_HW_CLK(ID)	S32CC_CLK(0UL, U(ID))
+#define S32CC_SW_CLK(SUB, ID)	S32CC_CLK(2UL | ((SUB) & 1UL), U(ID))
+
+/* SW clocks subcategories */
+#define S32CC_ARCH_CLK(ID)	S32CC_SW_CLK(0UL, ID)
+#define S32CC_PLAT_CLK(ID)	S32CC_SW_CLK(1UL, ID)
+
+/* IDs for clock selectors listed in S32CC Reference Manuals  */
+#define S32CC_CLK_FIRC				S32CC_HW_CLK(0)
+#define S32CC_CLK_SIRC				S32CC_HW_CLK(1)
+#define S32CC_CLK_FXOSC				S32CC_HW_CLK(2)
+#define S32CC_CLK_ARM_PLL_PHI0			S32CC_HW_CLK(4)
+#define S32CC_CLK_ARM_PLL_PHI1			S32CC_HW_CLK(5)
+#define S32CC_CLK_ARM_PLL_PHI2			S32CC_HW_CLK(6)
+#define S32CC_CLK_ARM_PLL_PHI3			S32CC_HW_CLK(7)
+#define S32CC_CLK_ARM_PLL_PHI4			S32CC_HW_CLK(8)
+#define S32CC_CLK_ARM_PLL_PHI5			S32CC_HW_CLK(9)
+#define S32CC_CLK_ARM_PLL_PHI6			S32CC_HW_CLK(10)
+#define S32CC_CLK_ARM_PLL_PHI7			S32CC_HW_CLK(11)
+#define S32CC_CLK_ARM_PLL_DFS1			S32CC_HW_CLK(12)
+#define S32CC_CLK_ARM_PLL_DFS2			S32CC_HW_CLK(13)
+#define S32CC_CLK_ARM_PLL_DFS3			S32CC_HW_CLK(14)
+#define S32CC_CLK_ARM_PLL_DFS4			S32CC_HW_CLK(15)
+#define S32CC_CLK_ARM_PLL_DFS5			S32CC_HW_CLK(16)
+#define S32CC_CLK_ARM_PLL_DFS6			S32CC_HW_CLK(17)
+#define S32CC_CLK_PERIPH_PLL_PHI0		S32CC_HW_CLK(18)
+#define S32CC_CLK_PERIPH_PLL_PHI1		S32CC_HW_CLK(19)
+#define S32CC_CLK_PERIPH_PLL_PHI2		S32CC_HW_CLK(20)
+#define S32CC_CLK_PERIPH_PLL_PHI3		S32CC_HW_CLK(21)
+#define S32CC_CLK_PERIPH_PLL_PHI4		S32CC_HW_CLK(22)
+#define S32CC_CLK_PERIPH_PLL_PHI5		S32CC_HW_CLK(23)
+#define S32CC_CLK_PERIPH_PLL_PHI6		S32CC_HW_CLK(24)
+#define S32CC_CLK_PERIPH_PLL_PHI7		S32CC_HW_CLK(25)
+#define S32CC_CLK_PERIPH_PLL_DFS1		S32CC_HW_CLK(26)
+#define S32CC_CLK_PERIPH_PLL_DFS2		S32CC_HW_CLK(27)
+#define S32CC_CLK_PERIPH_PLL_DFS3		S32CC_HW_CLK(28)
+#define S32CC_CLK_PERIPH_PLL_DFS4		S32CC_HW_CLK(29)
+#define S32CC_CLK_PERIPH_PLL_DFS5		S32CC_HW_CLK(30)
+#define S32CC_CLK_PERIPH_PLL_DFS6		S32CC_HW_CLK(31)
+#define S32CC_CLK_FTM0_EXT_REF			S32CC_HW_CLK(34)
+#define S32CC_CLK_FTM1_EXT_REF			S32CC_HW_CLK(35)
+#define S32CC_CLK_DDR_PLL_PHI0			S32CC_HW_CLK(36)
+#define S32CC_CLK_GMAC0_EXT_TX			S32CC_HW_CLK(37)
+#define S32CC_CLK_GMAC0_EXT_RX			S32CC_HW_CLK(38)
+#define S32CC_CLK_GMAC0_EXT_REF			S32CC_HW_CLK(39)
+#define S32CC_CLK_SERDES0_LANE0_TX		S32CC_HW_CLK(40)
+#define S32CC_CLK_SERDES0_LANE0_CDR		S32CC_HW_CLK(41)
+#define S32CC_CLK_GMAC0_EXT_TS			S32CC_HW_CLK(44)
+#define S32CC_CLK_GMAC0_REF_DIV			S32CC_HW_CLK(45)
+
+/* Software defined clock IDs */
+#define S32CC_CLK_ARM_PLL_MUX			S32CC_ARCH_CLK(0)
+#define S32CC_CLK_ARM_PLL_VCO			S32CC_ARCH_CLK(1)
+
+/* ARM CGM1 clocks */
+#define S32CC_CLK_MC_CGM1_MUX0			S32CC_ARCH_CLK(2)
+#define S32CC_CLK_A53_CORE			S32CC_ARCH_CLK(3)
+#define S32CC_CLK_A53_CORE_DIV2			S32CC_ARCH_CLK(4)
+#define S32CC_CLK_A53_CORE_DIV10		S32CC_ARCH_CLK(5)
+
+#endif /* S32CC_CLK_IDS_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
new file mode 100644
index 0000000..9524f72
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2020-2024 NXP
+ */
+#ifndef S32CC_CLK_MODULES_H
+#define S32CC_CLK_MODULES_H
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#define MHZ	UL(1000000)
+#define GHZ	(UL(1000) * MHZ)
+
+enum s32cc_clkm_type {
+	s32cc_osc_t,
+	s32cc_clk_t,
+};
+
+enum s32cc_clk_source {
+	S32CC_FIRC,
+	S32CC_FXOSC,
+	S32CC_SIRC,
+};
+
+struct s32cc_clk_obj {
+	enum s32cc_clkm_type type;
+	uint32_t refcount;
+};
+
+struct s32cc_osc {
+	struct s32cc_clk_obj desc;
+	enum s32cc_clk_source source;
+	unsigned long freq;
+	void *base;
+};
+
+#define S32CC_OSC_INIT(SOURCE)       \
+{                                    \
+	.desc = {                    \
+		.type = s32cc_osc_t, \
+	},                           \
+	.source = (SOURCE),          \
+}
+
+struct s32cc_clk {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *module;
+	struct s32cc_clk *pclock;
+	unsigned long min_freq;
+	unsigned long max_freq;
+};
+
+struct s32cc_clk_array {
+	unsigned long type_mask;
+	struct s32cc_clk **clks;
+	size_t n_clks;
+};
+
+#define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
+{                                                      \
+	.desc = {                                      \
+		.type = s32cc_clk_t,                   \
+	},                                             \
+	.module = &(PARENT_MODULE).desc,               \
+	.min_freq = (MIN_F),                           \
+	.max_freq = (MAX_F),                           \
+}
+
+#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
+	S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
+
+#define S32CC_MODULE_CLK(PARENT_MODULE) \
+	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
+
+static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t osc_addr;
+
+	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
+	return (struct s32cc_osc *)osc_addr;
+}
+
+static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t clk_addr;
+
+	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
+	return (struct s32cc_clk *)clk_addr;
+}
+
+#endif /* S32CC_CLK_MODULES_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
new file mode 100644
index 0000000..6a90406
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2024 NXP
+ */
+#ifndef S32CC_CLK_UTILS_H
+#define S32CC_CLK_UTILS_H
+
+#include <s32cc-clk-modules.h>
+
+struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
+					   size_t size,
+					   unsigned long clk_id);
+
+struct s32cc_clk *s32cc_get_arch_clk(unsigned long id);
+
+void s32cc_clk_register_drv(void);
+
+#endif /* S32CC_CLK_UTILS_H */
diff --git a/include/drivers/nxp/console/linflex.h b/include/drivers/nxp/console/linflex.h
new file mode 100644
index 0000000..2b4e0d7
--- /dev/null
+++ b/include/drivers/nxp/console/linflex.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef LINFLEX_H
+#define LINFLEX_H
+
+#ifndef __ASSEMBLER__
+#include <drivers/console.h>
+
+int console_linflex_core_init(uintptr_t baseaddr, uint32_t clock,
+			      uint32_t baud);
+int console_linflex_register(uintptr_t baseaddr, uint32_t clock,
+			     uint32_t baud, console_t *console);
+#endif
+
+#endif /* LINFLEX_H */
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index d567d4c..9e22d34 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,13 +41,15 @@
 
 typedef struct partition_entry_list {
 	partition_entry_t	list[PLAT_PARTITION_MAX_ENTRIES];
-	int			entry_count;
+	unsigned int		entry_count;
 } partition_entry_list_t;
 
 int load_partition_table(unsigned int image_id);
 const partition_entry_t *get_partition_entry(const char *name);
-const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_guid);
-const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
+const partition_entry_t *get_partition_entry_by_type(
+	const struct efi_guid *type_guid);
+const partition_entry_t *get_partition_entry_by_guid(
+	const struct efi_guid *part_guid);
 const partition_entry_list_t *get_partition_entry_list(void);
 void partition_init(unsigned int image_id);
 int gpt_partition_init(void);
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
index eeef9da..ef4eb04 100644
--- a/include/drivers/st/stm32_gpio.h
+++ b/include/drivers/st/stm32_gpio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #define GPIO_TYPE_OFFSET	U(0x04)
 #define GPIO_SPEED_OFFSET	U(0x08)
 #define GPIO_PUPD_OFFSET	U(0x0C)
+#define GPIO_IDR_OFFSET		U(0x10)
 #define GPIO_OD_OFFSET		U(0x14)
 #define GPIO_BSRR_OFFSET	U(0x18)
 #define GPIO_AFRL_OFFSET	U(0x20)
@@ -58,6 +59,16 @@
 int dt_set_pinctrl_config(int node);
 void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
 void set_gpio_reset_cfg(uint32_t bank, uint32_t pin);
+
+enum gpio_level {
+	GPIO_LEVEL_LOW,
+	GPIO_LEVEL_HIGH
+};
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level);
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin);
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status);
 #endif /*__ASSEMBLER__*/
 
 #endif /* STM32_GPIO_H */
diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h
index e2395bc..93ec1c5 100644
--- a/include/drivers/st/stm32mp1_clk.h
+++ b/include/drivers/st/stm32mp1_clk.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,8 @@
 void stm32mp1_clk_rcc_regs_lock(void);
 void stm32mp1_clk_rcc_regs_unlock(void);
 
+void stm32mp1_clk_mcuss_protect(bool enable);
+
 #ifdef STM32MP_SHARED_RESOURCES
 void stm32mp1_register_clock_parents_secure(unsigned long id);
 #endif
diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h
index 61286b2..8fd5ed1 100644
--- a/include/drivers/st/stm32mp_clkfunc.h
+++ b/include/drivers/st/stm32mp_clkfunc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,8 +29,6 @@
 unsigned long fdt_get_uart_clock_freq(uintptr_t instance);
 
 void stm32mp_stgen_config(unsigned long rate);
-void stm32mp_stgen_restore_counter(unsigned long long value,
-				   unsigned long long offset_in_ms);
-unsigned long long stm32mp_stgen_get_counter(void);
+void stm32mp_stgen_restore_rate(void);
 
 #endif /* STM32MP_CLKFUNC_H */
diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h
index 1d5bb78..031e432 100644
--- a/include/dt-bindings/clock/stm32mp13-clks.h
+++ b/include/dt-bindings/clock/stm32mp13-clks.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2022-2024 - All Rights Reserved
  * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
  */
 
@@ -193,7 +193,13 @@
 #define SAI1		160
 #define SAI2		161
 
-#define STM32MP1_LAST_CLK 162
+#define SPI1		162
+#define SPI2		163
+#define SPI3		164
+#define SPI4		165
+#define SPI5		166
+
+#define STM32MP1_LAST_CLK 167
 
 /* SCMI clock identifiers */
 #define CK_SCMI0_HSE		0
diff --git a/include/dt-bindings/clock/stm32mp15-clksrc.h b/include/dt-bindings/clock/stm32mp15-clksrc.h
index 3a3792d..e601b48 100644
--- a/include/dt-bindings/clock/stm32mp15-clksrc.h
+++ b/include/dt-bindings/clock/stm32mp15-clksrc.h
@@ -1,273 +1,413 @@
 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
 /*
- * Copyright (C) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2017-2024, STMicroelectronics - All Rights Reserved
  */
 
 #ifndef _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
 #define _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
 
+#include <lib/utils_def.h>
+
+#define CMD_DIV		0
+#define CMD_MUX		1
+#define CMD_CLK		2
+
+#define CMD_ADDR_BIT	BIT(31)
+
+#define CMD_SHIFT	26
+#define CMD_MASK	GENMASK_32(31, 26)
+#define CMD_DATA_MASK	GENMASK_32(25, 0)
+
+#define DIV_ID_SHIFT	8
+#define DIV_ID_MASK	GENMASK_32(15, 8)
+
+#define DIV_DIVN_SHIFT	0
+#define DIV_DIVN_MASK	GENMASK_32(7, 0)
+
+#define MUX_ID_SHIFT	4
+#define MUX_ID_MASK	GENMASK_32(11, 4)
+
+#define MUX_SEL_SHIFT	0
+#define MUX_SEL_MASK	GENMASK_32(3, 0)
+
+#define CLK_ID_MASK	GENMASK_32(19, 11)
+#define CLK_ID_SHIFT	11
+#define CLK_ON_MASK	0x00000400
+#define CLK_ON_SHIFT	10
+#define CLK_DIV_MASK	GENMASK_32(9, 4)
+#define CLK_DIV_SHIFT	4
+#define CLK_SEL_MASK	GENMASK_32(3, 0)
+#define CLK_SEL_SHIFT	0
+
+#define DIV(div_id, div)	((CMD_DIV << CMD_SHIFT) |\
+				 ((div_id) << DIV_ID_SHIFT) |\
+				 (div))
+
+#define CLKSRC(mux_id, sel)	((CMD_MUX << CMD_SHIFT) |\
+				 ((mux_id) << MUX_ID_SHIFT) |\
+				 (sel))
+
+/* CLK output is enable */
+#define CLK_SRC(clk_id, sel)	((CMD_CLK << CMD_SHIFT) |\
+				 ((clk_id) << CLK_ID_SHIFT) |\
+				 (sel) | CLK_ON_MASK)
+
+#define CLK_DISABLED(clk_id)	((CMD_CLK << CMD_SHIFT) |\
+				 ((clk_id) << CLK_ID_SHIFT))
+
+#define CLK_ADDR_SHIFT		16
+#define CLK_ADDR_MASK		GENMASK_32(30, 16)
+#define CLK_ADDR_VAL_MASK	GENMASK_32(15, 0)
+
+#define DIV_PLL1DIVP	0
+#define DIV_PLL2DIVP	1
+#define DIV_PLL2DIVQ	2
+#define DIV_PLL2DIVR	3
+#define DIV_PLL3DIVP	4
+#define DIV_PLL3DIVQ	5
+#define DIV_PLL3DIVR	6
+#define DIV_PLL4DIVP	7
+#define DIV_PLL4DIVQ	8
+#define DIV_PLL4DIVR	9
+#define DIV_MPU		10
+#define DIV_AXI		11
+#define DIV_MCU		12
+#define DIV_APB1	13
+#define DIV_APB2	14
+#define DIV_APB3	15
+#define DIV_APB4	16
+#define DIV_APB5	17
+#define DIV_RTC		19
+#define DIV_MCO1	20
+#define DIV_MCO2	21
+#define DIV_HSI		22
+#define DIV_TRACE	23
+#define DIV_ETHPTP	24
+#define DIV_NB		25
+
+#define MUX_MPU		0
+#define MUX_AXI		1
+#define MUX_MCU		2
+#define MUX_PLL12	3
+#define MUX_PLL3	4
+#define MUX_PLL4	5
+#define MUX_CKPER	6
+#define MUX_RTC		7
+#define MUX_SDMMC12	8
+#define MUX_SDMMC3	9
+#define MUX_FMC		10
+#define MUX_QSPI	11
+#define MUX_RNG1	12
+#define MUX_RNG2	13
+#define MUX_USBPHY	14
+#define MUX_USBO	15
+#define MUX_STGEN	16
+#define MUX_SPDIF	17
+#define MUX_SPI2S1	18
+#define MUX_SPI2S23	19
+#define MUX_SPI45	20
+#define MUX_SPI6	21
+#define MUX_CEC		22
+#define MUX_I2C12	23
+#define MUX_I2C35	24
+#define MUX_I2C46	25
+#define MUX_LPTIM1	26
+#define MUX_LPTIM23	27
+#define MUX_LPTIM45	28
+#define MUX_UART1	29
+#define MUX_UART24	30
+#define MUX_UART35	31
+#define MUX_UART6	32
+#define MUX_UART78	33
+#define MUX_SAI1	34
+#define MUX_SAI2	35
+#define MUX_SAI3	36
+#define MUX_SAI4	37
+#define MUX_DSI		38
+#define MUX_FDCAN	39
+#define MUX_ADC		40
+#define MUX_ETH		41
+#define MUX_MCO1	42
+#define MUX_MCO2	43
+#define MUX_NB		44
+
 /* PLL output is enable when x=1, with x=p,q or r */
 #define PQR(p, q, r)	(((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
 
+/* st,clksrc: clock sources */
+#define CLK_MPU_HSI		CLKSRC(MUX_MPU, 0)
+#define CLK_MPU_HSE		CLKSRC(MUX_MPU, 1)
+#define CLK_MPU_PLL1P		CLKSRC(MUX_MPU, 2)
+#define CLK_MPU_PLL1P_DIV	CLKSRC(MUX_MPU, 3)
+
-/* st,clksrc: mandatory clock source */
-#define CLK_MPU_HSI		0x00000200
-#define CLK_MPU_HSE		0x00000201
-#define CLK_MPU_PLL1P		0x00000202
-#define CLK_MPU_PLL1P_DIV	0x00000203
+#define CLK_AXI_HSI		CLKSRC(MUX_AXI, 0)
+#define CLK_AXI_HSE		CLKSRC(MUX_AXI, 1)
+#define CLK_AXI_PLL2P		CLKSRC(MUX_AXI, 2)
 
-#define CLK_AXI_HSI		0x00000240
-#define CLK_AXI_HSE		0x00000241
-#define CLK_AXI_PLL2P		0x00000242
+#define CLK_MCU_HSI		CLKSRC(MUX_MCU, 0)
+#define CLK_MCU_HSE		CLKSRC(MUX_MCU, 1)
+#define CLK_MCU_CSI		CLKSRC(MUX_MCU, 2)
+#define CLK_MCU_PLL3P		CLKSRC(MUX_MCU, 3)
 
-#define CLK_MCU_HSI		0x00000480
-#define CLK_MCU_HSE		0x00000481
-#define CLK_MCU_CSI		0x00000482
-#define CLK_MCU_PLL3P		0x00000483
+#define CLK_PLL12_HSI		CLKSRC(MUX_PLL12, 0)
+#define CLK_PLL12_HSE		CLKSRC(MUX_PLL12, 1)
 
-#define CLK_PLL12_HSI		0x00000280
-#define CLK_PLL12_HSE		0x00000281
+#define CLK_PLL3_HSI		CLKSRC(MUX_PLL3, 0)
+#define CLK_PLL3_HSE		CLKSRC(MUX_PLL3, 1)
+#define CLK_PLL3_CSI		CLKSRC(MUX_PLL3, 2)
 
-#define CLK_PLL3_HSI		0x00008200
-#define CLK_PLL3_HSE		0x00008201
-#define CLK_PLL3_CSI		0x00008202
+#define CLK_PLL4_HSI		CLKSRC(MUX_PLL4, 0)
+#define CLK_PLL4_HSE		CLKSRC(MUX_PLL4, 1)
+#define CLK_PLL4_CSI		CLKSRC(MUX_PLL4, 2)
+#define CLK_PLL4_I2SCKIN	CLKSRC(MUX_PLL4, 3)
 
-#define CLK_PLL4_HSI		0x00008240
-#define CLK_PLL4_HSE		0x00008241
-#define CLK_PLL4_CSI		0x00008242
-#define CLK_PLL4_I2SCKIN	0x00008243
+#define CLK_RTC_DISABLED	CLK_DISABLED(RTC)
+#define CLK_RTC_LSE		CLK_SRC(RTC, 1)
+#define CLK_RTC_LSI		CLK_SRC(RTC, 2)
+#define CLK_RTC_HSE		CLK_SRC(RTC, 3)
 
-#define CLK_RTC_DISABLED	0x00001400
-#define CLK_RTC_LSE		0x00001401
-#define CLK_RTC_LSI		0x00001402
-#define CLK_RTC_HSE		0x00001403
+/* Register addresses of MCO1 & MCO2 */
+#define MCO1			0x800
+#define MCO2			0x804
 
-#define CLK_MCO1_HSI		0x00008000
-#define CLK_MCO1_HSE		0x00008001
-#define CLK_MCO1_CSI		0x00008002
-#define CLK_MCO1_LSI		0x00008003
-#define CLK_MCO1_LSE		0x00008004
-#define CLK_MCO1_DISABLED	0x0000800F
+#define MCO_OFF			0
+#define MCO_ON			1
+#define MCO_STATUS_SHIFT	12
 
-#define CLK_MCO2_MPU		0x00008040
-#define CLK_MCO2_AXI		0x00008041
-#define CLK_MCO2_MCU		0x00008042
-#define CLK_MCO2_PLL4P		0x00008043
-#define CLK_MCO2_HSE		0x00008044
-#define CLK_MCO2_HSI		0x00008045
-#define CLK_MCO2_DISABLED	0x0000804F
+#define MCO_ON_CFG(addr, sel)	(CMD_ADDR_BIT |\
+				((addr) << CLK_ADDR_SHIFT) |\
+				(MCO_ON << MCO_STATUS_SHIFT) |\
+				(sel))
 
-/* st,pkcs: peripheral kernel clock source */
+#define MCO_OFF_CFG(addr)	(CMD_ADDR_BIT |\
+				((addr) << CLK_ADDR_SHIFT) |\
+				(MCO_OFF << MCO_STATUS_SHIFT))
 
-#define CLK_I2C12_PCLK1		0x00008C00
-#define CLK_I2C12_PLL4R		0x00008C01
-#define CLK_I2C12_HSI		0x00008C02
-#define CLK_I2C12_CSI		0x00008C03
-#define CLK_I2C12_DISABLED	0x00008C07
+#define CLK_MCO1_HSI		MCO_ON_CFG(MCO1, 0)
+#define CLK_MCO1_HSE		MCO_ON_CFG(MCO1, 1)
+#define CLK_MCO1_CSI		MCO_ON_CFG(MCO1, 2)
+#define CLK_MCO1_LSI		MCO_ON_CFG(MCO1, 3)
+#define CLK_MCO1_LSE		MCO_ON_CFG(MCO1, 4)
+#define CLK_MCO1_DISABLED	MCO_OFF_CFG(MCO1)
 
-#define CLK_I2C35_PCLK1		0x00008C40
-#define CLK_I2C35_PLL4R		0x00008C41
-#define CLK_I2C35_HSI		0x00008C42
-#define CLK_I2C35_CSI		0x00008C43
-#define CLK_I2C35_DISABLED	0x00008C47
+#define CLK_MCO2_MPU		MCO_ON_CFG(MCO2, 0)
+#define CLK_MCO2_AXI		MCO_ON_CFG(MCO2, 1)
+#define CLK_MCO2_MCU		MCO_ON_CFG(MCO2, 2)
+#define CLK_MCO2_PLL4		MCO_ON_CFG(MCO2, 3)
+#define CLK_MCO2_HSE		MCO_ON_CFG(MCO2, 4)
+#define CLK_MCO2_HSI		MCO_ON_CFG(MCO2, 5)
+#define CLK_MCO2_DISABLED	MCO_OFF_CFG(MCO2)
 
-#define CLK_I2C46_PCLK5		0x00000C00
-#define CLK_I2C46_PLL3Q		0x00000C01
-#define CLK_I2C46_HSI		0x00000C02
-#define CLK_I2C46_CSI		0x00000C03
-#define CLK_I2C46_DISABLED	0x00000C07
+#define CLK_I2C12_PCLK1		CLKSRC(MUX_I2C12, 0)
+#define CLK_I2C12_PLL4R		CLKSRC(MUX_I2C12, 1)
+#define CLK_I2C12_HSI		CLKSRC(MUX_I2C12, 2)
+#define CLK_I2C12_CSI		CLKSRC(MUX_I2C12, 3)
+#define CLK_I2C12_DISABLED	CLKSRC(MUX_I2C12, 7)
 
-#define CLK_SAI1_PLL4Q		0x00008C80
-#define CLK_SAI1_PLL3Q		0x00008C81
-#define CLK_SAI1_I2SCKIN	0x00008C82
-#define CLK_SAI1_CKPER		0x00008C83
-#define CLK_SAI1_PLL3R		0x00008C84
-#define CLK_SAI1_DISABLED	0x00008C87
+#define CLK_I2C35_PCLK1		CLKSRC(MUX_I2C35, 0)
+#define CLK_I2C35_PLL4R		CLKSRC(MUX_I2C35, 1)
+#define CLK_I2C35_HSI		CLKSRC(MUX_I2C35, 2)
+#define CLK_I2C35_CSI		CLKSRC(MUX_I2C35, 3)
+#define CLK_I2C35_DISABLED	CLKSRC(MUX_I2C35, 7)
 
-#define CLK_SAI2_PLL4Q		0x00008CC0
-#define CLK_SAI2_PLL3Q		0x00008CC1
-#define CLK_SAI2_I2SCKIN	0x00008CC2
-#define CLK_SAI2_CKPER		0x00008CC3
-#define CLK_SAI2_SPDIF		0x00008CC4
-#define CLK_SAI2_PLL3R		0x00008CC5
-#define CLK_SAI2_DISABLED	0x00008CC7
+#define CLK_I2C46_PCLK5		CLKSRC(MUX_I2C46, 0)
+#define CLK_I2C46_PLL3Q		CLKSRC(MUX_I2C46, 1)
+#define CLK_I2C46_HSI		CLKSRC(MUX_I2C46, 2)
+#define CLK_I2C46_CSI		CLKSRC(MUX_I2C46, 3)
+#define CLK_I2C46_DISABLED	CLKSRC(MUX_I2C46, 7)
 
-#define CLK_SAI3_PLL4Q		0x00008D00
-#define CLK_SAI3_PLL3Q		0x00008D01
-#define CLK_SAI3_I2SCKIN	0x00008D02
-#define CLK_SAI3_CKPER		0x00008D03
-#define CLK_SAI3_PLL3R		0x00008D04
-#define CLK_SAI3_DISABLED	0x00008D07
+#define CLK_SAI1_PLL4Q		CLKSRC(MUX_SAI1, 0)
+#define CLK_SAI1_PLL3Q		CLKSRC(MUX_SAI1, 1)
+#define CLK_SAI1_I2SCKIN	CLKSRC(MUX_SAI1, 2)
+#define CLK_SAI1_CKPER		CLKSRC(MUX_SAI1, 3)
+#define CLK_SAI1_PLL3R		CLKSRC(MUX_SAI1, 4)
+#define CLK_SAI1_DISABLED	CLKSRC(MUX_SAI1, 7)
 
-#define CLK_SAI4_PLL4Q		0x00008D40
-#define CLK_SAI4_PLL3Q		0x00008D41
-#define CLK_SAI4_I2SCKIN	0x00008D42
-#define CLK_SAI4_CKPER		0x00008D43
-#define CLK_SAI4_PLL3R		0x00008D44
-#define CLK_SAI4_DISABLED	0x00008D47
+#define CLK_SAI2_PLL4Q		CLKSRC(MUX_SAI2, 0)
+#define CLK_SAI2_PLL3Q		CLKSRC(MUX_SAI2, 1)
+#define CLK_SAI2_I2SCKIN	CLKSRC(MUX_SAI2, 2)
+#define CLK_SAI2_CKPER		CLKSRC(MUX_SAI2, 3)
+#define CLK_SAI2_SPDIF		CLKSRC(MUX_SAI2, 4)
+#define CLK_SAI2_PLL3R		CLKSRC(MUX_SAI2, 5)
+#define CLK_SAI2_DISABLED	CLKSRC(MUX_SAI2, 7)
 
-#define CLK_SPI2S1_PLL4P	0x00008D80
-#define CLK_SPI2S1_PLL3Q	0x00008D81
-#define CLK_SPI2S1_I2SCKIN	0x00008D82
-#define CLK_SPI2S1_CKPER	0x00008D83
-#define CLK_SPI2S1_PLL3R	0x00008D84
-#define CLK_SPI2S1_DISABLED	0x00008D87
+#define CLK_SAI3_PLL4Q		CLKSRC(MUX_SAI3, 0)
+#define CLK_SAI3_PLL3Q		CLKSRC(MUX_SAI3, 1)
+#define CLK_SAI3_I2SCKIN	CLKSRC(MUX_SAI3, 2)
+#define CLK_SAI3_CKPER		CLKSRC(MUX_SAI3, 3)
+#define CLK_SAI3_PLL3R		CLKSRC(MUX_SAI3, 4)
+#define CLK_SAI3_DISABLED	CLKSRC(MUX_SAI3, 7)
 
-#define CLK_SPI2S23_PLL4P	0x00008DC0
-#define CLK_SPI2S23_PLL3Q	0x00008DC1
-#define CLK_SPI2S23_I2SCKIN	0x00008DC2
-#define CLK_SPI2S23_CKPER	0x00008DC3
-#define CLK_SPI2S23_PLL3R	0x00008DC4
-#define CLK_SPI2S23_DISABLED	0x00008DC7
+#define CLK_SAI4_PLL4Q		CLKSRC(MUX_SAI4, 0)
+#define CLK_SAI4_PLL3Q		CLKSRC(MUX_SAI4, 1)
+#define CLK_SAI4_I2SCKIN	CLKSRC(MUX_SAI4, 2)
+#define CLK_SAI4_CKPER		CLKSRC(MUX_SAI4, 3)
+#define CLK_SAI4_PLL3R		CLKSRC(MUX_SAI4, 4)
+#define CLK_SAI4_DISABLED	CLKSRC(MUX_SAI4, 7)
 
-#define CLK_SPI45_PCLK2		0x00008E00
-#define CLK_SPI45_PLL4Q		0x00008E01
-#define CLK_SPI45_HSI		0x00008E02
-#define CLK_SPI45_CSI		0x00008E03
-#define CLK_SPI45_HSE		0x00008E04
-#define CLK_SPI45_DISABLED	0x00008E07
+#define CLK_SPI2S1_PLL4P	CLKSRC(MUX_SPI2S1, 0)
+#define CLK_SPI2S1_PLL3Q	CLKSRC(MUX_SPI2S1, 1)
+#define CLK_SPI2S1_I2SCKIN	CLKSRC(MUX_SPI2S1, 2)
+#define CLK_SPI2S1_CKPER	CLKSRC(MUX_SPI2S1, 3)
+#define CLK_SPI2S1_PLL3R	CLKSRC(MUX_SPI2S1, 4)
+#define CLK_SPI2S1_DISABLED	CLKSRC(MUX_SPI2S1, 7)
 
-#define CLK_SPI6_PCLK5		0x00000C40
-#define CLK_SPI6_PLL4Q		0x00000C41
-#define CLK_SPI6_HSI		0x00000C42
-#define CLK_SPI6_CSI		0x00000C43
-#define CLK_SPI6_HSE		0x00000C44
-#define CLK_SPI6_PLL3Q		0x00000C45
-#define CLK_SPI6_DISABLED	0x00000C47
+#define CLK_SPI2S23_PLL4P	CLKSRC(MUX_SPI2S23, 0)
+#define CLK_SPI2S23_PLL3Q	CLKSRC(MUX_SPI2S23, 1)
+#define CLK_SPI2S23_I2SCKIN	CLKSRC(MUX_SPI2S23, 2)
+#define CLK_SPI2S23_CKPER	CLKSRC(MUX_SPI2S23, 3)
+#define CLK_SPI2S23_PLL3R	CLKSRC(MUX_SPI2S23, 4)
+#define CLK_SPI2S23_DISABLED	CLKSRC(MUX_SPI2S23, 7)
 
-#define CLK_UART6_PCLK2		0x00008E40
-#define CLK_UART6_PLL4Q		0x00008E41
-#define CLK_UART6_HSI		0x00008E42
-#define CLK_UART6_CSI		0x00008E43
-#define CLK_UART6_HSE		0x00008E44
-#define CLK_UART6_DISABLED	0x00008E47
+#define CLK_SPI45_PCLK2		CLKSRC(MUX_SPI45, 0)
+#define CLK_SPI45_PLL4Q		CLKSRC(MUX_SPI45, 1)
+#define CLK_SPI45_HSI		CLKSRC(MUX_SPI45, 2)
+#define CLK_SPI45_CSI		CLKSRC(MUX_SPI45, 3)
+#define CLK_SPI45_HSE		CLKSRC(MUX_SPI45, 4)
+#define CLK_SPI45_DISABLED	CLKSRC(MUX_SPI45, 7)
 
-#define CLK_UART24_PCLK1	0x00008E80
-#define CLK_UART24_PLL4Q	0x00008E81
-#define CLK_UART24_HSI		0x00008E82
-#define CLK_UART24_CSI		0x00008E83
-#define CLK_UART24_HSE		0x00008E84
-#define CLK_UART24_DISABLED	0x00008E87
+#define CLK_SPI6_PCLK5		CLKSRC(MUX_SPI6, 0)
+#define CLK_SPI6_PLL4Q		CLKSRC(MUX_SPI6, 1)
+#define CLK_SPI6_HSI		CLKSRC(MUX_SPI6, 2)
+#define CLK_SPI6_CSI		CLKSRC(MUX_SPI6, 3)
+#define CLK_SPI6_HSE		CLKSRC(MUX_SPI6, 4)
+#define CLK_SPI6_PLL3Q		CLKSRC(MUX_SPI6, 5)
+#define CLK_SPI6_DISABLED	CLKSRC(MUX_SPI6, 7)
 
-#define CLK_UART35_PCLK1	0x00008EC0
-#define CLK_UART35_PLL4Q	0x00008EC1
-#define CLK_UART35_HSI		0x00008EC2
-#define CLK_UART35_CSI		0x00008EC3
-#define CLK_UART35_HSE		0x00008EC4
-#define CLK_UART35_DISABLED	0x00008EC7
+#define CLK_UART6_PCLK2		CLKSRC(MUX_UART6, 0)
+#define CLK_UART6_PLL4Q		CLKSRC(MUX_UART6, 1)
+#define CLK_UART6_HSI		CLKSRC(MUX_UART6, 2)
+#define CLK_UART6_CSI		CLKSRC(MUX_UART6, 3)
+#define CLK_UART6_HSE		CLKSRC(MUX_UART6, 4)
+#define CLK_UART6_DISABLED	CLKSRC(MUX_UART6, 7)
 
-#define CLK_UART78_PCLK1	0x00008F00
-#define CLK_UART78_PLL4Q	0x00008F01
-#define CLK_UART78_HSI		0x00008F02
-#define CLK_UART78_CSI		0x00008F03
-#define CLK_UART78_HSE		0x00008F04
-#define CLK_UART78_DISABLED	0x00008F07
+#define CLK_UART24_PCLK1	CLKSRC(MUX_UART24, 0)
+#define CLK_UART24_PLL4Q	CLKSRC(MUX_UART24, 1)
+#define CLK_UART24_HSI		CLKSRC(MUX_UART24, 2)
+#define CLK_UART24_CSI		CLKSRC(MUX_UART24, 3)
+#define CLK_UART24_HSE		CLKSRC(MUX_UART24, 4)
+#define CLK_UART24_DISABLED	CLKSRC(MUX_UART24, 7)
 
-#define CLK_UART1_PCLK5		0x00000C80
-#define CLK_UART1_PLL3Q		0x00000C81
-#define CLK_UART1_HSI		0x00000C82
-#define CLK_UART1_CSI		0x00000C83
-#define CLK_UART1_PLL4Q		0x00000C84
-#define CLK_UART1_HSE		0x00000C85
-#define CLK_UART1_DISABLED	0x00000C87
+#define CLK_UART35_PCLK1	CLKSRC(MUX_UART35, 0)
+#define CLK_UART35_PLL4Q	CLKSRC(MUX_UART35, 1)
+#define CLK_UART35_HSI		CLKSRC(MUX_UART35, 2)
+#define CLK_UART35_CSI		CLKSRC(MUX_UART35, 3)
+#define CLK_UART35_HSE		CLKSRC(MUX_UART35, 4)
+#define CLK_UART35_DISABLED	CLKSRC(MUX_UART35, 7)
 
-#define CLK_SDMMC12_HCLK6	0x00008F40
-#define CLK_SDMMC12_PLL3R	0x00008F41
-#define CLK_SDMMC12_PLL4P	0x00008F42
-#define CLK_SDMMC12_HSI		0x00008F43
-#define CLK_SDMMC12_DISABLED	0x00008F47
+#define CLK_UART78_PCLK1	CLKSRC(MUX_UART78, 0)
+#define CLK_UART78_PLL4Q	CLKSRC(MUX_UART78, 1)
+#define CLK_UART78_HSI		CLKSRC(MUX_UART78, 2)
+#define CLK_UART78_CSI		CLKSRC(MUX_UART78, 3)
+#define CLK_UART78_HSE		CLKSRC(MUX_UART78, 4)
+#define CLK_UART78_DISABLED	CLKSRC(MUX_UART78, 7)
 
-#define CLK_SDMMC3_HCLK2	0x00008F80
-#define CLK_SDMMC3_PLL3R	0x00008F81
-#define CLK_SDMMC3_PLL4P	0x00008F82
-#define CLK_SDMMC3_HSI		0x00008F83
-#define CLK_SDMMC3_DISABLED	0x00008F87
+#define CLK_UART1_PCLK5		CLKSRC(MUX_UART1, 0)
+#define CLK_UART1_PLL3Q		CLKSRC(MUX_UART1, 1)
+#define CLK_UART1_HSI		CLKSRC(MUX_UART1, 2)
+#define CLK_UART1_CSI		CLKSRC(MUX_UART1, 3)
+#define CLK_UART1_PLL4Q		CLKSRC(MUX_UART1, 4)
+#define CLK_UART1_HSE		CLKSRC(MUX_UART1, 5)
+#define CLK_UART1_DISABLED	CLKSRC(MUX_UART1, 7)
 
-#define CLK_ETH_PLL4P		0x00008FC0
-#define CLK_ETH_PLL3Q		0x00008FC1
-#define CLK_ETH_DISABLED	0x00008FC3
+#define CLK_SDMMC12_HCLK6	CLKSRC(MUX_SDMMC12, 0)
+#define CLK_SDMMC12_PLL3R	CLKSRC(MUX_SDMMC12, 1)
+#define CLK_SDMMC12_PLL4P	CLKSRC(MUX_SDMMC12, 2)
+#define CLK_SDMMC12_HSI		CLKSRC(MUX_SDMMC12, 3)
+#define CLK_SDMMC12_DISABLED	CLKSRC(MUX_SDMMC12, 7)
 
-#define CLK_QSPI_ACLK		0x00009000
-#define CLK_QSPI_PLL3R		0x00009001
-#define CLK_QSPI_PLL4P		0x00009002
-#define CLK_QSPI_CKPER		0x00009003
+#define CLK_SDMMC3_HCLK2	CLKSRC(MUX_SDMMC3, 0)
+#define CLK_SDMMC3_PLL3R	CLKSRC(MUX_SDMMC3, 1)
+#define CLK_SDMMC3_PLL4P	CLKSRC(MUX_SDMMC3, 2)
+#define CLK_SDMMC3_HSI		CLKSRC(MUX_SDMMC3, 3)
+#define CLK_SDMMC3_DISABLED	CLKSRC(MUX_SDMMC3, 7)
 
-#define CLK_FMC_ACLK		0x00009040
-#define CLK_FMC_PLL3R		0x00009041
-#define CLK_FMC_PLL4P		0x00009042
-#define CLK_FMC_CKPER		0x00009043
+#define CLK_ETH_PLL4P		CLKSRC(MUX_ETH, 0)
+#define CLK_ETH_PLL3Q		CLKSRC(MUX_ETH, 1)
+#define CLK_ETH_DISABLED	CLKSRC(MUX_ETH, 3)
 
-#define CLK_FDCAN_HSE		0x000090C0
-#define CLK_FDCAN_PLL3Q		0x000090C1
-#define CLK_FDCAN_PLL4Q		0x000090C2
-#define CLK_FDCAN_PLL4R		0x000090C3
+#define CLK_QSPI_ACLK		CLKSRC(MUX_QSPI, 0)
+#define CLK_QSPI_PLL3R		CLKSRC(MUX_QSPI, 1)
+#define CLK_QSPI_PLL4P		CLKSRC(MUX_QSPI, 2)
+#define CLK_QSPI_CKPER		CLKSRC(MUX_QSPI, 3)
 
-#define CLK_SPDIF_PLL4P		0x00009140
-#define CLK_SPDIF_PLL3Q		0x00009141
-#define CLK_SPDIF_HSI		0x00009142
-#define CLK_SPDIF_DISABLED	0x00009143
+#define CLK_FMC_ACLK		CLKSRC(MUX_FMC, 0)
+#define CLK_FMC_PLL3R		CLKSRC(MUX_FMC, 1)
+#define CLK_FMC_PLL4P		CLKSRC(MUX_FMC, 2)
+#define CLK_FMC_CKPER		CLKSRC(MUX_FMC, 3)
 
-#define CLK_CEC_LSE		0x00009180
-#define CLK_CEC_LSI		0x00009181
-#define CLK_CEC_CSI_DIV122	0x00009182
-#define CLK_CEC_DISABLED	0x00009183
+#define CLK_FDCAN_HSE		CLKSRC(MUX_FDCAN, 0)
+#define CLK_FDCAN_PLL3Q		CLKSRC(MUX_FDCAN, 1)
+#define CLK_FDCAN_PLL4Q		CLKSRC(MUX_FDCAN, 2)
+#define CLK_FDCAN_PLL4R		CLKSRC(MUX_FDCAN, 3)
 
-#define CLK_USBPHY_HSE		0x000091C0
-#define CLK_USBPHY_PLL4R	0x000091C1
-#define CLK_USBPHY_HSE_DIV2	0x000091C2
-#define CLK_USBPHY_DISABLED	0x000091C3
+#define CLK_SPDIF_PLL4P		CLKSRC(MUX_SPDIF, 0)
+#define CLK_SPDIF_PLL3Q		CLKSRC(MUX_SPDIF, 1)
+#define CLK_SPDIF_HSI		CLKSRC(MUX_SPDIF, 2)
+#define CLK_SPDIF_DISABLED	CLKSRC(MUX_SPDIF, 3)
 
-#define CLK_USBO_PLL4R		0x800091C0
-#define CLK_USBO_USBPHY		0x800091C1
+#define CLK_CEC_LSE		CLKSRC(MUX_CEC, 0)
+#define CLK_CEC_LSI		CLKSRC(MUX_CEC, 1)
+#define CLK_CEC_CSI_DIV122	CLKSRC(MUX_CEC, 2)
+#define CLK_CEC_DISABLED	CLKSRC(MUX_CEC, 3)
 
-#define CLK_RNG1_CSI		0x00000CC0
-#define CLK_RNG1_PLL4R		0x00000CC1
-#define CLK_RNG1_LSE		0x00000CC2
-#define CLK_RNG1_LSI		0x00000CC3
+#define CLK_USBPHY_HSE		CLKSRC(MUX_USBPHY, 0)
+#define CLK_USBPHY_PLL4R	CLKSRC(MUX_USBPHY, 1)
+#define CLK_USBPHY_HSE_DIV2	CLKSRC(MUX_USBPHY, 2)
+#define CLK_USBPHY_DISABLED	CLKSRC(MUX_USBPHY, 3)
 
-#define CLK_RNG2_CSI		0x00009200
-#define CLK_RNG2_PLL4R		0x00009201
-#define CLK_RNG2_LSE		0x00009202
-#define CLK_RNG2_LSI		0x00009203
+#define CLK_USBO_PLL4R		CLKSRC(MUX_USBO, 0)
+#define CLK_USBO_USBPHY		CLKSRC(MUX_USBO, 1)
 
-#define CLK_CKPER_HSI		0x00000D00
-#define CLK_CKPER_CSI		0x00000D01
-#define CLK_CKPER_HSE		0x00000D02
-#define CLK_CKPER_DISABLED	0x00000D03
+#define CLK_RNG1_CSI		CLKSRC(MUX_RNG1, 0)
+#define CLK_RNG1_PLL4R		CLKSRC(MUX_RNG1, 1)
+#define CLK_RNG1_LSE		CLKSRC(MUX_RNG1, 2)
+#define CLK_RNG1_LSI		CLKSRC(MUX_RNG1, 3)
 
-#define CLK_STGEN_HSI		0x00000D40
-#define CLK_STGEN_HSE		0x00000D41
-#define CLK_STGEN_DISABLED	0x00000D43
+#define CLK_RNG2_CSI		CLKSRC(MUX_RNG2, 0)
+#define CLK_RNG2_PLL4R		CLKSRC(MUX_RNG2, 1)
+#define CLK_RNG2_LSE		CLKSRC(MUX_RNG2, 2)
+#define CLK_RNG2_LSI		CLKSRC(MUX_RNG2, 3)
 
-#define CLK_DSI_DSIPLL		0x00009240
-#define CLK_DSI_PLL4P		0x00009241
+#define CLK_CKPER_HSI		CLKSRC(MUX_CKPER, 0)
+#define CLK_CKPER_CSI		CLKSRC(MUX_CKPER, 1)
+#define CLK_CKPER_HSE		CLKSRC(MUX_CKPER, 2)
+#define CLK_CKPER_DISABLED	CLKSRC(MUX_CKPER, 3)
 
-#define CLK_ADC_PLL4R		0x00009280
-#define CLK_ADC_CKPER		0x00009281
-#define CLK_ADC_PLL3Q		0x00009282
-#define CLK_ADC_DISABLED	0x00009283
+#define CLK_STGEN_HSI		CLKSRC(MUX_STGEN, 0)
+#define CLK_STGEN_HSE		CLKSRC(MUX_STGEN, 1)
+#define CLK_STGEN_DISABLED	CLKSRC(MUX_STGEN, 3)
 
-#define CLK_LPTIM45_PCLK3	0x000092C0
-#define CLK_LPTIM45_PLL4P	0x000092C1
-#define CLK_LPTIM45_PLL3Q	0x000092C2
-#define CLK_LPTIM45_LSE		0x000092C3
-#define CLK_LPTIM45_LSI		0x000092C4
-#define CLK_LPTIM45_CKPER	0x000092C5
-#define CLK_LPTIM45_DISABLED	0x000092C7
+#define CLK_DSI_DSIPLL		CLKSRC(MUX_DSI, 0)
+#define CLK_DSI_PLL4P		CLKSRC(MUX_DSI, 1)
 
-#define CLK_LPTIM23_PCLK3	0x00009300
-#define CLK_LPTIM23_PLL4Q	0x00009301
-#define CLK_LPTIM23_CKPER	0x00009302
-#define CLK_LPTIM23_LSE		0x00009303
-#define CLK_LPTIM23_LSI		0x00009304
-#define CLK_LPTIM23_DISABLED	0x00009307
+#define CLK_ADC_PLL4R		CLKSRC(MUX_ADC, 0)
+#define CLK_ADC_CKPER		CLKSRC(MUX_ADC, 1)
+#define CLK_ADC_PLL3Q		CLKSRC(MUX_ADC, 2)
+#define CLK_ADC_DISABLED	CLKSRC(MUX_ADC, 3)
+
+#define CLK_LPTIM45_PCLK3	CLKSRC(MUX_LPTIM45, 0)
+#define CLK_LPTIM45_PLL4P	CLKSRC(MUX_LPTIM45, 1)
+#define CLK_LPTIM45_PLL3Q	CLKSRC(MUX_LPTIM45, 2)
+#define CLK_LPTIM45_LSE		CLKSRC(MUX_LPTIM45, 3)
+#define CLK_LPTIM45_LSI		CLKSRC(MUX_LPTIM45, 4)
+#define CLK_LPTIM45_CKPER	CLKSRC(MUX_LPTIM45, 5)
+#define CLK_LPTIM45_DISABLED	CLKSRC(MUX_LPTIM45, 7)
+
+#define CLK_LPTIM23_PCLK3	CLKSRC(MUX_LPTIM23, 0)
+#define CLK_LPTIM23_PLL4Q	CLKSRC(MUX_LPTIM23, 1)
+#define CLK_LPTIM23_CKPER	CLKSRC(MUX_LPTIM23, 2)
+#define CLK_LPTIM23_LSE		CLKSRC(MUX_LPTIM23, 3)
+#define CLK_LPTIM23_LSI		CLKSRC(MUX_LPTIM23, 4)
+#define CLK_LPTIM23_DISABLED	CLKSRC(MUX_LPTIM23, 7)
 
-#define CLK_LPTIM1_PCLK1	0x00009340
-#define CLK_LPTIM1_PLL4P	0x00009341
-#define CLK_LPTIM1_PLL3Q	0x00009342
-#define CLK_LPTIM1_LSE		0x00009343
-#define CLK_LPTIM1_LSI		0x00009344
-#define CLK_LPTIM1_CKPER	0x00009345
-#define CLK_LPTIM1_DISABLED	0x00009347
+#define CLK_LPTIM1_PCLK1	CLKSRC(MUX_LPTIM1, 0)
+#define CLK_LPTIM1_PLL4P	CLKSRC(MUX_LPTIM1, 1)
+#define CLK_LPTIM1_PLL3Q	CLKSRC(MUX_LPTIM1, 2)
+#define CLK_LPTIM1_LSE		CLKSRC(MUX_LPTIM1, 3)
+#define CLK_LPTIM1_LSI		CLKSRC(MUX_LPTIM1, 4)
+#define CLK_LPTIM1_CKPER	CLKSRC(MUX_LPTIM1, 5)
+#define CLK_LPTIM1_DISABLED	CLKSRC(MUX_LPTIM1, 7)
 
 /* define for st,pll /csg */
 #define SSCG_MODE_CENTER_SPREAD	0
diff --git a/include/dt-bindings/gpio/stm32-gpio.h b/include/dt-bindings/gpio/stm32-gpio.h
new file mode 100644
index 0000000..2c7a0f1
--- /dev/null
+++ b/include/dt-bindings/gpio/stm32-gpio.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2024 STMicroelectronics - All Rights Reserved
+ * Author: Paillet Pascal <p.paillet@foss.st.com> for STMicroelectronics.
+ */
+
+#ifndef DT_BINDINGS_STM32_GPIO_H
+#define DT_BINDINGS_STM32_GPIO_H
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A			0U
+#define GPIO_BANK_B			1U
+#define GPIO_BANK_C			2U
+#define GPIO_BANK_D			3U
+#define GPIO_BANK_E			4U
+#define GPIO_BANK_F			5U
+#define GPIO_BANK_G			6U
+#define GPIO_BANK_H			7U
+#define GPIO_BANK_I			8U
+#define GPIO_BANK_J			9U
+#define GPIO_BANK_K			10U
+#define GPIO_BANK_Z			25U
+
+/* Bit 0 is used to set GPIO in input mode */
+#define GPIOF_DIR_OUT			0x0
+#define GPIOF_DIR_IN			0x1
+
+/* Bit 1 is used to set GPIO high level during init */
+#define GPIOF_INIT_LOW			0x0
+#define GPIOF_INIT_HIGH			0x2
+
+#define GPIOF_IN			(GPIOF_DIR_IN)
+#define GPIOF_OUT_INIT_LOW		(GPIOF_DIR_OUT | GPIOF_INIT_LOW)
+#define GPIOF_OUT_INIT_HIGH		(GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
+
+/* Bit 2 is used to set GPIO pull up */
+#define GPIOF_PULL_UP			0x4
+/* Bit 3 is used to set GPIO pull down */
+#define GPIOF_PULL_DOWN			0x8
+
+#endif /* DT_BINDINGS_STM32_GPIO_H */
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
index 366894d..c7f50db 100644
--- a/include/lib/cpus/aarch64/cortex_a715.h
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -13,6 +13,11 @@
 #define CORTEX_A715_BHB_LOOP_COUNT				U(38)
 
 /*******************************************************************************
+ * CPU Auxiliary Control register 1 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A715_CPUACTLR_EL1				S3_0_C15_C1_0
+
+/*******************************************************************************
  * CPU Auxiliary Control register 2 specific definitions.
  ******************************************************************************/
 #define CORTEX_A715_CPUACTLR2_EL1				S3_0_C15_C1_1
@@ -22,6 +27,11 @@
  ******************************************************************************/
 #define CORTEX_A715_CPUECTLR_EL1				S3_0_C15_C1_4
 
+#define CORTEX_A715_CPUPSELR_EL3				S3_6_C15_C8_0
+#define CORTEX_A715_CPUPCR_EL3					S3_6_C15_C8_1
+#define CORTEX_A715_CPUPOR_EL3					S3_6_C15_C8_2
+#define CORTEX_A715_CPUPMR_EL3					S3_6_C15_C8_3
+
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a720.h b/include/lib/cpus/aarch64/cortex_a720.h
index 47bbbc0..fb27f79 100644
--- a/include/lib/cpus/aarch64/cortex_a720.h
+++ b/include/lib/cpus/aarch64/cortex_a720.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,16 @@
 #define CORTEX_A720_BHB_LOOP_COUNT				U(132)
 
 /*******************************************************************************
+ * CPU Auxiliary Control register 1 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A720_CPUACTLR_EL1				S3_0_C15_C1_0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A720_CPUACTLR2_EL1				S3_0_C15_C1_1
+
+/*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
 #define CORTEX_A720_CPUECTLR_EL1				S3_0_C15_C1_4
diff --git a/include/lib/cpus/aarch64/cortex_a725.h b/include/lib/cpus/aarch64/cortex_a725.h
new file mode 100644
index 0000000..123c5ab
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a725.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A725_H
+#define CORTEX_A725_H
+
+#define CORTEX_A725_MIDR					U(0x410FD870)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A725_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A725_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A725_H */
diff --git a/include/lib/cpus/aarch64/cortex_blackhawk.h b/include/lib/cpus/aarch64/cortex_blackhawk.h
deleted file mode 100644
index bfb3039..0000000
--- a/include/lib/cpus/aarch64/cortex_blackhawk.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_BLACKHAWK_H
-#define CORTEX_BLACKHAWK_H
-
-#define CORTEX_BLACKHAWK_MIDR					U(0x410FD850)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_BLACKHAWK_H */
diff --git a/include/lib/cpus/aarch64/cortex_chaberton.h b/include/lib/cpus/aarch64/cortex_chaberton.h
deleted file mode 100644
index 8f10b68..0000000
--- a/include/lib/cpus/aarch64/cortex_chaberton.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_CHABERTON_H
-#define CORTEX_CHABERTON_H
-
-#define CORTEX_CHABERTON_MIDR					U(0x410FD870)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_CHABERTON_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_CHABERTON_H */
diff --git a/include/lib/cpus/aarch64/cortex_x4.h b/include/lib/cpus/aarch64/cortex_x4.h
index 17d07c8..433687b 100644
--- a/include/lib/cpus/aarch64/cortex_x4.h
+++ b/include/lib/cpus/aarch64/cortex_x4.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,4 +23,9 @@
 #define CORTEX_X4_CPUPWRCTLR_EL1			S3_0_C15_C2_7
 #define CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+/*******************************************************************************
+ * CPU Auxiliary control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUACTLR3_EL1				S3_0_C15_C1_2
+
 #endif /* CORTEX_X4_H */
diff --git a/include/lib/cpus/aarch64/cortex_x925.h b/include/lib/cpus/aarch64/cortex_x925.h
new file mode 100644
index 0000000..38aafcf
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x925.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X925_H
+#define CORTEX_X925_H
+
+#define CORTEX_X925_MIDR					U(0x410FD850)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_X925_H */
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index 577de61..51fbfd1 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -30,6 +30,7 @@
  * DSU Cluster Auxiliary Control registers definitions
  ********************************************************************/
 #define CLUSTERACTLR_EL1	S3_0_C15_C3_3
+#define CLUSTERPWRCTLR_EL1	S3_0_C15_C3_5
 
 #define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING	(ULL(1) << 15)
 #define CLUSTERACTLR_EL1_DISABLE_SCLK_GATING	(ULL(3) << 15)
@@ -39,4 +40,7 @@
  ********************************************************************/
 #define DSU_ERRATA_936184_MASK	(U(0x3) << 15)
 
+#ifndef __ASSEMBLER__
+void dsu_pwr_dwn(void);
+#endif
 #endif /* DSU_DEF_H */
diff --git a/include/lib/cpus/aarch64/neoverse_hermes.h b/include/lib/cpus/aarch64/neoverse_hermes.h
deleted file mode 100644
index 22492c3..0000000
--- a/include/lib/cpus/aarch64/neoverse_hermes.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef NEOVERSE_HERMES_H
-#define NEOVERSE_HERMES_H
-
-#define NEOVERSE_HERMES_MIDR				U(0x410FD8E0)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_HERMES_CPUECTLR_EL1			S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_HERMES_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
-
-#endif /* NEOVERSE_HERMES_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n3.h b/include/lib/cpus/aarch64/neoverse_n3.h
new file mode 100644
index 0000000..9196330
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_n3.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_N3_H
+#define NEOVERSE_N3_H
+
+#define NEOVERSE_N3_MIDR				U(0x410FD8E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_N3_CPUECTLR_EL1			S3_0_C15_C1_4
+#define NEOVERSE_N3_CPUECTLR_EL1_EXTLLC_BIT		(ULL(1) << 0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_N3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_N3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* NEOVERSE_N3_H */
diff --git a/include/lib/cpus/aarch64/neoverse_poseidon.h b/include/lib/cpus/aarch64/neoverse_poseidon.h
deleted file mode 100644
index 117826d..0000000
--- a/include/lib/cpus/aarch64/neoverse_poseidon.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef NEOVERSE_POSEIDON_H
-#define NEOVERSE_POSEIDON_H
-
-
-#define NEOVERSE_POSEIDON_VNAE_MIDR				U(0x410FD830)
-#define NEOVERSE_POSEIDON_V_MIDR				U(0x410FD840)
-
-/* Neoverse Poseidon loop count for CVE-2022-23960 mitigation */
-#define NEOVERSE_POSEIDON_BHB_LOOP_COUNT			U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions.
- ******************************************************************************/
-#define NEOVERSE_POSEIDON_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_POSEIDON_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define NEOVERSE_POSEIDON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* NEOVERSE_POSEIDON_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
index 39a6607..1171e95 100644
--- a/include/lib/cpus/aarch64/neoverse_v2.h
+++ b/include/lib/cpus/aarch64/neoverse_v2.h
@@ -16,6 +16,7 @@
  * CPU Extended Control register specific definitions
  ******************************************************************************/
 #define NEOVERSE_V2_CPUECTLR_EL1			S3_0_C15_C1_4
+#define NEOVERSE_V2_CPUECTLR_EL1_EXTLLC_BIT		(ULL(1) << 0)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
diff --git a/include/lib/cpus/aarch64/neoverse_v3.h b/include/lib/cpus/aarch64/neoverse_v3.h
new file mode 100644
index 0000000..e5f75ba
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_v3.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_V3_H
+#define NEOVERSE_V3_H
+
+
+#define NEOVERSE_V3_VNAE_MIDR				U(0x410FD830)
+#define NEOVERSE_V3_MIDR				U(0x410FD840)
+
+/* Neoverse V3 loop count for CVE-2022-23960 mitigation */
+#define NEOVERSE_V3_BHB_LOOP_COUNT			U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_V3_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_V3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* NEOVERSE_V3_H */
diff --git a/include/lib/debugfs.h b/include/lib/debugfs.h
index 8ed237a..1fdccb6 100644
--- a/include/lib/debugfs.h
+++ b/include/lib/debugfs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -61,11 +61,23 @@
 /* Debugfs version returned through SMC interface */
 #define DEBUGFS_VERSION		(0x000000001U)
 
-/* Function ID for accessing the debugfs interface */
-#define DEBUGFS_FID_VALUE	(0x30U)
+/* Function ID for accessing the debugfs interface from
+ * Vendor-Specific EL3 Range.
+ */
+#define DEBUGFS_FID_VALUE	(0x10U)
+
+#define is_debugfs_fid(_fid) \
+	(GET_SMC_NUM(_fid) == DEBUGFS_FID_VALUE)
+
+
+/* Function ID for accessing the debugfs interface from arm sip.
+ * This is now deprecated FID and will be removed after 2.12 release.
+ */
+#define DEBUGFS_FID_VALUE_DEPRECATED	(0x30U)
+
+#define is_debugfs_fid_deprecated(_fid)	\
+	(GET_SMC_NUM(_fid) == DEBUGFS_FID_VALUE_DEPRECATED)
 
-#define is_debugfs_fid(_fid)	\
-	(((_fid) & FUNCID_NUM_MASK) == DEBUGFS_FID_VALUE)
 
 /* Error code for debugfs SMC interface failures */
 #define DEBUGFS_E_INVALID_PARAMS	(-2)
diff --git a/include/lib/dice/dice.h b/include/lib/dice/dice.h
new file mode 100644
index 0000000..cf54942
--- /dev/null
+++ b/include/lib/dice/dice.h
@@ -0,0 +1,166 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#ifndef DICE_DICE_H_
+#define DICE_DICE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DICE_CDI_SIZE 32
+#define DICE_HASH_SIZE 64
+#define DICE_HIDDEN_SIZE 64
+#define DICE_INLINE_CONFIG_SIZE 64
+#define DICE_PRIVATE_KEY_SEED_SIZE 32
+#define DICE_ID_SIZE 20
+
+typedef enum {
+  kDiceResultOk,
+  kDiceResultInvalidInput,
+  kDiceResultBufferTooSmall,
+  kDiceResultPlatformError,
+} DiceResult;
+
+typedef enum {
+  kDiceModeNotInitialized,
+  kDiceModeNormal,
+  kDiceModeDebug,
+  kDiceModeMaintenance,
+} DiceMode;
+
+typedef enum {
+  kDiceConfigTypeInline,
+  kDiceConfigTypeDescriptor,
+} DiceConfigType;
+
+// Contains a full set of input values describing the target program or system.
+// See the Open Profile for DICE specification for a detailed explanation of
+// these inputs.
+//
+// Fields:
+//    code_hash: A hash or similar representation of the target code.
+//    code_descriptor: An optional descriptor to be included in the certificate.
+//        This descriptor is opaque to the DICE flow and is included verbatim
+//        in the certificate with no validation. May be null.
+//    code_descriptor_size: The size in bytes of |code_descriptor|.
+//    config_type: Indicates how to interpret the remaining config-related
+//        fields. If the type is 'inline', then the 64 byte configuration input
+//        value must be provided in |config_value| and |config_descriptor| is
+//        ignored. If the type is 'descriptor', then |config_descriptor| is
+//        hashed to get the configuration input value and |config_value| is
+//        ignored.
+//    config_value: A 64-byte configuration input value when |config_type| is
+//        kDiceConfigTypeInline. Otherwise, this field is ignored.
+//    config_descriptor: A descriptor to be hashed for the configuration input
+//        value when |config_type| is kDiceConfigTypeDescriptor. Otherwise,
+//        this field is ignored and may be null.
+//    config_descriptor_size: The size in bytes of |config_descriptor|.
+//    authority_hash: A hash or similar representation of the authority used to
+//        verify the target code. If the code is not verified or the authority
+//        is implicit, for example hard coded as part of the code currently
+//        executing, then this value should be set to all zero bytes.
+//    authority_descriptor: An optional descriptor to be included in the
+//        certificate. This descriptor is opaque to the DICE flow and is
+//        included verbatim in the certificate with no validation. May be null.
+//    authority_descriptor_size: The size in bytes of |authority_descriptor|.
+//    mode: The current operating mode.
+//    hidden: Additional input which will not appear in certificates. If this is
+//        not used it should be set to all zero bytes.
+typedef struct DiceInputValues_ {
+  uint8_t code_hash[DICE_HASH_SIZE];
+  const uint8_t* code_descriptor;
+  size_t code_descriptor_size;
+  DiceConfigType config_type;
+  uint8_t config_value[DICE_INLINE_CONFIG_SIZE];
+  const uint8_t* config_descriptor;
+  size_t config_descriptor_size;
+  uint8_t authority_hash[DICE_HASH_SIZE];
+  const uint8_t* authority_descriptor;
+  size_t authority_descriptor_size;
+  DiceMode mode;
+  uint8_t hidden[DICE_HIDDEN_SIZE];
+} DiceInputValues;
+
+// Derives a |cdi_private_key_seed| from a |cdi_attest| value. On success
+// populates |cdi_private_key_seed| and returns kDiceResultOk.
+DiceResult DiceDeriveCdiPrivateKeySeed(
+    void* context, const uint8_t cdi_attest[DICE_CDI_SIZE],
+    uint8_t cdi_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE]);
+
+// Derives an |id| from a |cdi_public_key| value. Because public keys can vary
+// in length depending on the algorithm, the |cdi_public_key_size| in bytes must
+// be provided. When interpreted as an integer, |id| is big-endian. On success
+// populates |id| and returns kDiceResultOk.
+DiceResult DiceDeriveCdiCertificateId(void* context,
+                                      const uint8_t* cdi_public_key,
+                                      size_t cdi_public_key_size,
+                                      uint8_t id[DICE_ID_SIZE]);
+
+// Executes the main DICE flow.
+//
+// Given a full set of input values and the current CDI values, computes the
+// next CDI values and a matching certificate. See the Open Profile for DICE
+// specification for a detailed explanation of this flow.
+// In certain cases, the caller may not need to generate the CDI certificate.
+// The caller should signal this by setting the certificate parameters to
+// null/zero values appropriately.
+//
+// Parameters:
+//    context: Context provided by the caller that is opaque to this library
+//        but is passed through to the integration-provided operations in
+//        dice/ops.h. The value is, therefore, integration-specific and may be
+//        null.
+//    current_cdi_attest, current_cdi_seal: The current CDI values as produced
+//        by a previous DICE flow. If this is the first DICE flow in a system,
+//        the Unique Device Secret (UDS) should be used for both of these
+//        arguments.
+//    input_values: A set of input values describing the target program or
+//        system.
+//    next_cdi_certificate_buffer_size: The size in bytes of the buffer pointed
+//        to by the |next_cdi_certificate| argument. This should be set to zero
+//        if next CDI certificate should not be computed.
+//    next_cdi_certificate: On success, will be populated with the generated
+//        certificate, up to |next_cdi_certificate_buffer_size| in size. If the
+//        certificate cannot fit in the buffer, |next_cdi_certificate_size| is
+//        populated with the required size and kDiceResultBufferTooSmall is
+//        returned. This should be set to NULL if next CDI certificate should
+//        not be computed.
+//    next_cdi_certificate_actual_size: On success, will be populated with the
+//        size, in bytes, of the certificate data written to
+//        |next_cdi_certificate|. If kDiceResultBufferTooSmall is returned, will
+//        be populated with the required buffer size. This should be set to NULL
+//        if next CDI certificate should not be computed.
+//    next_cdi_attest: On success, will be populated with the next CDI value for
+//        attestation.
+//    next_cdi_seal: On success, will be populated with the next CDI value for
+//        sealing.
+DiceResult DiceMainFlow(void* context,
+                        const uint8_t current_cdi_attest[DICE_CDI_SIZE],
+                        const uint8_t current_cdi_seal[DICE_CDI_SIZE],
+                        const DiceInputValues* input_values,
+                        size_t next_cdi_certificate_buffer_size,
+                        uint8_t* next_cdi_certificate,
+                        size_t* next_cdi_certificate_actual_size,
+                        uint8_t next_cdi_attest[DICE_CDI_SIZE],
+                        uint8_t next_cdi_seal[DICE_CDI_SIZE]);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // DICE_DICE_H_
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index d5bd890..acf111b 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -7,6 +7,7 @@
 #ifndef CONTEXT_H
 #define CONTEXT_H
 
+#include <lib/el3_runtime/context_el2.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/utils_def.h>
 
@@ -62,19 +63,20 @@
 #define CTX_ELR_EL3		U(0x20)
 #define CTX_PMCR_EL0		U(0x28)
 #define CTX_IS_IN_EL3		U(0x30)
+#define CTX_MDCR_EL3		U(0x38)
 /* Constants required in supporting nested exception in EL3 */
-#define CTX_SAVED_ELR_EL3	U(0x38)
+#define CTX_SAVED_ELR_EL3	U(0x40)
 /*
  * General purpose flag, to save various EL3 states
  * FFH mode : Used to identify if handling nested exception
  * KFH mode : Used as counter value
  */
-#define CTX_NESTED_EA_FLAG	U(0x40)
+#define CTX_NESTED_EA_FLAG	U(0x48)
 #if FFH_SUPPORT
- #define CTX_SAVED_ESR_EL3	U(0x48)
- #define CTX_SAVED_SPSR_EL3	U(0x50)
- #define CTX_SAVED_GPREG_LR	U(0x58)
- #define CTX_EL3STATE_END	U(0x60) /* Align to the next 16 byte boundary */
+ #define CTX_SAVED_ESR_EL3	U(0x50)
+ #define CTX_SAVED_SPSR_EL3	U(0x58)
+ #define CTX_SAVED_GPREG_LR	U(0x60)
+ #define CTX_EL3STATE_END	U(0x70) /* Align to the next 16 byte boundary */
 #else
  #define CTX_EL3STATE_END	U(0x50) /* Align to the next 16 byte boundary */
 #endif /* FFH_SUPPORT */
@@ -108,21 +110,25 @@
 #define CTX_AFSR1_EL1		U(0x98)
 #define CTX_CONTEXTIDR_EL1	U(0xa0)
 #define CTX_VBAR_EL1		U(0xa8)
+#define CTX_MDCCINT_EL1		U(0xb0)
+#define CTX_MDSCR_EL1		U(0xb8)
+
+#define CTX_AARCH64_END		U(0xc0) /* Align to the next 16 byte boundary */
 
 /*
  * If the platform is AArch64-only, there is no need to save and restore these
  * AArch32 registers.
  */
 #if CTX_INCLUDE_AARCH32_REGS
-#define CTX_SPSR_ABT		U(0xb0)	/* Align to the next 16 byte boundary */
-#define CTX_SPSR_UND		U(0xb8)
-#define CTX_SPSR_IRQ		U(0xc0)
-#define CTX_SPSR_FIQ		U(0xc8)
-#define CTX_DACR32_EL2		U(0xd0)
-#define CTX_IFSR32_EL2		U(0xd8)
-#define CTX_AARCH32_END		U(0xe0) /* Align to the next 16 byte boundary */
+#define CTX_SPSR_ABT		(CTX_AARCH64_END + U(0x0))
+#define CTX_SPSR_UND		(CTX_AARCH64_END + U(0x8))
+#define CTX_SPSR_IRQ		(CTX_AARCH64_END + U(0x10))
+#define CTX_SPSR_FIQ		(CTX_AARCH64_END + U(0x18))
+#define CTX_DACR32_EL2		(CTX_AARCH64_END + U(0x20))
+#define CTX_IFSR32_EL2		(CTX_AARCH64_END + U(0x28))
+#define CTX_AARCH32_END		(CTX_AARCH64_END + U(0x30)) /* Align to the next 16 byte boundary */
 #else
-#define CTX_AARCH32_END		U(0xb0)	/* Align to the next 16 byte boundary */
+#define CTX_AARCH32_END		CTX_AARCH64_END
 #endif /* CTX_INCLUDE_AARCH32_REGS */
 
 /*
@@ -140,119 +146,87 @@
 #define CTX_TIMER_SYSREGS_END	CTX_AARCH32_END
 #endif /* NS_TIMER_SWITCH */
 
-#if ENABLE_FEAT_MTE
+#if ENABLE_FEAT_MTE2
 #define CTX_TFSRE0_EL1		(CTX_TIMER_SYSREGS_END + U(0x0))
 #define CTX_TFSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x8))
 #define CTX_RGSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x10))
 #define CTX_GCR_EL1		(CTX_TIMER_SYSREGS_END + U(0x18))
-
-/* Align to the next 16 byte boundary */
-#define CTX_MTE_REGS_END	(CTX_TIMER_SYSREGS_END + U(0x20))
+#define CTX_MTE_REGS_END	(CTX_TIMER_SYSREGS_END + U(0x20)) /* Align to the next 16 byte boundary */
 #else
 #define CTX_MTE_REGS_END	CTX_TIMER_SYSREGS_END
-#endif /* ENABLE_FEAT_MTE */
-
-/*
- * End of system registers.
- */
-#define CTX_EL1_SYSREGS_END		CTX_MTE_REGS_END
-
-/*
- * EL2 register set
- */
-
-#if CTX_INCLUDE_EL2_REGS
-/* For later discussion
- * ICH_AP0R<n>_EL2
- * ICH_AP1R<n>_EL2
- * AMEVCNTVOFF0<n>_EL2
- * AMEVCNTVOFF1<n>_EL2
- * ICH_LR<n>_EL2
- */
-#define CTX_EL2_SYSREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
+#endif /* ENABLE_FEAT_MTE2 */
 
-#define CTX_ACTLR_EL2		U(0x0)
-#define CTX_AFSR0_EL2		U(0x8)
-#define CTX_AFSR1_EL2		U(0x10)
-#define CTX_AMAIR_EL2		U(0x18)
-#define CTX_CNTHCTL_EL2		U(0x20)
-#define CTX_CNTVOFF_EL2		U(0x28)
-#define CTX_CPTR_EL2		U(0x30)
-#define CTX_DBGVCR32_EL2	U(0x38)
-#define CTX_ELR_EL2		U(0x40)
-#define CTX_ESR_EL2		U(0x48)
-#define CTX_FAR_EL2		U(0x50)
-#define CTX_HACR_EL2		U(0x58)
-#define CTX_HCR_EL2		U(0x60)
-#define CTX_HPFAR_EL2		U(0x68)
-#define CTX_HSTR_EL2		U(0x70)
-#define CTX_ICC_SRE_EL2		U(0x78)
-#define CTX_ICH_HCR_EL2		U(0x80)
-#define CTX_ICH_VMCR_EL2	U(0x88)
-#define CTX_MAIR_EL2		U(0x90)
-#define CTX_MDCR_EL2		U(0x98)
-#define CTX_PMSCR_EL2		U(0xa0)
-#define CTX_SCTLR_EL2		U(0xa8)
-#define CTX_SPSR_EL2		U(0xb0)
-#define CTX_SP_EL2		U(0xb8)
-#define CTX_TCR_EL2		U(0xc0)
-#define CTX_TPIDR_EL2		U(0xc8)
-#define CTX_TTBR0_EL2		U(0xd0)
-#define CTX_VBAR_EL2		U(0xd8)
-#define CTX_VMPIDR_EL2		U(0xe0)
-#define CTX_VPIDR_EL2		U(0xe8)
-#define CTX_VTCR_EL2		U(0xf0)
-#define CTX_VTTBR_EL2		U(0xf8)
+#if ENABLE_FEAT_RAS
+#define CTX_DISR_EL1		(CTX_MTE_REGS_END + U(0x0))
+#define CTX_RAS_REGS_END	(CTX_MTE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_RAS_REGS_END        CTX_MTE_REGS_END
+#endif /* ENABLE_FEAT_RAS */
 
-// Only if MTE registers in use
-#define CTX_TFSR_EL2		U(0x100)
+#if ENABLE_FEAT_S1PIE
+#define CTX_PIRE0_EL1		(CTX_RAS_REGS_END + U(0x0))
+#define CTX_PIR_EL1		(CTX_RAS_REGS_END + U(0x8))
+#define CTX_S1PIE_REGS_END	(CTX_RAS_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_S1PIE_REGS_END	CTX_RAS_REGS_END
+#endif /* ENABLE_FEAT_S1PIE */
 
-// Starting with Armv8.6
-#define CTX_HDFGRTR_EL2		U(0x108)
-#define CTX_HAFGRTR_EL2		U(0x110)
-#define CTX_HDFGWTR_EL2		U(0x118)
-#define CTX_HFGITR_EL2		U(0x120)
-#define CTX_HFGRTR_EL2		U(0x128)
-#define CTX_HFGWTR_EL2		U(0x130)
-#define CTX_CNTPOFF_EL2		U(0x138)
+#if ENABLE_FEAT_S1POE
+#define CTX_POR_EL1		(CTX_S1PIE_REGS_END + U(0x0))
+#define CTX_S1POE_REGS_END	(CTX_S1PIE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_S1POE_REGS_END	CTX_S1PIE_REGS_END
+#endif /* ENABLE_FEAT_S1POE */
 
-// Starting with Armv8.4
-#define CTX_CONTEXTIDR_EL2	U(0x140)
-#define CTX_TTBR1_EL2		U(0x148)
-#define CTX_VDISR_EL2		U(0x150)
-#define CTX_VSESR_EL2		U(0x158)
-#define CTX_VNCR_EL2		U(0x160)
-#define CTX_TRFCR_EL2		U(0x168)
+#if ENABLE_FEAT_S2POE
+#define CTX_S2POR_EL1		(CTX_S1POE_REGS_END + U(0x0))
+#define CTX_S2POE_REGS_END	(CTX_S1POE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_S2POE_REGS_END	CTX_S1POE_REGS_END
+#endif /* ENABLE_FEAT_S2POE */
 
-// Starting with Armv8.5
-#define CTX_SCXTNUM_EL2		U(0x170)
+#if ENABLE_FEAT_TCR2
+#define CTX_TCR2_EL1		(CTX_S2POE_REGS_END + U(0x0))
+#define CTX_TCR2_REGS_END	(CTX_S2POE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_TCR2_REGS_END       CTX_S2POE_REGS_END
+#endif /* ENABLE_FEAT_TCR2 */
 
-// Register for FEAT_HCX
-#define CTX_HCRX_EL2            U(0x178)
+#if ENABLE_TRF_FOR_NS
+#define CTX_TRFCR_EL1		(CTX_TCR2_REGS_END + U(0x0))
+#define CTX_TRF_REGS_END	(CTX_TCR2_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_TRF_REGS_END	CTX_TCR2_REGS_END
+#endif /* ENABLE_TRF_FOR_NS */
 
-// Starting with Armv8.9
-#define CTX_TCR2_EL2            U(0x180)
-#define CTX_POR_EL2             U(0x188)
-#define CTX_PIRE0_EL2           U(0x190)
-#define CTX_PIR_EL2             U(0x198)
-#define CTX_S2PIR_EL2		U(0x1a0)
-#define CTX_GCSCR_EL2           U(0x1a8)
-#define CTX_GCSPR_EL2           U(0x1b0)
+#if ENABLE_FEAT_CSV2_2
+#define CTX_SCXTNUM_EL0		(CTX_TRF_REGS_END + U(0x0))
+#define CTX_SCXTNUM_EL1		(CTX_TRF_REGS_END + U(0x8))
+#define CTX_CSV2_2_REGS_END	(CTX_TRF_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_CSV2_2_REGS_END	CTX_TRF_REGS_END
+#endif /* ENABLE_FEAT_CSV2_2 */
 
-/* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END	U(0x1c0)
+#if ENABLE_FEAT_GCS
+#define CTX_GCSCR_EL1		(CTX_CSV2_2_REGS_END + U(0x0))
+#define CTX_GCSCRE0_EL1		(CTX_CSV2_2_REGS_END + U(0x8))
+#define CTX_GCSPR_EL1		(CTX_CSV2_2_REGS_END + U(0x10))
+#define CTX_GCSPR_EL0		(CTX_CSV2_2_REGS_END + U(0x18))
+#define CTX_GCS_REGS_END	(CTX_CSV2_2_REGS_END + U(0x20)) /* Align to the next 16 byte boundary */
+#else
+#define CTX_GCS_REGS_END	CTX_CSV2_2_REGS_END
+#endif /* ENABLE_FEAT_GCS */
 
-#endif /* CTX_INCLUDE_EL2_REGS */
+/*
+ * End of EL1 system registers.
+ */
+#define CTX_EL1_SYSREGS_END	CTX_GCS_REGS_END
 
 /*******************************************************************************
  * Constants that allow assembler code to access members of and the 'fp_regs'
  * structure at their correct offsets.
  ******************************************************************************/
-#if CTX_INCLUDE_EL2_REGS
-# define CTX_FPREGS_OFFSET	(CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END)
-#else
 # define CTX_FPREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
-#endif
 #if CTX_INCLUDE_FPREGS
 #define CTX_FP_Q0		U(0x0)
 #define CTX_FP_Q1		U(0x10)
@@ -293,10 +267,10 @@
 #define CTX_FPREGS_END		U(0x220) /* Align to the next 16 byte boundary */
 #else
 #define CTX_FPREGS_END		U(0x210) /* Align to the next 16 byte boundary */
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
 #else
 #define CTX_FPREGS_END		U(0)
-#endif
+#endif /* CTX_INCLUDE_FPREGS */
 
 /*******************************************************************************
  * Registers related to CVE-2018-3639
@@ -326,27 +300,6 @@
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 /*******************************************************************************
- * Registers related to ARMv8.2-MPAM.
- ******************************************************************************/
-#define CTX_MPAM_REGS_OFFSET	(CTX_PAUTH_REGS_OFFSET + CTX_PAUTH_REGS_END)
-#if CTX_INCLUDE_MPAM_REGS
-#define CTX_MPAM2_EL2		U(0x0)
-#define CTX_MPAMHCR_EL2		U(0x8)
-#define CTX_MPAMVPM0_EL2	U(0x10)
-#define CTX_MPAMVPM1_EL2	U(0x18)
-#define CTX_MPAMVPM2_EL2	U(0x20)
-#define CTX_MPAMVPM3_EL2	U(0x28)
-#define CTX_MPAMVPM4_EL2	U(0x30)
-#define CTX_MPAMVPM5_EL2	U(0x38)
-#define CTX_MPAMVPM6_EL2	U(0x40)
-#define CTX_MPAMVPM7_EL2	U(0x48)
-#define CTX_MPAMVPMV_EL2	U(0x50)
-#define CTX_MPAM_REGS_END	U(0x60)
-#else
-#define CTX_MPAM_REGS_END	U(0x0)
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-/*******************************************************************************
  * Registers initialised in a per-world context.
  ******************************************************************************/
 #define CTX_CPTR_EL3			U(0x0)
@@ -373,9 +326,7 @@
 /* Constants to determine the size of individual context structures */
 #define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
 #define CTX_EL1_SYSREGS_ALL	(CTX_EL1_SYSREGS_END >> DWORD_SHIFT)
-#if CTX_INCLUDE_EL2_REGS
-# define CTX_EL2_SYSREGS_ALL	(CTX_EL2_SYSREGS_END >> DWORD_SHIFT)
-#endif
+
 #if CTX_INCLUDE_FPREGS
 # define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
 #endif
@@ -384,9 +335,6 @@
 #if CTX_INCLUDE_PAUTH_REGS
 # define CTX_PAUTH_REGS_ALL	(CTX_PAUTH_REGS_END >> DWORD_SHIFT)
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-# define CTX_MPAM_REGS_ALL	(CTX_MPAM_REGS_END >> DWORD_SHIFT)
-#endif
 
 /*
  * AArch64 general purpose register context structure. Usually x0-x18,
@@ -403,15 +351,6 @@
  */
 DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL);
 
-
-/*
- * AArch64 EL2 system register context structure for preserving the
- * architectural state during world switches.
- */
-#if CTX_INCLUDE_EL2_REGS
-DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL);
-#endif
-
 /*
  * AArch64 floating point register context structure for preserving
  * the floating point state during switches from one security state to
@@ -435,11 +374,6 @@
 DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
 #endif
 
-/* Registers associated to ARMv8.2 MPAM */
-#if CTX_INCLUDE_MPAM_REGS
-DEFINE_REG_STRUCT(mpam, CTX_MPAM_REGS_ALL);
-#endif
-
 /*
  * Macros to access members of any of the above structures using their
  * offsets
@@ -460,19 +394,20 @@
 	gp_regs_t gpregs_ctx;
 	el3_state_t el3state_ctx;
 	el1_sysregs_t el1_sysregs_ctx;
-#if CTX_INCLUDE_EL2_REGS
-	el2_sysregs_t el2_sysregs_ctx;
-#endif
+
 #if CTX_INCLUDE_FPREGS
 	fp_regs_t fpregs_ctx;
 #endif
 	cve_2018_3639_t cve_2018_3639_ctx;
+
 #if CTX_INCLUDE_PAUTH_REGS
 	pauth_t pauth_ctx;
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-	mpam_t	mpam_ctx;
+
+#if CTX_INCLUDE_EL2_REGS
+	el2_sysregs_t el2_sysregs_ctx;
 #endif
+
 } cpu_context_t;
 
 /*
@@ -501,9 +436,6 @@
 #if CTX_INCLUDE_PAUTH_REGS
 # define get_pauth_ctx(h)	(&((cpu_context_t *) h)->pauth_ctx)
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-# define get_mpam_ctx(h)	(&((cpu_context_t *) h)->mpam_ctx)
-#endif
 
 /*
  * Compile time assertions related to the 'cpu_context' structure to
@@ -512,28 +444,25 @@
  */
 CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx),
 	assert_core_context_gp_offset_mismatch);
+
+CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
+	assert_core_context_el3state_offset_mismatch);
+
 CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx),
 	assert_core_context_el1_sys_offset_mismatch);
-#if CTX_INCLUDE_EL2_REGS
-CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx),
-	assert_core_context_el2_sys_offset_mismatch);
-#endif
+
 #if CTX_INCLUDE_FPREGS
 CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx),
 	assert_core_context_fp_offset_mismatch);
-#endif
-CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
-	assert_core_context_el3state_offset_mismatch);
+#endif /* CTX_INCLUDE_FPREGS */
+
 CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx),
 	assert_core_context_cve_2018_3639_offset_mismatch);
+
 #if CTX_INCLUDE_PAUTH_REGS
 CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx),
 	assert_core_context_pauth_offset_mismatch);
-#endif
-#if CTX_INCLUDE_MPAM_REGS
-CASSERT(CTX_MPAM_REGS_OFFSET == __builtin_offsetof(cpu_context_t, mpam_ctx),
-	assert_core_context_mpam_offset_mismatch);
-#endif
+#endif /* CTX_INCLUDE_PAUTH_REGS */
 
 /*
  * Helper macro to set the general purpose registers that correspond to
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
new file mode 100644
index 0000000..d25ab81
--- /dev/null
+++ b/include/lib/el3_runtime/context_el2.h
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONTEXT_EL2_H
+#define CONTEXT_EL2_H
+
+#ifndef __ASSEMBLER__
+/*******************************************************************************
+ * EL2 Registers:
+ * AArch64 EL2 system register context structure for preserving the
+ * architectural state during world switches.
+ ******************************************************************************/
+#if CTX_INCLUDE_EL2_REGS
+typedef struct el2_common_regs {
+	uint64_t actlr_el2;
+	uint64_t afsr0_el2;
+	uint64_t afsr1_el2;
+	uint64_t amair_el2;
+	uint64_t cnthctl_el2;
+	uint64_t cntvoff_el2;
+	uint64_t cptr_el2;
+	uint64_t dbgvcr32_el2;
+	uint64_t elr_el2;
+	uint64_t esr_el2;
+	uint64_t far_el2;
+	uint64_t hacr_el2;
+	uint64_t hcr_el2;
+	uint64_t hpfar_el2;
+	uint64_t hstr_el2;
+	uint64_t icc_sre_el2;
+	uint64_t ich_hcr_el2;
+	uint64_t ich_vmcr_el2;
+	uint64_t mair_el2;
+	uint64_t mdcr_el2;
+	uint64_t pmscr_el2;
+	uint64_t sctlr_el2;
+	uint64_t spsr_el2;
+	uint64_t sp_el2;
+	uint64_t tcr_el2;
+	uint64_t tpidr_el2;
+	uint64_t ttbr0_el2;
+	uint64_t vbar_el2;
+	uint64_t vmpidr_el2;
+	uint64_t vpidr_el2;
+	uint64_t vtcr_el2;
+	uint64_t vttbr_el2;
+} el2_common_regs_t;
+
+typedef struct el2_mte2_regs {
+	uint64_t tfsr_el2;
+} el2_mte2_regs_t;
+
+typedef struct el2_fgt_regs {
+	uint64_t hdfgrtr_el2;
+	uint64_t hafgrtr_el2;
+	uint64_t hdfgwtr_el2;
+	uint64_t hfgitr_el2;
+	uint64_t hfgrtr_el2;
+	uint64_t hfgwtr_el2;
+} el2_fgt_regs_t;
+
+typedef struct el2_ecv_regs {
+	uint64_t cntpoff_el2;
+} el2_ecv_regs_t;
+
+typedef struct el2_vhe_regs {
+	uint64_t contextidr_el2;
+	uint64_t ttbr1_el2;
+} el2_vhe_regs_t;
+
+typedef struct el2_ras_regs {
+	uint64_t vdisr_el2;
+	uint64_t vsesr_el2;
+} el2_ras_regs_t;
+
+typedef struct el2_neve_regs {
+	uint64_t vncr_el2;
+} el2_neve_regs_t;
+
+typedef struct el2_trf_regs {
+	uint64_t trfcr_el2;
+} el2_trf_regs_t;
+
+typedef struct el2_csv2_regs {
+	uint64_t scxtnum_el2;
+} el2_csv2_regs_t;
+
+typedef struct el2_hcx_regs {
+	uint64_t hcrx_el2;
+} el2_hcx_regs_t;
+
+typedef struct el2_tcr2_regs {
+	uint64_t tcr2_el2;
+} el2_tcr2_regs_t;
+
+typedef struct el2_sxpoe_regs {
+	uint64_t por_el2;
+} el2_sxpoe_regs_t;
+
+typedef struct el2_sxpie_regs {
+	uint64_t pire0_el2;
+	uint64_t pir_el2;
+} el2_sxpie_regs_t;
+
+typedef struct el2_s2pie_regs {
+	uint64_t s2pir_el2;
+} el2_s2pie_regs_t;
+
+typedef struct el2_gcs_regs {
+	uint64_t gcscr_el2;
+	uint64_t gcspr_el2;
+} el2_gcs_regs_t;
+
+typedef struct el2_mpam_regs {
+	uint64_t mpam2_el2;
+	uint64_t mpamhcr_el2;
+	uint64_t mpamvpm0_el2;
+	uint64_t mpamvpm1_el2;
+	uint64_t mpamvpm2_el2;
+	uint64_t mpamvpm3_el2;
+	uint64_t mpamvpm4_el2;
+	uint64_t mpamvpm5_el2;
+	uint64_t mpamvpm6_el2;
+	uint64_t mpamvpm7_el2;
+	uint64_t mpamvpmv_el2;
+} el2_mpam_regs_t;
+
+typedef struct el2_sysregs {
+
+	el2_common_regs_t common;
+
+#if ENABLE_FEAT_MTE2
+	el2_mte2_regs_t mte2;
+#endif
+
+#if ENABLE_FEAT_FGT
+	el2_fgt_regs_t fgt;
+#endif
+
+#if ENABLE_FEAT_ECV
+	el2_ecv_regs_t ecv;
+#endif
+
+#if ENABLE_FEAT_VHE
+	el2_vhe_regs_t vhe;
+#endif
+
+#if ENABLE_FEAT_RAS
+	el2_ras_regs_t ras;
+#endif
+
+#if CTX_INCLUDE_NEVE_REGS
+	el2_neve_regs_t neve;
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	el2_trf_regs_t trf;
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	el2_csv2_regs_t csv2;
+#endif
+
+#if ENABLE_FEAT_HCX
+	el2_hcx_regs_t hcx;
+#endif
+
+#if ENABLE_FEAT_TCR2
+	el2_tcr2_regs_t tcr2;
+#endif
+
+#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
+	el2_sxpoe_regs_t sxpoe;
+#endif
+
+#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
+	el2_sxpie_regs_t sxpie;
+#endif
+
+#if ENABLE_FEAT_S2PIE
+	el2_s2pie_regs_t s2pie;
+#endif
+
+#if ENABLE_FEAT_GCS
+	el2_gcs_regs_t gcs;
+#endif
+
+#if CTX_INCLUDE_MPAM_REGS
+	el2_mpam_regs_t mpam;
+#endif
+
+} el2_sysregs_t;
+
+/*
+ * Macros to access members related to individual features of the el2_sysregs_t
+ * structures.
+ */
+#define read_el2_ctx_common(ctx, reg)		(((ctx)->common).reg)
+
+#define write_el2_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (uint64_t) (val))
+
+#if ENABLE_FEAT_MTE2
+#define read_el2_ctx_mte2(ctx, reg)		(((ctx)->mte2).reg)
+#define write_el2_ctx_mte2(ctx, reg, val)	((((ctx)->mte2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mte2(ctx, reg)		ULL(0)
+#define write_el2_ctx_mte2(ctx, reg, val)
+#endif /* ENABLE_FEAT_MTE2 */
+
+#if ENABLE_FEAT_FGT
+#define read_el2_ctx_fgt(ctx, reg)		(((ctx)->fgt).reg)
+#define write_el2_ctx_fgt(ctx, reg, val)	((((ctx)->fgt).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_fgt(ctx, reg)		ULL(0)
+#define write_el2_ctx_fgt(ctx, reg, val)
+#endif /* ENABLE_FEAT_FGT */
+
+#if ENABLE_FEAT_ECV
+#define read_el2_ctx_ecv(ctx, reg)		(((ctx)->ecv).reg)
+#define write_el2_ctx_ecv(ctx, reg, val)	((((ctx)->ecv).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_ecv(ctx, reg)		ULL(0)
+#define write_el2_ctx_ecv(ctx, reg, val)
+#endif /* ENABLE_FEAT_ECV */
+
+#if ENABLE_FEAT_VHE
+#define read_el2_ctx_vhe(ctx, reg)		(((ctx)->vhe).reg)
+#define write_el2_ctx_vhe(ctx, reg, val)	((((ctx)->vhe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_vhe(ctx, reg)		ULL(0)
+#define write_el2_ctx_vhe(ctx, reg, val)
+#endif /* ENABLE_FEAT_VHE */
+
+#if ENABLE_FEAT_RAS
+#define read_el2_ctx_ras(ctx, reg)		(((ctx)->ras).reg)
+#define write_el2_ctx_ras(ctx, reg, val)	((((ctx)->ras).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_ras(ctx, reg)		ULL(0)
+#define write_el2_ctx_ras(ctx, reg, val)
+#endif /* ENABLE_FEAT_RAS */
+
+#if CTX_INCLUDE_NEVE_REGS
+#define read_el2_ctx_neve(ctx, reg)		(((ctx)->neve).reg)
+#define write_el2_ctx_neve(ctx, reg, val)	((((ctx)->neve).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_neve(ctx, reg)		ULL(0)
+#define write_el2_ctx_neve(ctx, reg, val)
+#endif /* CTX_INCLUDE_NEVE_REGS */
+
+#if ENABLE_TRF_FOR_NS
+#define read_el2_ctx_trf(ctx, reg)		(((ctx)->trf).reg)
+#define write_el2_ctx_trf(ctx, reg, val)	((((ctx)->trf).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_trf(ctx, reg)		ULL(0)
+#define write_el2_ctx_trf(ctx, reg, val)
+#endif /* ENABLE_TRF_FOR_NS */
+
+#if ENABLE_FEAT_CSV2_2
+#define read_el2_ctx_csv2_2(ctx, reg)		(((ctx)->csv2).reg)
+#define write_el2_ctx_csv2_2(ctx, reg, val)	((((ctx)->csv2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_csv2_2(ctx, reg)		ULL(0)
+#define write_el2_ctx_csv2_2(ctx, reg, val)
+#endif /* ENABLE_FEAT_CSV2_2 */
+
+#if ENABLE_FEAT_HCX
+#define read_el2_ctx_hcx(ctx, reg)		(((ctx)->hcx).reg)
+#define write_el2_ctx_hcx(ctx, reg, val)	((((ctx)->hcx).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_hcx(ctx, reg)		ULL(0)
+#define write_el2_ctx_hcx(ctx, reg, val)
+#endif /* ENABLE_FEAT_HCX */
+
+#if ENABLE_FEAT_TCR2
+#define read_el2_ctx_tcr2(ctx, reg)		(((ctx)->tcr2).reg)
+#define write_el2_ctx_tcr2(ctx, reg, val)	((((ctx)->tcr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_tcr2(ctx, reg)		ULL(0)
+#define write_el2_ctx_tcr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_TCR2 */
+
+#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
+#define read_el2_ctx_sxpoe(ctx, reg)		(((ctx)->sxpoe).reg)
+#define write_el2_ctx_sxpoe(ctx, reg, val)	((((ctx)->sxpoe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sxpoe(ctx, reg)		ULL(0)
+#define write_el2_ctx_sxpoe(ctx, reg, val)
+#endif /*(ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE) */
+
+#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
+#define read_el2_ctx_sxpie(ctx, reg)		(((ctx)->sxpie).reg)
+#define write_el2_ctx_sxpie(ctx, reg, val)	((((ctx)->sxpie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sxpie(ctx, reg)		ULL(0)
+#define write_el2_ctx_sxpie(ctx, reg, val)
+#endif /*(ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE) */
+
+#if ENABLE_FEAT_S2PIE
+#define read_el2_ctx_s2pie(ctx, reg)		(((ctx)->s2pie).reg)
+#define write_el2_ctx_s2pie(ctx, reg, val)	((((ctx)->s2pie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_s2pie(ctx, reg)		ULL(0)
+#define write_el2_ctx_s2pie(ctx, reg, val)
+#endif /* ENABLE_FEAT_S2PIE */
+
+#if ENABLE_FEAT_GCS
+#define read_el2_ctx_gcs(ctx, reg)		(((ctx)->gcs).reg)
+#define write_el2_ctx_gcs(ctx, reg, val)	((((ctx)->gcs).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_gcs(ctx, reg)		ULL(0)
+#define write_el2_ctx_gcs(ctx, reg, val)
+#endif /* ENABLE_FEAT_GCS */
+
+#if CTX_INCLUDE_MPAM_REGS
+#define read_el2_ctx_mpam(ctx, reg)		(((ctx)->mpam).reg)
+#define write_el2_ctx_mpam(ctx, reg, val)	((((ctx)->mpam).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mpam(ctx, reg)		ULL(0)
+#define write_el2_ctx_mpam(ctx, reg, val)
+#endif /* CTX_INCLUDE_MPAM_REGS */
+
+#endif /* CTX_INCLUDE_EL2_REGS */
+/******************************************************************************/
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* CONTEXT_EL2_H */
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index f631125..7451b85 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,12 +30,15 @@
 void *cm_get_context(uint32_t security_state);
 void cm_set_context(void *context, uint32_t security_state);
 void cm_init_my_context(const struct entry_point_info *ep);
-void cm_init_context_by_index(unsigned int cpu_idx,
-			      const struct entry_point_info *ep);
 void cm_setup_context(cpu_context_t *ctx, const struct entry_point_info *ep);
 void cm_prepare_el3_exit(uint32_t security_state);
 void cm_prepare_el3_exit_ns(void);
 
+#if !IMAGE_BL1
+void cm_init_context_by_index(unsigned int cpu_idx,
+			      const struct entry_point_info *ep);
+#endif /* !IMAGE_BL1 */
+
 #ifdef __aarch64__
 #if IMAGE_BL31
 void cm_manage_extensions_el3(void);
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
index 194efba..425a037 100644
--- a/include/lib/extensions/brbe.h
+++ b/include/lib/extensions/brbe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,10 +7,12 @@
 #ifndef BRBE_H
 #define BRBE_H
 
+#include <context.h>
+
 #if ENABLE_BRBE_FOR_NS
-void brbe_init_el3(void);
+void brbe_enable(cpu_context_t *ctx);
 #else
-static inline void brbe_init_el3(void)
+static inline void brbe_enable(cpu_context_t *ctx)
 {
 }
 #endif /* ENABLE_BRBE_FOR_NS */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index 7b39037..c6e44f9 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,13 +8,14 @@
 #define SPE_H
 
 #include <stdbool.h>
+#include <context.h>
 
 #if ENABLE_SPE_FOR_NS
-void spe_init_el3(void);
+void spe_enable(cpu_context_t *ctx);
 void spe_init_el2_unused(void);
 void spe_disable(void);
 #else
-static inline void spe_init_el3(void)
+static inline void spe_enable(cpu_context_t *ctx)
 {
 }
 static inline void spe_init_el2_unused(void)
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
index 0bed433..5db3316 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,11 +7,13 @@
 #ifndef TRBE_H
 #define TRBE_H
 
+#include <context.h>
+
 #if ENABLE_TRBE_FOR_NS
-void trbe_init_el3(void);
+void trbe_enable(cpu_context_t *ctx);
 void trbe_init_el2_unused(void);
 #else
-static inline void trbe_init_el3(void)
+static inline void trbe_enable(cpu_context_t *ctx)
 {
 }
 static inline void trbe_init_el2_unused(void)
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
index 1ac7cda..f0a946b 100644
--- a/include/lib/extensions/trf.h
+++ b/include/lib/extensions/trf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,16 +7,32 @@
 #ifndef TRF_H
 #define TRF_H
 
+#include <context.h>
+
 #if ENABLE_TRF_FOR_NS
-void trf_init_el3(void);
+
+#if __aarch64__
+void trf_enable(cpu_context_t *ctx);
 void trf_init_el2_unused(void);
-#else
-static inline void trf_init_el3(void)
+#else /* !__aarch64 */
+void trf_init_el3(void);
+#endif /* __aarch64__ */
+
+#else /* ENABLE_TRF_FOR_NS=0 */
+
+#if __aarch64__
+static inline void trf_enable(cpu_context_t *ctx)
 {
 }
 static inline void trf_init_el2_unused(void)
 {
 }
+#else /* !__aarch64 */
+static inline void trf_init_el3(void)
+{
+}
+#endif /* __aarch64__*/
+
 #endif /* ENABLE_TRF_FOR_NS */
 
 #endif /* TRF_H */
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index 9d901e2..41bf7fc 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,19 +36,36 @@
 #define PMF_NO_CACHE_MAINT	U(0)
 
 /*
- * Defines for PMF SMC function ids.
+ * Defines for PMF SMC function ids used with arm-sip
+ * range, this is now deprecated and will be removed.
  */
-#define PMF_SMC_GET_TIMESTAMP_32	U(0x82000010)
-#define PMF_SMC_GET_TIMESTAMP_64	U(0xC2000010)
+#define PMF_SMC_GET_TIMESTAMP_32_DEP	U(0x82000010)
+#define PMF_SMC_GET_TIMESTAMP_64_DEP	U(0xC2000010)
+
+#define PMF_FID_VALUE_DEPRECATED	U(0x10)
+#define is_pmf_fid_deprecated(_fid) \
+	(GET_SMC_NUM(_fid) == PMF_FID_VALUE_DEPRECATED)
+
+/*
+ * Defines for PMF SMC function ids used with Vendor-Specific
+ * EL3 range.
+ */
+#define PMF_SMC_GET_TIMESTAMP_32	U(0x87000020)
+#define PMF_SMC_GET_TIMESTAMP_64	U(0xC7000020)
 #define PMF_NUM_SMC_CALLS		2
 
+#define PMF_SMC_GET_VERSION_32		U(0x87000021)
+#define PMF_SMC_GET_VERSION_64		U(0xC7000021)
+
+#define PMF_SMC_VERSION			U(0x00000001)
+
 /*
  * The macros below are used to identify
  * PMF calls from the SMC function ID.
  */
-#define PMF_FID_MASK	U(0xffe0)
-#define PMF_FID_VALUE	U(0)
-#define is_pmf_fid(_fid)	(((_fid) & PMF_FID_MASK) == PMF_FID_VALUE)
+#define PMF_FID_VALUE		U(0x20)
+#define PMF_ID_MASK		(FUNCID_NUM_MASK & ~(0xf))
+#define is_pmf_fid(_fid)	((GET_SMC_NUM(_fid) & PMF_ID_MASK) == PMF_FID_VALUE)
 
 /* Following are the supported PMF service IDs */
 #define PMF_PSCI_STAT_SVC_ID	0
diff --git a/include/lib/psa/cca_attestation.h b/include/lib/psa/cca_attestation.h
new file mode 100644
index 0000000..4062dde
--- /dev/null
+++ b/include/lib/psa/cca_attestation.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_ATTESTATION_H
+#define CCA_ATTESTATION_H
+
+#include <stdint.h>
+#include <psa/crypto_types.h>
+
+psa_status_t
+cca_attestation_get_realm_key(uintptr_t buf, size_t *len, unsigned int type);
+
+psa_status_t
+cca_attestation_get_plat_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size);
+
+#endif /* CCA_ATTESTATION_H */
diff --git a/include/lib/psa/delegated_attestation.h b/include/lib/psa/delegated_attestation.h
index 7aaceb3..ec49f5d 100644
--- a/include/lib/psa/delegated_attestation.h
+++ b/include/lib/psa/delegated_attestation.h
@@ -15,9 +15,9 @@
 
 #include "psa/error.h"
 
-/* RSS Delegated Attestation message types that distinguish its services. */
-#define RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY      1001U
-#define RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN     1002U
+/* RSE Delegated Attestation message types that distinguish its services. */
+#define RSE_DELEGATED_ATTEST_GET_DELEGATED_KEY      1001U
+#define RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN     1002U
 
 /**
  * The aim of these APIs to get a derived signing key (private only) for the
@@ -28,13 +28,13 @@
  * key is bind to the platform token (details below).
  *
  * Expected usage model:
- *  - First rss_delegated_attest_get_delegated_key() API need to be called to
+ *  - First rse_delegated_attest_get_delegated_key() API need to be called to
  *    obtain the private part of the delegated attestation key. The public part
  *    of key is computed by the cryptographic library when the key is
  *    registered.
- *  - Secondly the rss_delegated_attest_get_token() must be called to obtain
+ *  - Secondly the rse_delegated_attest_get_token() must be called to obtain
  *    platform attestation token. The hash of the public key (computed by
- *    the hash_algo indicated in the rss_delegated_attest_get_delegated_key()
+ *    the hash_algo indicated in the rse_delegated_attest_get_delegated_key()
  *    call) must be the input of this call. This ensures that nothing but the
  *    previously derived delegated key is bindable to the platform token.
  */
@@ -74,7 +74,7 @@
  *     platform attestation token as they are cryptographically linked together.
  */
 psa_status_t
-rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+rse_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 				       uint32_t  key_bits,
 				       uint8_t  *key_buf,
 				       size_t    key_buf_size,
@@ -100,7 +100,7 @@
  * code will be returned.
  */
 psa_status_t
-rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+rse_delegated_attest_get_token(const uint8_t *dak_pub_hash,
 			       size_t         dak_pub_hash_size,
 			       uint8_t       *token_buf,
 			       size_t         token_buf_size,
diff --git a/include/lib/psa/dice_protection_environment.h b/include/lib/psa/dice_protection_environment.h
new file mode 100644
index 0000000..5351451
--- /dev/null
+++ b/include/lib/psa/dice_protection_environment.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef DICE_PROTECTION_ENVIRONMENT_H
+#define DICE_PROTECTION_ENVIRONMENT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <dice.h>
+
+/* Additional defines for max size limit. These limits are set by DPE in RSE. */
+#define DICE_AUTHORITY_DESCRIPTOR_MAX_SIZE	64
+#define DICE_CONFIG_DESCRIPTOR_MAX_SIZE		64
+#define DICE_CODE_DESCRIPTOR_MAX_SIZE		32
+
+typedef int32_t dpe_error_t;
+
+#define DPE_NO_ERROR			((dpe_error_t)0)
+#define DPE_INTERNAL_ERROR		((dpe_error_t)1)
+#define DPE_INVALID_COMMAND		((dpe_error_t)2)
+#define DPE_INVALID_ARGUMENT		((dpe_error_t)3)
+#define DPE_ARGUMENT_NOT_SUPPORTED	((dpe_error_t)4)
+#define DPE_SESSION_EXHAUSTED		((dpe_error_t)5)
+
+/* Custom values in RSE based DPE implementation */
+#define DPE_INSUFFICIENT_MEMORY		((dpe_error_t)128)
+#define DPE_ERR_CBOR_FORMATTING		((dpe_error_t)129)
+
+/**
+ * Client facing API. Parameters are according to the DPE spec version r0.9
+ *
+ * \brief Performs the DICE computation to derive a new context and optionally
+ *        creates an intermediate certificate. Software component measurement
+ *        must be provided in dice_inputs.
+ *
+ * \param[in]  context_handle              Input context handle for the DPE
+ *                                         context.
+ * \param[in]  cert_id                     Logical certificate id to which derived
+ *                                         context belongs to.
+ * \param[in]  retain_parent_context       Flag to indicate whether to retain the
+ *                                         parent context. True only if a client
+ *                                         will call further DPE commands on the
+ *                                         same context.
+ * \param[in]  allow_new_context_to_derive Flag to indicate whether derived context
+ *                                         can derive further. True only if the
+ *                                         new context will load further components.
+ * \param[in]  create_certificate          Flag to indicate whether to create an
+ *                                         intermediate certificate. True only if
+ *                                         it is the last component in the layer.
+ * \param[in]  dice_inputs                 DICE input values.
+ * \param[in]  target_locality             Identifies the locality to which the
+ *                                         derived context will be bound. Could be
+ *                                         MHU id.
+ * \param[in]  return_certificate          Indicates whether to return the generated
+ *                                         certificate when create_certificate is true.
+ * \param[in]  allow_new_context_to_export Indicates whether the DPE permits export of
+ *                                         the CDI from the newly derived context.
+ * \param[in]  export_cdi                  Indicates whether to export derived CDI.
+ * \param[out] new_context_handle          New handle for the derived context.
+ * \param[out] new_parent_context_handle   New handle for the parent context.
+ * \param[out] new_certificate_buf         If create_certificate and return_certificate
+ *                                         are both true, this argument holds the new
+ *                                         certificate generated for the new context
+ * \param[in]  new_certificate_buf_size    Size of the allocated buffer for
+ *                                         new certificate.
+ * \param[out] new_certificate_actual_size Actual size of the new certificate.
+ * \param[out] exported_cdi_buf            If export_cdi is true, this is the
+ *                                         exported CDI value.
+ * \param[in]  exported_cdi_buf_size       Size of the allocated buffer for
+ *                                         exported cdi.
+ * \param[out] exported_cdi_actual_size    Actual size of the exported cdi.
+ *
+ * \return Returns error code of type dpe_error_t
+ */
+dpe_error_t dpe_derive_context(int      context_handle,
+			       uint32_t cert_id,
+			       bool     retain_parent_context,
+			       bool     allow_new_context_to_derive,
+			       bool     create_certificate,
+			       const DiceInputValues *dice_inputs,
+			       int32_t  target_locality,
+			       bool     return_certificate,
+			       bool     allow_new_context_to_export,
+			       bool     export_cdi,
+			       int     *new_context_handle,
+			       int     *new_parent_context_handle,
+			       uint8_t *new_certificate_buf,
+			       size_t   new_certificate_buf_size,
+			       size_t  *new_certificate_actual_size,
+			       uint8_t *exported_cdi_buf,
+			       size_t   exported_cdi_buf_size,
+			       size_t  *exported_cdi_actual_size);
+
+#endif /* DICE_PROTECTION_ENVIRONMENT_H */
diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h
index af624a6..3cc6c95 100644
--- a/include/lib/psa/measured_boot.h
+++ b/include/lib/psa/measured_boot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,21 +14,6 @@
 
 #include "psa/error.h"
 
-/* Minimum measurement value size that can be requested to store */
-#define MEASUREMENT_VALUE_MIN_SIZE	32U
-/* Maximum measurement value size that can be requested to store */
-#define MEASUREMENT_VALUE_MAX_SIZE	64U
-/* Minimum signer id size that can be requested to store */
-#define SIGNER_ID_MIN_SIZE		MEASUREMENT_VALUE_MIN_SIZE
-/* Maximum signer id size that can be requested to store */
-#define SIGNER_ID_MAX_SIZE		MEASUREMENT_VALUE_MAX_SIZE
-/* The theoretical maximum image version is: "255.255.65535\0" */
-#define VERSION_MAX_SIZE		14U
-/* Example sw_type: "BL_2, BL_33, etc." */
-#define SW_TYPE_MAX_SIZE		20U
-#define NUM_OF_MEASUREMENT_SLOTS	32U
-
-
 /**
  * Extends and stores a measurement to the requested slot.
  *
@@ -58,11 +43,11 @@
  *	- When the requested slot is not accessible to the caller.
  */
 
-/* Not a standard PSA API, just an extension therefore use the 'rss_' prefix
+/* Not a standard PSA API, just an extension therefore use the 'rse_' prefix
  * rather than the usual 'psa_'.
  */
 psa_status_t
-rss_measured_boot_extend_measurement(uint8_t index,
+rse_measured_boot_extend_measurement(uint8_t index,
 				     const uint8_t *signer_id,
 				     size_t signer_id_size,
 				     const uint8_t *version,
@@ -107,7 +92,7 @@
  * PSA_ERROR_DOES_NOT_EXIST
  *	- The requested slot is empty, does not contain a measurement.
  */
-psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+psa_status_t rse_measured_boot_read_measurement(uint8_t index,
 					uint8_t *signer_id,
 					size_t signer_id_size,
 					size_t *signer_id_len,
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 7183112..bb8abe4 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,16 +8,19 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
-/******** RSS_SP_CRYPTO ********/
-#define RSS_CRYPTO_HANDLE				(0x40000100U)
+/******** RSE_SP_CRYPTO ********/
+#define RSE_CRYPTO_HANDLE				(0x40000100U)
 
-/******** RSS_SP_PLATFORM ********/
-#define RSS_PLATFORM_SERVICE_HANDLE			(0x40000105U)
+/******** RSE_SP_PLATFORM ********/
+#define RSE_PLATFORM_SERVICE_HANDLE			(0x40000105U)
 
 /******** PSA_SP_MEASURED_BOOT ********/
-#define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
+#define RSE_MEASURED_BOOT_HANDLE			(0x40000110U)
+
+/******** PSA_SP_DELEGATED_ATTESTATION ********/
+#define RSE_DELEGATED_SERVICE_HANDLE			(0x40000111U)
 
-/******** PSA_SP_DELAGATED_ATTESTATION ********/
-#define RSS_DELEGATED_SERVICE_HANDLE			(0x40000111U)
+/******** PSA_SP_DICE_PROTECTION_ENVIRONMENT ********/
+#define RSE_DPE_SERVICE_HANDLE				(0x40000112U)
 
 #endif /* PSA_MANIFEST_SID_H */
diff --git a/include/lib/psa/rss_crypto_defs.h b/include/lib/psa/rse_crypto_defs.h
similarity index 68%
rename from include/lib/psa/rss_crypto_defs.h
rename to include/lib/psa/rse_crypto_defs.h
index 301dc05..44936b8 100644
--- a/include/lib/psa/rss_crypto_defs.h
+++ b/include/lib/psa/rse_crypto_defs.h
@@ -5,8 +5,8 @@
  *
  */
 
-#ifndef RSS_CRYPTO_DEFS_H
-#define RSS_CRYPTO_DEFS_H
+#ifndef RSE_CRYPTO_DEFS_H
+#define RSE_CRYPTO_DEFS_H
 
 /* Declares types that encode errors, algorithms, key types, policies, etc. */
 #include "psa/crypto_types.h"
@@ -16,31 +16,31 @@
  * to the corresponding API implementation in the Crypto service backend.
  *
  */
-#define RSS_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x701)
+#define RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x701)
 
 /*
- * The persistent key identifiers for RSS builtin keys.
+ * The persistent key identifiers for RSE 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,
+enum rse_key_id_builtin_t {
+	RSE_BUILTIN_KEY_ID_HOST_S_ROTPK = 0x7FFF816Cu,
+	RSE_BUILTIN_KEY_ID_HOST_NS_ROTPK,
+	RSE_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
 };
 
 /*
- * This type is used to overcome a limitation within RSS firmware in the number of maximum
+ * This type is used to overcome a limitation within RSE 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];
+#define RSE_CRYPTO_MAX_NONCE_LENGTH (16u)
+struct rse_crypto_aead_pack_input {
+	uint8_t nonce[RSE_CRYPTO_MAX_NONCE_LENGTH];
 	uint32_t nonce_length;
 };
 
 /*
  * Structure used to pack non-pointer types in a call to PSA Crypto APIs
  */
-struct rss_crypto_pack_iovec {
+struct rse_crypto_pack_iovec {
 	psa_key_id_t key_id;		/* !< Key id */
 	psa_algorithm_t alg;		/* !< Algorithm */
 	uint32_t op_handle;		/*
@@ -56,7 +56,7 @@
 					 *    AEAD
 					 */
 
-	struct rss_crypto_aead_pack_input aead_in; /*
+	struct rse_crypto_aead_pack_input aead_in; /*
 						    * !< Packs AEAD-related
 						    *    inputs
 						    */
@@ -64,7 +64,7 @@
 	uint16_t function_id;	/*
 				 * !< Used to identify the function in the
 				 *    API dispatcher to the service backend
-				 *    See rss_crypto_func_sid for detail
+				 *    See rse_crypto_func_sid for detail
 				 */
 	uint16_t step;		/* !< Key derivation step */
 	union {
@@ -76,4 +76,4 @@
 	};
 };
 
-#endif /* RSS_CRYPTO_DEFS_H */
+#endif /* RSE_CRYPTO_DEFS_H */
diff --git a/include/lib/psa/rss_platform_api.h b/include/lib/psa/rse_platform_api.h
similarity index 75%
rename from include/lib/psa/rss_platform_api.h
rename to include/lib/psa/rse_platform_api.h
index 8f74a51..535001b 100644
--- a/include/lib/psa/rss_platform_api.h
+++ b/include/lib/psa/rse_platform_api.h
@@ -5,16 +5,16 @@
  *
  */
 
-#ifndef RSS_PLATFORM_API_H
-#define RSS_PLATFORM_API_H
+#ifndef RSE_PLATFORM_API_H
+#define RSE_PLATFORM_API_H
 
 #include <stdint.h>
 
 #include "psa/error.h"
-#include <rss_crypto_defs.h>
+#include <rse_crypto_defs.h>
 
-#define RSS_PLATFORM_API_ID_NV_READ       (1010)
-#define RSS_PLATFORM_API_ID_NV_INCREMENT  (1011)
+#define RSE_PLATFORM_API_ID_NV_READ       (1010)
+#define RSE_PLATFORM_API_ID_NV_INCREMENT  (1011)
 
 /*
  * Increments the given non-volatile (NV) counter by one
@@ -25,7 +25,7 @@
  *	it returns a PSA_ERROR.
  */
 psa_status_t
-rss_platform_nv_counter_increment(uint32_t counter_id);
+rse_platform_nv_counter_increment(uint32_t counter_id);
 
 /*
  * Reads the given non-volatile (NV) counter
@@ -39,7 +39,7 @@
  *	it returns a PSA_ERROR.
  */
 psa_status_t
-rss_platform_nv_counter_read(uint32_t counter_id,
+rse_platform_nv_counter_read(uint32_t counter_id,
 		uint32_t size, uint8_t *val);
 
 /*
@@ -54,7 +54,7 @@
  *	it returns a PSA_ERROR.
  */
 psa_status_t
-rss_platform_key_read(enum rss_key_id_builtin_t key, uint8_t *data,
+rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data,
 		size_t data_size, size_t *data_length);
 
-#endif /* RSS_PLATFORM_API_H */
+#endif /* RSE_PLATFORM_API_H */
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index c493105..775c2b2 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,7 @@
 						SMCCC_VERSION_MINOR_SHIFT))
 
 #define SMCCC_MAJOR_VERSION U(1)
-#define SMCCC_MINOR_VERSION U(4)
+#define SMCCC_MINOR_VERSION U(5)
 
 /*******************************************************************************
  * Bit definitions inside the function id as per the SMC calling convention
@@ -95,6 +95,8 @@
 #define OEN_STD_HYP_END			U(5)
 #define OEN_VEN_HYP_START		U(6)	/* Vendor Hypervisor Service calls */
 #define OEN_VEN_HYP_END			U(6)
+#define OEN_VEN_EL3_START		U(7)	/* Vendor Specific EL3 Monitor Calls */
+#define OEN_VEN_EL3_END			U(7)
 #define OEN_TAP_START			U(48)	/* Trusted Applications */
 #define OEN_TAP_END			U(49)
 #define OEN_TOS_START			U(50)	/* Trusted OS */
diff --git a/include/lib/spinlock.h b/include/lib/spinlock.h
index 9fd3fc6..055a911 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,15 +15,21 @@
 	volatile uint32_t lock;
 } spinlock_t;
 
+typedef struct bitlock {
+	volatile uint8_t lock;
+} bitlock_t;
+
 void spin_lock(spinlock_t *lock);
 void spin_unlock(spinlock_t *lock);
 
+void bit_lock(bitlock_t *lock, uint8_t mask);
+void bit_unlock(bitlock_t *lock, uint8_t mask);
+
 #else
 
 /* Spin lock definitions for use in assembly */
 #define SPINLOCK_ASM_ALIGN	2
 #define SPINLOCK_ASM_SIZE	4
 
-#endif
-
+#endif /* __ASSEMBLER__ */
 #endif /* SPINLOCK_H */
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 5ea5a41..5bea270 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,6 +42,10 @@
 	TL_TAG_HOB_LIST = 3,
 	TL_TAG_ACPI_TABLE_AGGREGATE = 4,
 	TL_TAG_OPTEE_PAGABLE_PART = 0x100,
+	TL_TAG_DT_SPMC_MANIFEST = 0x101,
+	TL_TAG_EXEC_EP_INFO64 = 0x102,
+	TL_TAG_TB_FW_CONFIG = 0x103,
+	TL_TAG_SRAM_LAYOUT64 = 0x104,
 };
 
 enum transfer_list_ops {
@@ -73,9 +77,8 @@
 	 */
 };
 
-struct transfer_list_entry {
-	uint16_t tag_id;
-	uint8_t reserved0; /* place holder */
+struct __attribute__((packed)) transfer_list_entry {
+	uint32_t tag_id : 24;
 	uint8_t hdr_size;
 	uint32_t data_size;
 	/*
@@ -89,6 +92,8 @@
 	 */
 };
 
+CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size);
+
 void transfer_list_dump(struct transfer_list_header *tl);
 entry_point_info_t *
 transfer_list_set_handoff_args(struct transfer_list_header *tl,
@@ -113,12 +118,12 @@
 		       struct transfer_list_entry *entry);
 
 struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
-					      uint16_t tag_id,
+					      uint32_t tag_id,
 					      uint32_t data_size,
 					      const void *data);
 
 struct transfer_list_entry *
-transfer_list_add_with_align(struct transfer_list_header *tl, uint16_t tag_id,
+transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
 			     uint32_t data_size, const void *data,
 			     uint8_t alignment);
 
@@ -127,7 +132,7 @@
 		   struct transfer_list_entry *last);
 
 struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
-					       uint16_t tag_id);
+					       uint32_t tag_id);
 
 #endif /*__ASSEMBLER__*/
 #endif /*__TRANSFER_LIST_H*/
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 8a03c7d..c3f767e 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -19,8 +19,13 @@
 
 #define SIZE_FROM_LOG2_WORDS(n)		(U(4) << (n))
 
+#if defined(__LINKER__) || defined(__ASSEMBLER__)
 #define BIT_32(nr)			(U(1) << (nr))
 #define BIT_64(nr)			(ULL(1) << (nr))
+#else
+#define BIT_32(nr)			(((uint32_t)(1U)) << (nr))
+#define BIT_64(nr)			(((uint64_t)(1ULL)) << (nr))
+#endif
 
 #ifdef __aarch64__
 #define BIT				BIT_64
@@ -29,22 +34,22 @@
 #endif
 
 /*
- * Create a contiguous bitmask starting at bit position @l and ending at
- * position @h. For example
+ * Create a contiguous bitmask starting at bit position @low and ending at
+ * position @high. For example
  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
 #if defined(__LINKER__) || defined(__ASSEMBLER__)
-#define GENMASK_32(h, l) \
-	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
+#define GENMASK_32(high, low) \
+	(((0xFFFFFFFF) << (low)) & (0xFFFFFFFF >> (32 - 1 - (high))))
 
-#define GENMASK_64(h, l) \
-	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
+#define GENMASK_64(high, low) \
+	((~0 << (low)) & (~0 >> (64 - 1 - (high))))
 #else
-#define GENMASK_32(h, l) \
-	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
+#define GENMASK_32(high, low) \
+	((~UINT32_C(0) >> (32U - 1U - (high))) ^ ((BIT_32(low) - 1U)))
 
-#define GENMASK_64(h, l) \
-	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+#define GENMASK_64(high, low) \
+	((~UINT64_C(0) >> (64U - 1U - (high))) ^ ((BIT_64(low) - 1U)))
 #endif
 
 #ifdef __aarch64__
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 1963bf0..3bb68ee 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -67,9 +67,6 @@
 #define PLAT_ARM_RUN_UART_BASE		SOC_CSS_UART1_BASE
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ	SOC_CSS_UART1_CLK_IN_HZ
 
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE		SOC_CSS_UART1_BASE
-#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ	SOC_CSS_UART1_CLK_IN_HZ
-
 #define PLAT_ARM_CRASH_UART_BASE		PLAT_ARM_RUN_UART_BASE
 #define PLAT_ARM_CRASH_UART_CLK_IN_HZ		PLAT_ARM_RUN_UART_CLK_IN_HZ
 
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index c3a88e7..ec5f90b 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -411,6 +411,8 @@
 #define ARM_V2M_MAP_MEM_PROTECT		MAP_REGION_FLAT(PLAT_ARM_MEM_PROT_ADDR,	\
 						V2M_FLASH_BLOCK_SIZE,		\
 						MT_DEVICE | MT_RW | MT_SECURE)
+
+#if !TRANSFER_LIST
 /*
  * Map the region for device tree configuration with read and write permissions
  */
@@ -418,6 +420,8 @@
 						(ARM_FW_CONFIGS_LIMIT		\
 							- ARM_BL_RAM_BASE),	\
 						MT_MEMORY | MT_RW | EL3_PAS)
+#endif
+
 /*
  * Map L0_GPT with read and write permissions
  */
@@ -505,6 +509,14 @@
  */
 #define CACHE_WRITEBACK_GRANULE		(U(1) << ARM_CACHE_WRITEBACK_SHIFT)
 
+/* Define memory configuration for trusted boot device tree files. */
+#ifdef PLAT_ARM_TB_FW_CONFIG_SIZE
+#define ARM_TB_FW_CONFIG_MAX_SIZE	PLAT_ARM_TB_FW_CONFIG_SIZE
+#else
+#define ARM_TB_FW_CONFIG_MAX_SIZE	U(0x400)
+#endif
+
+#if !TRANSFER_LIST
 /*
  * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
  * and limit. Leave enough space of BL2 meminfo.
@@ -526,6 +538,7 @@
  */
 #define ARM_FW_CONFIGS_SIZE		(PAGE_SIZE * 2)
 #define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
+#endif
 
 #if ENABLE_RME
 /*
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index a6fd42b..bca224d 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -16,12 +16,14 @@
 /*					U(0x8200ff02) is reserved */
 #define ARM_SIP_SVC_VERSION		U(0x8200ff03)
 
+/* Deprecated FID's Range and will be removed */
 /* PMF_SMC_GET_TIMESTAMP_32		0x82000010 */
 /* PMF_SMC_GET_TIMESTAMP_64		0xC2000010 */
 
 /* Function ID for requesting state switch of lower EL */
 #define ARM_SIP_SVC_EXE_STATE_SWITCH	U(0x82000020)
 
+/* Deprecated FID's Range and will be removed */
 /* DEBUGFS_SMC_32			0x82000030U */
 /* DEBUGFS_SMC_64			0xC2000030U */
 
@@ -32,8 +34,8 @@
  */
 
 /* ARM SiP Service Calls version numbers */
-#define ARM_SIP_SVC_VERSION_MAJOR		U(0x0)
-#define ARM_SIP_SVC_VERSION_MINOR		U(0x2)
+#define ARM_SIP_SVC_VERSION_MAJOR		U(0x1)
+#define ARM_SIP_SVC_VERSION_MINOR		U(0x0)
 
 /*
  * Arm SiP SMC calls that are primarily used for testing purposes.
diff --git a/include/plat/arm/common/arm_tzc_dram.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S
index c790bb9..08990f6 100644
--- a/include/plat/arm/common/arm_tzc_dram.ld.S
+++ b/include/plat/arm/common/arm_tzc_dram.ld.S
@@ -18,6 +18,9 @@
 	ASSERT(. == ALIGN(PAGE_SIZE),
 	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
 	.el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
+	__PLAT_SPMC_SHMEM_DATASTORE_START__ = .;
+	*(.arm_spmc_shmem_datastore)
+	__PLAT_SPMC_SHMEM_DATASTORE_END__ = .;
 	__EL3_SEC_DRAM_START__ = .;
 	*(.arm_el3_tzc_dram)
 	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 4c425a7..ba8df2a 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -9,12 +9,14 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <common/desc_image_load.h>
 #include <drivers/arm/tzc_common.h>
 #include <lib/bakery_lock.h>
 #include <lib/cassert.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/gpt_rme/gpt_rme.h>
 #include <lib/spinlock.h>
+#include <lib/transfer_list.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 
@@ -67,14 +69,16 @@
 
 #if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #define ARM_TZC_REGIONS_DEF						\
-	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
-		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}, 				\
-	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
-		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{ARM_AP_TZC_DRAM1_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE - 1),	\
+		TZC_REGION_S_RDWR, 0},					\
 	{PLAT_SP_IMAGE_NS_BUF_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE +	\
-		PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+		PLAT_SP_IMAGE_NS_BUF_SIZE - 1), TZC_REGION_S_NONE,	\
+		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{PLAT_SP_IMAGE_STACK_BASE, ARM_EL3_TZC_DRAM1_END,		\
+		TZC_REGION_S_RDWR, 0},					\
+	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 #elif ENABLE_RME
@@ -151,11 +155,10 @@
 #define ARM_LOCAL_PSTATE_WIDTH		4
 #define ARM_LOCAL_PSTATE_MASK		((1 << ARM_LOCAL_PSTATE_WIDTH) - 1)
 
-#if PSCI_OS_INIT_MODE
+/* Last in Level for the OS-initiated */
 #define ARM_LAST_AT_PLVL_MASK		(ARM_LOCAL_PSTATE_MASK <<	\
 					 (ARM_LOCAL_PSTATE_WIDTH *	\
 					  (PLAT_MAX_PWR_LVL + 1)))
-#endif /* __PSCI_OS_INIT_MODE__ */
 
 /* Macros to construct the composite power state */
 
@@ -254,6 +257,7 @@
 int arm_bl2_plat_handle_post_image_load(unsigned int image_id);
 int arm_bl2_handle_post_image_load(unsigned int image_id);
 struct bl_params *arm_get_next_bl_params(void);
+void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node);
 
 /* BL2 at EL3 functions */
 void arm_bl2_el3_early_platform_setup(void);
@@ -266,12 +270,25 @@
 void arm_bl2u_plat_arch_setup(void);
 
 /* BL31 utility functions */
+#if TRANSFER_LIST
+void arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				   u_register_t arg2, u_register_t arg3);
+#else
 void arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
 				uintptr_t hw_config, void *plat_params_from_bl2);
+#endif
 void arm_bl31_platform_setup(void);
 void arm_bl31_plat_runtime_setup(void);
 void arm_bl31_plat_arch_setup(void);
 
+/* Firmware Handoff utility functions */
+void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl);
+void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
+					struct transfer_list_header *secure_tl,
+					struct transfer_list_header *ns_tl);
+void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl,
+				      struct transfer_list_header *ns_tl);
+
 /* TSP utility functions */
 void arm_tsp_early_platform_setup(void);
 
@@ -285,11 +302,21 @@
 bool arm_io_is_toc_valid(void);
 
 /* Utility functions for Dynamic Config */
-void arm_bl2_dyn_cfg_init(void);
+
 void arm_bl1_set_mbedtls_heap(void);
 int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 
+#if IMAGE_BL2
+void arm_bl2_dyn_cfg_init(void);
+#endif /* IMAGE_BL2 */
+
 #if MEASURED_BOOT
+#if DICE_PROTECTION_ENVIRONMENT
+int arm_set_nt_fw_info(int *ctx_handle);
+int arm_set_tb_fw_info(int *ctx_handle);
+int arm_get_tb_fw_info(int *ctx_handle);
+#else
+/* Specific to event log backend */
 int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size);
 int arm_set_nt_fw_info(
 /*
@@ -304,6 +331,7 @@
 		       size_t log_max_size);
 int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
 		       size_t *log_max_size);
+#endif /* DICE_PROTECTION_ENVIRONMENT */
 #endif /* MEASURED_BOOT */
 
 /*
@@ -357,6 +385,8 @@
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
 #endif
 
+unsigned int plat_cluster_id_by_mpidr(u_register_t mpidr);
+
 /*
  * This function is called after loading SCP_BL2 image and it is used to perform
  * any platform-specific actions required to handle the SCP firmware.
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 0aea548..6203937 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -58,12 +58,12 @@
 	INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_TZC, 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)
 
 #define CSS_G1S_IRQ_PROPS(grp) \
 	CSS_G1S_INT_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, 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)
 
diff --git a/include/plat/common/plat_drtm.h b/include/plat/common/plat_drtm.h
index e96e719..07545a6 100644
--- a/include/plat/common/plat_drtm.h
+++ b/include/plat/common/plat_drtm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,7 @@
 
 typedef struct {
 	bool tpm_based_hash_support;
-	uint32_t firmware_hash_algorithm;
+	uint16_t firmware_hash_algorithm;
 } plat_drtm_tpm_features_t;
 
 typedef struct {
@@ -26,7 +26,7 @@
 } __attribute__((packed)) drtm_mem_region_t;
 
 /*
- * Memory region descriptor table structure as per DRTM beta0 section 3.13
+ * Memory region descriptor table structure as per DRTM 1.0 section 3.13
  * Table 11 MEMORY_REGION_DESCRIPTOR_TABLE
  */
 typedef struct {
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 4d1b1c1..1015fca 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,6 +41,16 @@
 enum fw_enc_status_t;
 
 /*******************************************************************************
+ * Structure populated by platform specific code to export routines which
+ * perform load images functions, and associated pointer to platform ops
+ ******************************************************************************/
+struct plat_try_images_ops {
+	int (*next_instance)(unsigned int image_id);
+};
+
+extern const struct plat_try_images_ops *plat_try_img_ops;
+
+/*******************************************************************************
  * plat_get_rotpk_info() flags
  ******************************************************************************/
 #define ROTPK_IS_HASH			(1 << 0)
@@ -136,6 +146,7 @@
 void plat_ic_set_interrupt_pending(unsigned int id);
 void plat_ic_clear_interrupt_pending(unsigned int id);
 unsigned int plat_ic_set_priority_mask(unsigned int mask);
+unsigned int plat_ic_deactivate_priority(unsigned int mask);
 unsigned int plat_ic_get_interrupt_id(unsigned int raw);
 
 /*******************************************************************************
@@ -153,7 +164,7 @@
 void plat_system_reset(void) __dead2;
 const char *plat_log_get_prefix(unsigned int log_level);
 void bl2_plat_preload_setup(void);
-int plat_try_next_boot_source(void);
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops);
 
 #if MEASURED_BOOT
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data);
@@ -183,6 +194,14 @@
 }
 #endif /* MEASURED_BOOT */
 
+#if EARLY_CONSOLE
+void plat_setup_early_console(void);
+#else
+static inline void plat_setup_early_console(void)
+{
+}
+#endif /* EARLY_CONSOLE */
+
 /*******************************************************************************
  * Mandatory BL1 functions
  ******************************************************************************/
@@ -242,6 +261,10 @@
 int bl1_plat_handle_pre_image_load(unsigned int image_id);
 int bl1_plat_handle_post_image_load(unsigned int image_id);
 
+/* Utility functions */
+void bl1_plat_calc_bl2_layout(const meminfo_t *bl1_mem_layout,
+			      meminfo_t *bl2_mem_layout);
+
 #if MEASURED_BOOT
 void bl1_plat_mboot_init(void);
 void bl1_plat_mboot_finish(void);
@@ -252,7 +275,7 @@
 static inline void bl1_plat_mboot_finish(void)
 {
 }
-#endif /* MEASURED_BOOT */
+#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT */
 
 /*******************************************************************************
  * Mandatory BL2 functions
@@ -272,7 +295,7 @@
 /*******************************************************************************
  * Optional BL2 functions (may be overridden)
  ******************************************************************************/
-#if MEASURED_BOOT
+#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
 void bl2_plat_mboot_init(void);
 void bl2_plat_mboot_finish(void);
 #else
@@ -282,7 +305,7 @@
 static inline void bl2_plat_mboot_finish(void)
 {
 }
-#endif /* MEASURED_BOOT */
+#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENTs */
 
 /*******************************************************************************
  * Mandatory BL2 at EL3 functions: Must be implemented
diff --git a/include/plat/nuvoton/common/npcm845x_arm_def.h b/include/plat/nuvoton/common/npcm845x_arm_def.h
index 5a44907..df3ad24 100644
--- a/include/plat/nuvoton/common/npcm845x_arm_def.h
+++ b/include/plat/nuvoton/common/npcm845x_arm_def.h
@@ -149,7 +149,16 @@
 			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
 /*
@@ -310,7 +319,7 @@
 			BL_RO_DATA_END - BL_RO_DATA_BASE,	\
 			MT_RO_DATA | EL3_PAS)
 #else
-#define ARM_MAP_BL_RO		MAP_REGION_FLAT(	\
+#define ARM_MAP_BL_RO_NOT_USED		MAP_REGION_FLAT(	\
 			BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,	\
 			MT_CODE | EL3_PAS)
 #endif /* SEPARATE_CODE_AND_RODATA */
@@ -474,9 +483,9 @@
 #define NEW_SRAM_ALLOCATION
 
 #ifdef NEW_SRAM_ALLOCATION
-	#define BL31_BASE				0x20001000
+	#define BL31_BASE				0x02000000
 #else
-	#define BL31_BASE				0x20001000
+	#define BL31_BASE				0x02001000
 #endif /* NEW_SRAM_ALLOCATION */
 
 #define BL31_LIMIT			BL2_BASE	/* PLAT_ARM_MAX_BL31_SIZE */
@@ -502,6 +511,7 @@
  * no SPD and no SPM-MM, as they are the only ones that can be used as BL32.
  */
 #if defined(SPD_none) && !SPM_MM
+#error BL32_BASE is not defined
 #undef BL32_BASE
 #endif /* SPD_none && !SPM_MM */
 
diff --git a/include/plat/nuvoton/common/plat_macros.S b/include/plat/nuvoton/common/plat_macros.S
index 08f9feb..549db39 100644
--- a/include/plat/nuvoton/common/plat_macros.S
+++ b/include/plat/nuvoton/common/plat_macros.S
@@ -41,7 +41,8 @@
  * BL31.
  */
 .macro plat_crash_print_regs
-	/* TODO */
+plat_print_gic_regs
+/*print_cci_regs*/
 .endm
 
 #endif /* PLAT_MACROS_S */
diff --git a/include/plat/nuvoton/npcm845x/platform_def.h b/include/plat/nuvoton/npcm845x/platform_def.h
index 09da36b..c70ef22 100644
--- a/include/plat/nuvoton/npcm845x/platform_def.h
+++ b/include/plat/nuvoton/npcm845x/platform_def.h
@@ -132,11 +132,6 @@
  */
 #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 */
@@ -162,7 +157,8 @@
 
 /* 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)
+	MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE,                         \
+			MT_DEVICE | MT_RW | MT_SECURE)
 
 #define MAP_DEVICE1                                                            \
 	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE,                            \
diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h
index 69b314f..f0d3c63 100644
--- a/include/services/drtm_svc.h
+++ b/include/services/drtm_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -54,10 +54,10 @@
 	(((_fid) >= ARM_DRTM_SVC_VERSION) && ((_fid) <= ARM_DRTM_SVC_LOCK_TCB_HASH))
 
 /* ARM DRTM Service Calls version numbers */
-#define ARM_DRTM_VERSION_MAJOR		U(0)
+#define ARM_DRTM_VERSION_MAJOR		U(1)
 #define ARM_DRTM_VERSION_MAJOR_SHIFT	16
 #define ARM_DRTM_VERSION_MAJOR_MASK	U(0x7FFF)
-#define ARM_DRTM_VERSION_MINOR		U(1)
+#define ARM_DRTM_VERSION_MINOR		U(0)
 #define ARM_DRTM_VERSION_MINOR_SHIFT	0
 #define ARM_DRTM_VERSION_MINOR_MASK	U(0xFFFF)
 
@@ -74,7 +74,7 @@
 #define ARM_DRTM_FEAT_ID_MASK	ULL(0xff)
 
 /*
- * Definitions for DRTM features as per DRTM beta0 section 3.3,
+ * Definitions for DRTM features as per DRTM 1.0 section 3.3,
  * Table 6 DRTM_FEATURES
  */
 #define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT		U(33)
@@ -87,7 +87,7 @@
 #define ARM_DRTM_TPM_FEATURES_TPM_HASH_SUPPORTED	ULL(0x1)
 
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT		U(0)
-#define ARM_DRTM_TPM_FEATURES_FW_HASH_MASK		ULL(0xFFFFFFFF)
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_MASK		ULL(0xFFFF)
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA256		ULL(0xB)
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA384		ULL(0xC)
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA512		ULL(0xD)
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index b89de9f..578bc14 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -14,7 +14,9 @@
 #include <lib/cassert.h>
 
 #define RMMD_MANIFEST_VERSION_MAJOR		U(0)
-#define RMMD_MANIFEST_VERSION_MINOR		U(2)
+#define RMMD_MANIFEST_VERSION_MINOR		U(3)
+
+#define RMM_CONSOLE_MAX_NAME_LEN		U(8)
 
 /*
  * Manifest version encoding:
@@ -60,12 +62,49 @@
 CASSERT(offsetof(struct ns_dram_info, checksum) == 16UL,
 			rmm_manifest_checksum_unaligned);
 
+/* Console info structure */
+struct console_info {
+	uintptr_t base;			/* Console base address */
+	uint64_t map_pages;		/* Num of pages to be mapped in RMM for the console MMIO */
+	char name[RMM_CONSOLE_MAX_NAME_LEN];	/* Name of console */
+	uint64_t clk_in_hz;		/* UART clock (in HZ) for the console */
+	uint64_t baud_rate;		/* Baud rate */
+	uint64_t flags;			/* Additional flags RES0 */
+};
+
+CASSERT(offsetof(struct console_info, base) == 0UL,
+			rmm_manifest_console_base_unaligned);
+CASSERT(offsetof(struct console_info, map_pages) == 8UL,
+			rmm_manifest_console_map_pages_unaligned);
+CASSERT(offsetof(struct console_info, name) == 16UL,
+			rmm_manifest_console_name_unaligned);
+CASSERT(offsetof(struct console_info, clk_in_hz) == 24UL,
+			rmm_manifest_console_clk_in_hz_unaligned);
+CASSERT(offsetof(struct console_info, baud_rate) == 32UL,
+			rmm_manifest_console_baud_rate_unaligned);
+CASSERT(offsetof(struct console_info, flags) == 40UL,
+			rmm_manifest_console_flags_unaligned);
+
-/* Boot manifest core structure as per v0.2 */
+struct console_list {
+	uint64_t num_consoles;		/* Number of consoles */
+	struct console_info *consoles;	/* Pointer to ns_dram_bank[] */
+	uint64_t checksum;		/* Checksum of ns_dram_info data */
+};
+
+CASSERT(offsetof(struct console_list, num_consoles) == 0UL,
+			rmm_manifest_num_consoles);
+CASSERT(offsetof(struct console_list, consoles) == 8UL,
+			rmm_manifest_consoles);
+CASSERT(offsetof(struct console_list, checksum) == 16UL,
+			rmm_manifest_console_list_checksum);
+
+/* Boot manifest core structure as per v0.3 */
 struct rmm_manifest {
-	uint32_t version;		/* Manifest version */
-	uint32_t padding;		/* RES0 */
-	uintptr_t plat_data;		/* Manifest platform data */
-	struct ns_dram_info plat_dram;	/* Platform NS DRAM data */
+	uint32_t version;			/* Manifest version */
+	uint32_t padding;			/* RES0 */
+	uintptr_t plat_data;			/* Manifest platform data */
+	struct ns_dram_info plat_dram;		/* Platform NS DRAM data (v0.2) */
+	struct console_list plat_console;	/* Platform console list (v0.3) */
 };
 
 CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
@@ -74,5 +113,7 @@
 			rmm_manifest_plat_data_unaligned);
 CASSERT(offsetof(struct rmm_manifest, plat_dram) == 16UL,
 			rmm_manifest_plat_dram_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_console) == 40UL,
+			rmm_manifest_plat_console_unaligned);
 
 #endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/ven_el3_svc.h b/include/services/ven_el3_svc.h
new file mode 100644
index 0000000..e030b68
--- /dev/null
+++ b/include/services/ven_el3_svc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VEN_EL3_SVC_H
+#define VEN_EL3_SVC_H
+
+/*
+ * Function Identifier value ranges for Vendor-Specific
+ * EL3 Monitor Service Calls.
+ */
+/* VEN_EL3_SMC_32		0x87000000U */
+/* VEN_EL3_SMC_64		0xC7000000U */
+
+
+/* Function Identifier values of general queries */
+#define VEN_EL3_SVC_UID		0x8700ff01
+/*				0x8700ff02 is reserved */
+#define VEN_EL3_SVC_VERSION	0x8700ff03
+
+#define VEN_EL3_SVC_VERSION_MAJOR	1
+#define VEN_EL3_SVC_VERSION_MINOR	0
+
+/* DEBUGFS_SMC_32		0x87000010U */
+/* DEBUGFS_SMC_64		0xC7000010U */
+
+/* PMF_SMC_GET_TIMESTAMP_32	0x87000020U */
+/* PMF_SMC_GET_TIMESTAMP_64	0xC7000020U */
+
+#endif /* VEN_EL3_SVC_H */
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
index 8c53ef9..6f89c16 100644
--- a/include/tools_share/cca_oid.h
+++ b/include/tools_share/cca_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,15 +30,17 @@
 
 /*
  * First undef previous definitions from tbbr_oid.h.
- * CCA ROTPK authenticates BL31 and its configuration image in
+ * CCA ROTPK authenticates BL31, SCP_BL2 and its configuration image in
  * CCA CoT.
  **/
 #undef BL31_IMAGE_KEY_OID
 #undef SOC_FW_CONFIG_KEY_OID
 #undef HW_CONFIG_KEY_OID
+#undef SCP_BL2_IMAGE_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 SCP_BL2_IMAGE_KEY_OID			ZERO_OID
 #define RMM_IMAGE_KEY_OID			ZERO_OID
 
 #endif /* CCA_OID_H */
diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h
index 9881d1a..1a2e355 100644
--- a/include/tools_share/tbbr_oid.h
+++ b/include/tools_share/tbbr_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -170,6 +170,12 @@
 #define SOC_FW_CONFIG_KEY_OID			SOC_FW_CONTENT_CERT_PK_OID
 #define HW_CONFIG_KEY_OID			ZERO_OID
 
+#define SCP_BL2_IMAGE_KEY_OID			SCP_FW_CONTENT_CERT_PK_OID
+#define BL32_IMAGE_KEY_OID			TRUSTED_OS_FW_CONTENT_CERT_PK_OID
+#define TOS_FW_CONFIG_KEY_OID			TRUSTED_OS_FW_CONTENT_CERT_PK_OID
+#define BL33_IMAGE_KEY_OID			NON_TRUSTED_FW_CONTENT_CERT_PK_OID
+#define NT_FW_CONFIG_KEY_OID			NON_TRUSTED_FW_CONTENT_CERT_PK_OID
+
 #ifdef PLAT_DEF_OID
 #include <platform_oid.h>
 #endif
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index f9c4baf..93771df 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,6 @@
 	.globl	zero_normalmem
 	.globl	zeromem
 	.globl	memcpy16
-	.globl	gpt_tlbi_by_pa_ll
 
 	.globl	disable_mmu_el1
 	.globl	disable_mmu_el3
@@ -594,20 +593,3 @@
 	b.lo	1b
 	ret
 endfunc fixup_gdt_reloc
-
-/*
- * TODO: Currently only supports size of 4KB,
- * support other sizes as well.
- */
-func gpt_tlbi_by_pa_ll
-#if ENABLE_ASSERTIONS
-	cmp	x1, #PAGE_SIZE_4KB
-	ASM_ASSERT(eq)
-	tst	x0, #(PAGE_SIZE_MASK)
-	ASM_ASSERT(eq)
-#endif
-	lsr	x0, x0, #FOUR_KB_SHIFT	/* 4KB size encoding is zero */
-	sys	#6, c8, c4, #7, x0 	/* TLBI RPALOS, <Xt> */
-	dsb	sy
-	ret
-endfunc gpt_tlbi_by_pa_ll
diff --git a/lib/compiler-rt/builtins/assembly.h b/lib/compiler-rt/builtins/assembly.h
index 169d496..8c42fc7 100644
--- a/lib/compiler-rt/builtins/assembly.h
+++ b/lib/compiler-rt/builtins/assembly.h
@@ -260,9 +260,10 @@
   .globl name SEPARATOR                                                        \
   SYMBOL_IS_FUNC(name) SEPARATOR                                               \
   DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR                          \
-  CFI_START SEPARATOR                                                          \
   DECLARE_FUNC_ENCODING                                                        \
-  name: SEPARATOR BTI_C
+  name:                                                                        \
+  SEPARATOR CFI_START                                                          \
+  SEPARATOR BTI_C
 
 #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target)                         \
   .globl SYMBOL_NAME(name) SEPARATOR                                           \
diff --git a/lib/compiler-rt/builtins/int_lib.h b/lib/compiler-rt/builtins/int_lib.h
index 04ea2d9..f6c1b7c 100644
--- a/lib/compiler-rt/builtins/int_lib.h
+++ b/lib/compiler-rt/builtins/int_lib.h
@@ -119,14 +119,14 @@
 #if defined(_MSC_VER) && !defined(__clang__)
 #include <intrin.h>
 
-int __inline __builtin_ctz(uint32_t value) {
+static int __inline __builtin_ctz(uint32_t value) {
   unsigned long trailing_zero = 0;
   if (_BitScanForward(&trailing_zero, value))
     return trailing_zero;
   return 32;
 }
 
-int __inline __builtin_clz(uint32_t value) {
+static int __inline __builtin_clz(uint32_t value) {
   unsigned long leading_zero = 0;
   if (_BitScanReverse(&leading_zero, value))
     return 31 - leading_zero;
@@ -134,14 +134,14 @@
 }
 
 #if defined(_M_ARM) || defined(_M_X64)
-int __inline __builtin_clzll(uint64_t value) {
+static int __inline __builtin_clzll(uint64_t value) {
   unsigned long leading_zero = 0;
   if (_BitScanReverse64(&leading_zero, value))
     return 63 - leading_zero;
   return 64;
 }
 #else
-int __inline __builtin_clzll(uint64_t value) {
+static int __inline __builtin_clzll(uint64_t value) {
   if (value == 0)
     return 64;
   uint32_t msh = (uint32_t)(value >> 32);
@@ -154,7 +154,7 @@
 
 #define __builtin_clzl __builtin_clzll
 
-bool __inline __builtin_sadd_overflow(int x, int y, int *result) {
+static bool __inline __builtin_sadd_overflow(int x, int y, int *result) {
   if ((x < 0) != (y < 0)) {
     *result = x + y;
     return false;
diff --git a/lib/compiler-rt/builtins/int_types.h b/lib/compiler-rt/builtins/int_types.h
index 18bf0a7..48862f3 100644
--- a/lib/compiler-rt/builtins/int_types.h
+++ b/lib/compiler-rt/builtins/int_types.h
@@ -107,8 +107,8 @@
 
 static __inline ti_int make_ti(di_int h, di_int l) {
   twords r;
-  r.s.high = h;
-  r.s.low = l;
+  r.s.high = (du_int)h;
+  r.s.low = (du_int)l;
   return r.all;
 }
 
@@ -139,7 +139,6 @@
   udwords u;
   double f;
 } double_bits;
-#endif
 
 typedef struct {
 #if _YUGA_LITTLE_ENDIAN
@@ -190,12 +189,16 @@
 #define CRT_LDBL_IEEE_F128
 #endif
 #define TF_C(x) x##L
-#elif __LDBL_MANT_DIG__ == 113
-// Use long double instead of __float128 if it matches the IEEE 128-bit format.
+#elif __LDBL_MANT_DIG__ == 113 ||                                              \
+    (__FLT_RADIX__ == 16 && __LDBL_MANT_DIG__ == 28)
+// Use long double instead of __float128 if it matches the IEEE 128-bit format
+// or the IBM hexadecimal format.
 #define CRT_LDBL_128BIT
 #define CRT_HAS_F128
+#if __LDBL_MANT_DIG__ == 113
 #define CRT_HAS_IEEE_TF
 #define CRT_LDBL_IEEE_F128
+#endif
 typedef long double tf_float;
 #define TF_C(x) x##L
 #elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
@@ -220,7 +223,6 @@
 #define CRT_HAS_TF_MODE
 #endif
 
-#if CRT_HAS_FLOATING_POINT
 #if __STDC_VERSION__ >= 199901L
 typedef float _Complex Fcomplex;
 typedef double _Complex Dcomplex;
@@ -270,5 +272,5 @@
 #define COMPLEXTF_IMAGINARY(x) (x).imaginary
 #endif
 
-#endif
+#endif // CRT_HAS_FLOATING_POINT
 #endif // INT_TYPES_H
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index 0faa276..16be161 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -26,12 +26,95 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A715_BHB_LOOP_COUNT, cortex_a715
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-workaround_runtime_start cortex_a715, ERRATUM(2561034), ERRATA_A715_2561034
+workaround_reset_start cortex_a715, ERRATUM(2331818), ERRATA_A715_2331818
+        sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(20)
+workaround_reset_end cortex_a715, ERRATUM(2331818)
+
+check_erratum_ls cortex_a715, ERRATUM(2331818), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2344187), ERRATA_A715_2344187
+	/* GCR_EL1 is only present with FEAT_MTE2. */
+	mrs x1, ID_AA64PFR1_EL1
+	ubfx x0, x1, ID_AA64PFR1_EL1_MTE_SHIFT, #4
+	cmp x0, #MTE_IMPLEMENTED_ELX
+	bne #1f
+	sysreg_bit_set GCR_EL1, GCR_EL1_RRND_BIT
+
+1:
+	/* Mitigation upon ERETAA and ERETAB. */
+	mov x0, #2
+	msr CORTEX_A715_CPUPSELR_EL3, x0
+	isb
+	ldr x0, =0xd69f0bff
+	msr CORTEX_A715_CPUPOR_EL3, x0
+	ldr x0, =0xfffffbff
+	msr CORTEX_A715_CPUPMR_EL3, x0
+	mov x1, #0
+	orr x1, x1, #(1<<0)
+	orr x1, x1, #(3<<4)
+	orr x1, x1, #(0xf<<6)
+	orr x1, x1, #(1<<13)
+	orr x1, x1, #(1<<53)
+	msr CORTEX_A715_CPUPCR_EL3, x1
+workaround_reset_end cortex_a715, ERRATUM(2344187)
+
+check_erratum_ls cortex_a715, ERRATUM(2344187), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2413290), ERRATA_A715_2413290
+/* Erratum 2413290 workaround is required only if SPE is enabled */
+#if ENABLE_SPE_FOR_NS != 0
+	/* Check if Static profiling extension is implemented or present. */
+	mrs x1, id_aa64dfr0_el1
+	ubfx x0, x1, ID_AA64DFR0_PMS_SHIFT, #4
+	cbz x0, 1f
+	/* Apply the workaround by setting CPUACTLR_EL1[58:57] = 0b11. */
+	sysreg_bit_set CORTEX_A715_CPUACTLR_EL1, BIT(57)
+	sysreg_bit_set CORTEX_A715_CPUACTLR_EL1, BIT(58)
+1:
+#endif
+workaround_reset_end cortex_a715, ERRATUM(2413290)
+
+check_erratum_range cortex_a715, ERRATUM(2413290), CPU_REV(1,0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2420947), ERRATA_A715_2420947
+        sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(33)
+workaround_reset_end cortex_a715, ERRATUM(2420947)
+
+check_erratum_range cortex_a715, ERRATUM(2420947), CPU_REV(1, 0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2429384), ERRATA_A715_2429384
+        sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(27)
+workaround_reset_end cortex_a715, ERRATUM(2429384)
+
+check_erratum_range cortex_a715, ERRATUM(2429384), CPU_REV(1, 0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2561034), ERRATA_A715_2561034
 	sysreg_bit_set	CORTEX_A715_CPUACTLR2_EL1, BIT(26)
-workaround_runtime_end cortex_a715, ERRATUM(2561034), NO_ISB
+workaround_reset_end cortex_a715, ERRATUM(2561034)
 
 check_erratum_range cortex_a715, ERRATUM(2561034), CPU_REV(1, 0), CPU_REV(1, 0)
 
+workaround_reset_start cortex_a715, ERRATUM(2728106), ERRATA_A715_2728106
+	mov x0, #3
+	msr CORTEX_A715_CPUPSELR_EL3, x0
+	isb
+	ldr x0, =0xd503339f
+	msr CORTEX_A715_CPUPOR_EL3, x0
+	ldr x0, =0xfffff3ff
+	msr CORTEX_A715_CPUPMR_EL3, x0
+	mov x0, #1
+	orr x0, x0, #(3<<4)
+	orr x0, x0, #(0xf<<6)
+	orr x0, x0, #(1<<13)
+	orr x0, x0, #(1<<20)
+	orr x0, x0, #(1<<22)
+	orr x0, x0, #(1<<31)
+	orr x0, x0, #(1<<50)
+	msr CORTEX_A715_CPUPCR_EL3, x0
+workaround_reset_end cortex_a715, ERRATUM(2728106)
+
+check_erratum_ls cortex_a715, ERRATUM(2728106), CPU_REV(1, 1)
+
 workaround_reset_start cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
index 4b28fdb..53a1b78 100644
--- a/lib/cpus/aarch64/cortex_a720.S
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +26,28 @@
         wa_cve_2022_23960_bhb_vector_table CORTEX_A720_BHB_LOOP_COUNT, cortex_a720
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start cortex_a720, ERRATUM(2926083), ERRATA_A720_2926083
+/* Erratum 2926083 workaround is required only if SPE is enabled */
+#if ENABLE_SPE_FOR_NS != 0
+	/* Check if Static profiling extension is implemented or present. */
+	mrs x1, id_aa64dfr0_el1
+	ubfx x0, x1, ID_AA64DFR0_PMS_SHIFT, #4
+	cbz x0, 1f
+	/* Apply the workaround by setting CPUACTLR_EL1[58:57] = 0b11. */
+	sysreg_bit_set CORTEX_A720_CPUACTLR_EL1, BIT(57)
+	sysreg_bit_set CORTEX_A720_CPUACTLR_EL1, BIT(58)
+1:
+#endif
+workaround_reset_end cortex_a720, ERRATUM(2926083)
+
+check_erratum_ls cortex_a720, ERRATUM(2926083), CPU_REV(0, 1)
+
+workaround_reset_start cortex_a720, ERRATUM(2940794), ERRATA_A720_2940794
+        sysreg_bit_set CORTEX_A720_CPUACTLR2_EL1, BIT(37)
+workaround_reset_end cortex_a720, ERRATUM(2940794)
+
+check_erratum_ls cortex_a720, ERRATUM(2940794), CPU_REV(0, 1)
+
 workaround_reset_start cortex_a720, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
diff --git a/lib/cpus/aarch64/cortex_a725.S b/lib/cpus/aarch64/cortex_a725.S
new file mode 100644
index 0000000..c08945f
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a725.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023-2024, 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_a725.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A725 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-A725 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_a725
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_a725
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a725_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_A725_CPUPWRCTLR_EL1, CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_a725_core_pwr_dwn
+
+errata_report_shim cortex_a725
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-A725 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_a725_regs, "aS"
+cortex_a725_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a725_cpu_reg_dump
+	adr	x6, cortex_a725_regs
+	mrs	x8, CORTEX_A725_CPUECTLR_EL1
+	ret
+endfunc cortex_a725_cpu_reg_dump
+
+declare_cpu_ops cortex_a725, CORTEX_A725_MIDR, \
+	cortex_a725_reset_func, \
+	cortex_a725_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_blackhawk.S b/lib/cpus/aarch64/cortex_blackhawk.S
deleted file mode 100644
index b7b7a2d..0000000
--- a/lib/cpus/aarch64/cortex_blackhawk.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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_blackhawk.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex blackhawk must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex blackhawk supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start cortex_blackhawk
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end cortex_blackhawk
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_blackhawk_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	sysreg_bit_set CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	isb
-	ret
-endfunc cortex_blackhawk_core_pwr_dwn
-
-errata_report_shim cortex_blackhawk
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Blackhawk 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_blackhawk_regs, "aS"
-cortex_blackhawk_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_blackhawk_cpu_reg_dump
-	adr	x6, cortex_blackhawk_regs
-	mrs	x8, CORTEX_BLACKHAWK_CPUECTLR_EL1
-	ret
-endfunc cortex_blackhawk_cpu_reg_dump
-
-declare_cpu_ops cortex_blackhawk, CORTEX_BLACKHAWK_MIDR, \
-	cortex_blackhawk_reset_func, \
-	cortex_blackhawk_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_chaberton.S b/lib/cpus/aarch64/cortex_chaberton.S
deleted file mode 100644
index 596fe4a..0000000
--- a/lib/cpus/aarch64/cortex_chaberton.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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_chaberton.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Chaberton must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Chaberton supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start cortex_chaberton
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end cortex_chaberton
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_chaberton_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	sysreg_bit_set CORTEX_CHABERTON_CPUPWRCTLR_EL1, CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	isb
-	ret
-endfunc cortex_chaberton_core_pwr_dwn
-
-errata_report_shim cortex_chaberton
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Chaberton 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_chaberton_regs, "aS"
-cortex_chaberton_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_chaberton_cpu_reg_dump
-	adr	x6, cortex_chaberton_regs
-	mrs	x8, CORTEX_CHABERTON_CPUECTLR_EL1
-	ret
-endfunc cortex_chaberton_cpu_reg_dump
-
-declare_cpu_ops cortex_chaberton, CORTEX_CHABERTON_MIDR, \
-	cortex_chaberton_reset_func, \
-	cortex_chaberton_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_gelas.S b/lib/cpus/aarch64/cortex_gelas.S
index dc704f2..8870019 100644
--- a/lib/cpus/aarch64/cortex_gelas.S
+++ b/lib/cpus/aarch64/cortex_gelas.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,7 +42,7 @@
 	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
+        cmp     x0, #SME_NOT_IMPLEMENTED
 	b.eq	1f
 	msr	CORTEX_GELAS_SVCRSM, xzr
 	msr	CORTEX_GELAS_SVCRZA, xzr
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index e5a05fc..49e9ad1 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -51,6 +51,13 @@
 
 check_erratum_ls cortex_x3, ERRATUM(2313909), CPU_REV(1, 0)
 
+workaround_reset_start cortex_x3, ERRATUM(2372204), ERRATA_X3_2372204
+	/* Set bit 40 in CPUACTLR2_EL1 */
+	sysreg_bit_set CORTEX_X3_CPUACTLR2_EL1, BIT(40)
+workaround_reset_end cortex_x3, ERRATUM(2372204)
+
+check_erratum_ls cortex_x3, ERRATUM(2372204), CPU_REV(1, 0)
+
 workaround_reset_start cortex_x3, ERRATUM(2615812), ERRATA_X3_2615812
 	/* Disable retention control for WFI and WFE. */
 	mrs	x0, CORTEX_X3_CPUPWRCTLR_EL1
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 7619f9c..20f1ae1 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +26,19 @@
         wa_cve_2022_23960_bhb_vector_table CORTEX_X4_BHB_LOOP_COUNT, cortex_x4
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_runtime_start cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
+	/* dsb before isb of power down sequence */
+	dsb	sy
+workaround_runtime_end cortex_x4, ERRATUM(2740089)
+
+check_erratum_ls cortex_x4, ERRATUM(2740089), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(2763018), ERRATA_X4_2763018
+	sysreg_bit_set	CORTEX_X4_CPUACTLR3_EL1, BIT(47)
+workaround_reset_end cortex_x4, ERRATUM(2763018)
+
+check_erratum_ls cortex_x4, ERRATUM(2763018), CPU_REV(0, 1)
+
 workaround_reset_start cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -53,6 +66,9 @@
 	 * ---------------------------------------------------
 	 */
 	sysreg_bit_set CORTEX_X4_CPUPWRCTLR_EL1, CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
+	apply_erratum cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
+
 	isb
 	ret
 endfunc cortex_x4_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
new file mode 100644
index 0000000..36b442e
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023-2024, 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_x925.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-X925 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-X925 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_x925
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_x925
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_x925_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_X925_CPUPWRCTLR_EL1, CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_x925_core_pwr_dwn
+
+errata_report_shim cortex_x925
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-X925 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_x925_regs, "aS"
+cortex_x925_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_x925_cpu_reg_dump
+	adr	x6, cortex_x925_regs
+	mrs	x8, CORTEX_X925_CPUECTLR_EL1
+	ret
+endfunc cortex_x925_cpu_reg_dump
+
+declare_cpu_ops cortex_x925, CORTEX_X925_MIDR, \
+	cortex_x925_reset_func, \
+	cortex_x925_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 1ae3180..3aa4f15 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -165,13 +165,13 @@
 	and	w2, w2, w3
 
 	/* Get the cpu_ops end location */
-	adr	x5, (__CPU_OPS_END__ + CPU_MIDR)
+	adr_l	x5, (__CPU_OPS_END__ + CPU_MIDR)
 
 	/* Initialize the return parameter */
 	mov	x0, #0
 1:
 	/* Get the cpu_ops start location */
-	adr	x4, (__CPU_OPS_START__ + CPU_MIDR)
+	adr_l	x4, (__CPU_OPS_START__ + CPU_MIDR)
 
 2:
 	/* Check if we have reached end of list */
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index 8e5b459..3c5bf2e 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -24,6 +24,7 @@
 	 */
 	.globl	check_errata_dsu_798953
 	.globl	errata_dsu_798953_wa
+	.globl	dsu_pwr_dwn
 
 func check_errata_dsu_798953
 	mov	x2, #ERRATA_APPLIES
@@ -202,3 +203,15 @@
 1:
 	ret	x8
 endfunc errata_dsu_2313941_wa
+
+	/* ---------------------------------------------
+	 * controls power features of the cluster
+	 * 1. Cache portion power not request
+	 * 2. Disable the retention circuit
+	 * ---------------------------------------------
+	 */
+func dsu_pwr_dwn
+	msr	CLUSTERPWRCTLR_EL1, xzr
+	isb
+	ret
+endfunc dsu_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_hermes.S b/lib/cpus/aarch64/neoverse_hermes.S
deleted file mode 100644
index cb90b71..0000000
--- a/lib/cpus/aarch64/neoverse_hermes.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 <neoverse_hermes.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Neoverse Hermes must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Neoverse Hermes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start neoverse_hermes
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end neoverse_hermes
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func neoverse_hermes_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	sysreg_bit_set NEOVERSE_HERMES_CPUPWRCTLR_EL1, NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	isb
-	ret
-endfunc neoverse_hermes_core_pwr_dwn
-
-errata_report_shim neoverse_hermes
-
-	/* ---------------------------------------------
-	 * This function provides Neoverse Hermes 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.neoverse_hermes_regs, "aS"
-neoverse_hermes_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func neoverse_hermes_cpu_reg_dump
-	adr	x6, neoverse_hermes_regs
-	mrs	x8, NEOVERSE_HERMES_CPUECTLR_EL1
-	ret
-endfunc neoverse_hermes_cpu_reg_dump
-
-declare_cpu_ops neoverse_hermes, NEOVERSE_HERMES_MIDR, \
-	neoverse_hermes_reset_func, \
-	neoverse_hermes_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n3.S b/lib/cpus/aarch64/neoverse_n3.S
new file mode 100644
index 0000000..0b33b7e
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_n3.S
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_n3.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse-N3 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse-N3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start neoverse_n3
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if NEOVERSE_Nx_EXTERNAL_LLC
+	/* Some systems may have External LLC, core needs to be made aware */
+	sysreg_bit_set NEOVERSE_N3_CPUECTLR_EL1, NEOVERSE_N3_CPUECTLR_EL1_EXTLLC_BIT
+#endif
+cpu_reset_func_end neoverse_n3
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func neoverse_n3_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set NEOVERSE_N3_CPUPWRCTLR_EL1, NEOVERSE_N3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc neoverse_n3_core_pwr_dwn
+
+errata_report_shim neoverse_n3
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse-N3 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.neoverse_n3_regs, "aS"
+neoverse_n3_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_n3_cpu_reg_dump
+	adr	x6, neoverse_n3_regs
+	mrs	x8, NEOVERSE_N3_CPUECTLR_EL1
+	ret
+endfunc neoverse_n3_cpu_reg_dump
+
+declare_cpu_ops neoverse_n3, NEOVERSE_N3_MIDR, \
+	neoverse_n3_reset_func, \
+	neoverse_n3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_poseidon.S b/lib/cpus/aarch64/neoverse_poseidon.S
deleted file mode 100644
index 54c2ff9..0000000
--- a/lib/cpus/aarch64/neoverse_poseidon.S
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <neoverse_poseidon.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-#include "wa_cve_2022_23960_bhb_vector.S"
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Neoverse Poseidon must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Neoverse Poseidon supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-#if WORKAROUND_CVE_2022_23960
-	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
-	 * ---------------------------------------------
-	 */
-func neoverse_poseidon_core_pwr_dwn
-	/* ---------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
-	 */
-	sysreg_bit_set NEOVERSE_POSEIDON_CPUPWRCTLR_EL1, \
-		NEOVERSE_POSEIDON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-
-	isb
-	ret
-endfunc neoverse_poseidon_core_pwr_dwn
-
-cpu_reset_func_start neoverse_poseidon
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end neoverse_poseidon
-
-errata_report_shim neoverse_poseidon
-
-	/* ---------------------------------------------
-	 * This function provides Neoverse-Poseidon 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.neoverse_poseidon_regs, "aS"
-neoverse_poseidon_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func neoverse_poseidon_cpu_reg_dump
-	adr	x6, neoverse_poseidon_regs
-	mrs	x8, NEOVERSE_POSEIDON_CPUECTLR_EL1
-	ret
-endfunc neoverse_poseidon_cpu_reg_dump
-
-declare_cpu_ops neoverse_poseidon, NEOVERSE_POSEIDON_VNAE_MIDR, \
-	neoverse_poseidon_reset_func, \
-	neoverse_poseidon_core_pwr_dwn
-
-declare_cpu_ops neoverse_poseidon, NEOVERSE_POSEIDON_V_MIDR, \
-	neoverse_poseidon_reset_func, \
-	neoverse_poseidon_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index d4b3a96..3179918 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -109,6 +109,11 @@
 cpu_reset_func_start neoverse_v2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+
+#if NEOVERSE_Vx_EXTERNAL_LLC
+	/* Some systems may have External LLC, core needs to be made aware */
+	sysreg_bit_set NEOVERSE_V2_CPUECTLR_EL1, NEOVERSE_V2_CPUECTLR_EL1_EXTLLC_BIT
+#endif
 cpu_reset_func_end neoverse_v2
 
 errata_report_shim neoverse_v2
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
new file mode 100644
index 0000000..67258c8
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_v3.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse V3 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse V3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V3_BHB_LOOP_COUNT, neoverse_v3
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+workaround_reset_start neoverse_v3, CVE(2022,23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse V3 generic vectors are overridden to apply errata
+         * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_neoverse_v3
+
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_v3, CVE(2022,23960)
+
+check_erratum_chosen neoverse_v3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
+	/* ---------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ---------------------------------------------
+	 */
+func neoverse_v3_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------
+	 */
+	sysreg_bit_set NEOVERSE_V3_CPUPWRCTLR_EL1, \
+		NEOVERSE_V3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
+	isb
+	ret
+endfunc neoverse_v3_core_pwr_dwn
+
+cpu_reset_func_start neoverse_v3
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end neoverse_v3
+
+errata_report_shim neoverse_v3
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse V3 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.neoverse_v3_regs, "aS"
+neoverse_v3_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_v3_cpu_reg_dump
+	adr	x6, neoverse_v3_regs
+	mrs	x8, NEOVERSE_V3_CPUECTLR_EL1
+	ret
+endfunc neoverse_v3_cpu_reg_dump
+
+declare_cpu_ops neoverse_v3, NEOVERSE_V3_VNAE_MIDR, \
+	neoverse_v3_reset_func, \
+	neoverse_v3_core_pwr_dwn
+
+declare_cpu_ops neoverse_v3, NEOVERSE_V3_MIDR, \
+	neoverse_v3_reset_func, \
+	neoverse_v3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S
index 2abefe9..ba06f55 100644
--- a/lib/cpus/aarch64/travis.S
+++ b/lib/cpus/aarch64/travis.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,7 +38,7 @@
 	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
+        cmp     x0, #SME_NOT_IMPLEMENTED
 	b.eq	1f
 	msr	TRAVIS_SVCRSM, xzr
 	msr	TRAVIS_SVCRZA, xzr
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index dcbeba1..f736b5a 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -790,14 +790,22 @@
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_X3_2313909
 
+# Flag to apply erratum 2372204 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_X3_2372204
+
 # Flag to apply erratum 2615812 workaround on powerdown. This erratum applies
-# to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is still open.
+# to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2615812
 
 # Flag to apply erratum 2641945 workaround on reset. This erratum applies
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_X3_2641945
 
+# 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_X3_2701951
+
 # 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
@@ -810,6 +818,19 @@
 # to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2779509
 
+# Flag to apply erratum 2701112 workaround for platforms that do not use an
+# Arm interconnect IP. This erratum applies to revisions r0p0 of the Cortex-X4
+# cpu and is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_X4_2701112
+
+# Flag to apply erratum 2740089 workaround during powerdown. This erratum
+# applies to all revisions <= r0p1 of the Cortex-X4 cpu, it is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2740089
+
+# Flag to apply erratum 2763018 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2763018
+
 # 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
@@ -903,13 +924,41 @@
 # This erratum applies to revisions r0p0, r0p1. Fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2801372
 
+# Flag to apply erratum 2331818 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2331818
+
+# Flag to apply erratum 2344187 workaround during reset. This erratum applies
+# to revisions r0p0, and r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2344187
+
+# Flag to apply erratum 2413290 workaround during reset. This erratum applies
+# only to revision r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2413290
+
+# Flag to apply erratum 2420947 workaround during reset. This erratum applies
+# only to revision r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2420947
+
+# Flag to apply erratum 2429384 workaround during reset. This erratum applies
+# to revision r1p0. There is no workaround for r0p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2429384
+
 # Flag to apply erratum 2561034 workaround during reset. This erratum applies
 # only to revision r1p0. It is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_A715_2561034
 
-# 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
+# Flag to apply erratum 2728106 workaround during reset. This erratum applies
+# only to revision r0p0, r1p0 and r1p1. It is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_A715_2728106
+
+# Flag to apply erratum 2926083 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2926083
+
+# Flag to apply erratum 2940794 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2940794
 
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index b60b8e0..132888c 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -149,14 +149,13 @@
 		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_init_el3();
+	if (is_feat_pmuv3_present()) {
+		pmuv3_init_el3();
+	}
 #endif /*  IMAGE_BL32 */
 }
 
+#if !IMAGE_BL1
 /*******************************************************************************
  * The following function initializes the cpu_context for a CPU specified by
  * its `cpu_idx` for first use, and sets the initial entrypoint state as
@@ -169,6 +168,7 @@
 	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
 	cm_setup_context(ctx, ep);
 }
+#endif /* !IMAGE_BL1 */
 
 /*******************************************************************************
  * The following function initializes the cpu_context for the current CPU
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 76aebf9..1fce1bf 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -454,15 +454,17 @@
 	synchronize_errors
 #endif /* IMAGE_BL31 */
 
-	/* ----------------------------------------------------------
-	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
-	 * ----------------------------------------------------------
+	/* --------------------------------------------------------------
+	 * Restore MDCR_EL3, SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
+	 * --------------------------------------------------------------
 	 */
-	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
 	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-	msr	scr_el3, x18
+	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldr	x19, [sp, #CTX_EL3STATE_OFFSET + CTX_MDCR_EL3]
 	msr	spsr_el3, x16
 	msr	elr_el3, x17
+	msr	scr_el3, x18
+	msr	mdcr_el3, x19
 
 	restore_ptw_el1_sys_regs
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 922b2cf..981fddc 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -42,6 +42,7 @@
 per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
 static bool has_secure_perworld_init;
 
+static void manage_extensions_common(cpu_context_t *ctx);
 static void manage_extensions_nonsecure(cpu_context_t *ctx);
 static void manage_extensions_secure(cpu_context_t *ctx);
 static void manage_extensions_secure_per_world(void);
@@ -123,8 +124,8 @@
 	scr_el3 |= get_scr_el3_from_routing_model(SECURE);
 #endif
 
-	/* Allow access to Allocation Tags when mte is set*/
-	if (is_feat_mte_supported()) {
+	/* Allow access to Allocation Tags when FEAT_MTE2 is implemented and enabled. */
+	if (is_feat_mte2_supported()) {
 		scr_el3 |= SCR_ATA_BIT;
 	}
 
@@ -193,8 +194,10 @@
 	/* SCR_NS: Set the NS bit */
 	scr_el3 |= SCR_NS_BIT;
 
-	/* Allow access to Allocation Tags when MTE is implemented. */
-	scr_el3 |= SCR_ATA_BIT;
+	/* Allow access to Allocation Tags when FEAT_MTE2 is implemented and enabled. */
+	if (is_feat_mte2_supported()) {
+		scr_el3 |= SCR_ATA_BIT;
+	}
 
 #if !CTX_INCLUDE_PAUTH_REGS
 	/*
@@ -259,13 +262,9 @@
 #if CTX_INCLUDE_EL2_REGS
 
 	/*
-	 * Initialize SCTLR_EL2 context register using Endianness value
-	 * taken from the entrypoint attribute.
+	 * Initialize SCTLR_EL2 context register with reset value.
 	 */
-	u_register_t sctlr_el2 = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
-	sctlr_el2 |= SCTLR_EL2_RES1;
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_SCTLR_EL2,
-			sctlr_el2);
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), sctlr_el2, SCTLR_EL2_RES1);
 
 	if (is_feat_hcx_supported()) {
 		/*
@@ -276,7 +275,7 @@
 		 * this feature if not properly initialized, especially when
 		 * it comes to those bits that enable/disable traps.
 		 */
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
+		write_el2_ctx_hcx(get_el2_sysregs_ctx(ctx), hcrx_el2,
 			HCRX_EL2_INIT_VAL);
 	}
 
@@ -286,13 +285,14 @@
 		 * 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,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgitr_el2,
 			HFGITR_EL2_INIT_VAL);
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGRTR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgrtr_el2,
 			HFGRTR_EL2_INIT_VAL);
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGWTR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgwtr_el2,
 			HFGWTR_EL2_INIT_VAL);
 	}
+
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	manage_extensions_nonsecure(ctx);
@@ -309,6 +309,7 @@
 static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
 	u_register_t scr_el3;
+	u_register_t mdcr_el3;
 	el3_state_t *state;
 	gp_regs_t *gp_regs;
 
@@ -330,9 +331,9 @@
 	 * These bits are set in the gicv3 driver. Losing them (especially the
 	 * SRE bit) is problematic for all worlds. Henceforth recreate them.
 	 */
-	u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+	u_register_t icc_sre_el2_val = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
 				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
-	write_ctx_reg(el2_ctx, CTX_ICC_SRE_EL2, icc_sre_el2);
+	write_el2_ctx_common(el2_ctx, icc_sre_el2, icc_sre_el2_val);
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	/* Start with a clean SCR_EL3 copy as all relevant values are set */
@@ -481,6 +482,37 @@
 	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
 	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
 
+	/* Start with a clean MDCR_EL3 copy as all relevant values are set */
+	mdcr_el3 = MDCR_EL3_RESET_VAL;
+
+	/* ---------------------------------------------------------------------
+	 * Initialise MDCR_EL3, setting all fields rather than relying on hw.
+	 * Some fields are architecturally UNKNOWN on reset.
+	 *
+	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
+	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
+	 *  disabled from all ELs in Secure state.
+	 *
+	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
+	 *  privileged debug from S-EL1.
+	 *
+	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
+	 *  access to the powerdown debug registers do not trap to EL3.
+	 *
+	 * 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 |= ((MDCR_SDD_BIT | MDCR_SPD32(MDCR_SPD32_DISABLE))
+			& ~(MDCR_TDA_BIT | MDCR_TDOSA_BIT)) ;
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3);
+
+	/*
+	 * Configure MDCR_EL3 register as applicable for each world
+	 * (NS/Secure/Realm) context.
+	 */
+	manage_extensions_common(ctx);
+
 	/*
 	 * Store the X0-X7 value from the entrypoint into the context
 	 * Use memcpy as we are in control of the layout of the structures
@@ -557,10 +589,6 @@
 #if IMAGE_BL31
 void cm_manage_extensions_el3(void)
 {
-	if (is_feat_spe_supported()) {
-		spe_init_el3();
-	}
-
 	if (is_feat_amu_supported()) {
 		amu_init_el3();
 	}
@@ -569,18 +597,6 @@
 		sme_init_el3();
 	}
 
-	if (is_feat_trbe_supported()) {
-		trbe_init_el3();
-	}
-
-	if (is_feat_brbe_supported()) {
-		brbe_init_el3();
-	}
-
-	if (is_feat_trf_supported()) {
-		trf_init_el3();
-	}
-
 	pmuv3_init_el3();
 }
 #endif /* IMAGE_BL31 */
@@ -701,6 +717,48 @@
 }
 
 /*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world only
+ * and disable for secure world.
+ *
+ * NOTE: Arch features which have been provided with the capability of getting
+ * enabled only for non-secure world and being disabled for secure world are
+ * grouped here, as the MDCR_EL3 context value remains same across the worlds.
+ ******************************************************************************/
+static void manage_extensions_common(cpu_context_t *ctx)
+{
+#if IMAGE_BL31
+	if (is_feat_spe_supported()) {
+		/*
+		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
+		 */
+		spe_enable(ctx);
+	}
+
+	if (is_feat_trbe_supported()) {
+		/*
+		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure and
+		 * Realm state.
+		 */
+		trbe_enable(ctx);
+	}
+
+	if (is_feat_trf_supported()) {
+		/*
+		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
+		 */
+		trf_enable(ctx);
+	}
+
+	if (is_feat_brbe_supported()) {
+		/*
+		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
+		 */
+		brbe_enable(ctx);
+	}
+#endif /* IMAGE_BL31 */
+}
+
+/*******************************************************************************
  * Enable architecture extensions on first entry to Non-secure world.
  ******************************************************************************/
 static void manage_extensions_nonsecure(cpu_context_t *ctx)
@@ -806,6 +864,7 @@
 #endif /* IMAGE_BL31 */
 }
 
+#if !IMAGE_BL1
 /*******************************************************************************
  * The following function initializes the cpu_context for a CPU specified by
  * its `cpu_idx` for first use, and sets the initial entrypoint state as
@@ -818,6 +877,7 @@
 	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
 	cm_setup_context(ctx, ep);
 }
+#endif /* !IMAGE_BL1 */
 
 /*******************************************************************************
  * The following function initializes the cpu_context for the current CPU
@@ -947,7 +1007,7 @@
  ******************************************************************************/
 void cm_prepare_el3_exit(uint32_t security_state)
 {
-	u_register_t sctlr_elx, scr_el3;
+	u_register_t sctlr_el2, scr_el3;
 	cpu_context_t *ctx = cm_get_context(security_state);
 
 	assert(ctx != NULL);
@@ -958,8 +1018,8 @@
 		scr_el3 = read_ctx_reg(get_el3state_ctx(ctx),
 						 CTX_SCR_EL3);
 
-		if (((scr_el3 & SCR_HCE_BIT) != 0U)
-			|| (el2_implemented != EL_IMPL_NONE)) {
+		if (el2_implemented != EL_IMPL_NONE) {
+
 			/*
 			 * If context is not being used for EL2, initialize
 			 * HCRX_EL2 with its init value here.
@@ -985,29 +1045,29 @@
 				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),
-							   CTX_SCTLR_EL1);
-			sctlr_elx &= SCTLR_EE_BIT;
-			sctlr_elx |= SCTLR_EL2_RES1;
+			/* Condition to ensure EL2 is being used. */
+			if ((scr_el3 & SCR_HCE_BIT) != 0U) {
+				/* Initialize SCTLR_EL2 register with reset value. */
+				sctlr_el2 = SCTLR_EL2_RES1;
 #if ERRATA_A75_764081
-			/*
-			 * If workaround of errata 764081 for Cortex-A75 is used
-			 * then set SCTLR_EL2.IESB to enable Implicit Error
-			 * Synchronization Barrier.
-			 */
-			sctlr_elx |= SCTLR_IESB_BIT;
+				/*
+				 * If workaround of errata 764081 for Cortex-A75
+				 * is used then set SCTLR_EL2.IESB to enable
+				 * Implicit Error Synchronization Barrier.
+				 */
+				sctlr_el2 |= SCTLR_IESB_BIT;
 #endif
-			write_sctlr_el2(sctlr_elx);
-		} else if (el2_implemented != EL_IMPL_NONE) {
-			init_nonsecure_el2_unused(ctx);
+				write_sctlr_el2(sctlr_el2);
+			} else {
+				/*
+				 * (scr_el3 & SCR_HCE_BIT==0)
+				 * EL2 implemented but unused.
+				 */
+				init_nonsecure_el2_unused(ctx);
+			}
 		}
 	}
-
 	cm_el1_sysregs_context_restore(security_state);
 	cm_set_next_eret_context(security_state);
 }
@@ -1016,35 +1076,33 @@
 
 static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
 {
-	write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
+	write_el2_ctx_fgt(ctx, hdfgrtr_el2, read_hdfgrtr_el2());
 	if (is_feat_amu_supported()) {
-		write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
+		write_el2_ctx_fgt(ctx, hafgrtr_el2, read_hafgrtr_el2());
 	}
-	write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
-	write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
-	write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
-	write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
+	write_el2_ctx_fgt(ctx, hdfgwtr_el2, read_hdfgwtr_el2());
+	write_el2_ctx_fgt(ctx, hfgitr_el2, read_hfgitr_el2());
+	write_el2_ctx_fgt(ctx, hfgrtr_el2, read_hfgrtr_el2());
+	write_el2_ctx_fgt(ctx, hfgwtr_el2, read_hfgwtr_el2());
 }
 
 static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx)
 {
-	write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
+	write_hdfgrtr_el2(read_el2_ctx_fgt(ctx, hdfgrtr_el2));
 	if (is_feat_amu_supported()) {
-		write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
+		write_hafgrtr_el2(read_el2_ctx_fgt(ctx, hafgrtr_el2));
 	}
-	write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
-	write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
-	write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
-	write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
+	write_hdfgwtr_el2(read_el2_ctx_fgt(ctx, hdfgwtr_el2));
+	write_hfgitr_el2(read_el2_ctx_fgt(ctx, hfgitr_el2));
+	write_hfgrtr_el2(read_el2_ctx_fgt(ctx, hfgrtr_el2));
+	write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
 }
 
-#if CTX_INCLUDE_MPAM_REGS
-
-static void el2_sysregs_context_save_mpam(mpam_t *ctx)
+static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_ctx_reg(ctx, CTX_MPAM2_EL2, read_mpam2_el2());
+	write_el2_ctx_mpam(ctx, mpam2_el2, read_mpam2_el2());
 
 	/*
 	 * The context registers that we intend to save would be part of the
@@ -1058,9 +1116,9 @@
 	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 are always present if
 	 * MPAMIDR_HAS_HCR_BIT == 1.
 	 */
-	write_ctx_reg(ctx, CTX_MPAMHCR_EL2, read_mpamhcr_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPM0_EL2, read_mpamvpm0_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPMV_EL2, read_mpamvpmv_el2());
+	write_el2_ctx_mpam(ctx, mpamhcr_el2, read_mpamhcr_el2());
+	write_el2_ctx_mpam(ctx, mpamvpm0_el2, read_mpamvpm0_el2());
+	write_el2_ctx_mpam(ctx, mpamvpmv_el2, read_mpamvpmv_el2());
 
 	/*
 	 * The number of MPAMVPM registers is implementation defined, their
@@ -1068,71 +1126,67 @@
 	 */
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_ctx_reg(ctx, CTX_MPAMVPM7_EL2, read_mpamvpm7_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm7_el2, read_mpamvpm7_el2());
 		__fallthrough;
 	case 6:
-		write_ctx_reg(ctx, CTX_MPAMVPM6_EL2, read_mpamvpm6_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm6_el2, read_mpamvpm6_el2());
 		__fallthrough;
 	case 5:
-		write_ctx_reg(ctx, CTX_MPAMVPM5_EL2, read_mpamvpm5_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm5_el2, read_mpamvpm5_el2());
 		__fallthrough;
 	case 4:
-		write_ctx_reg(ctx, CTX_MPAMVPM4_EL2, read_mpamvpm4_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm4_el2, read_mpamvpm4_el2());
 		__fallthrough;
 	case 3:
-		write_ctx_reg(ctx, CTX_MPAMVPM3_EL2, read_mpamvpm3_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm3_el2, read_mpamvpm3_el2());
 		__fallthrough;
 	case 2:
-		write_ctx_reg(ctx, CTX_MPAMVPM2_EL2, read_mpamvpm2_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm2_el2, read_mpamvpm2_el2());
 		__fallthrough;
 	case 1:
-		write_ctx_reg(ctx, CTX_MPAMVPM1_EL2, read_mpamvpm1_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm1_el2, read_mpamvpm1_el2());
 		break;
 	}
 }
 
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-#if CTX_INCLUDE_MPAM_REGS
-static void el2_sysregs_context_restore_mpam(mpam_t *ctx)
+static void el2_sysregs_context_restore_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_mpam2_el2(read_ctx_reg(ctx, CTX_MPAM2_EL2));
+	write_mpam2_el2(read_el2_ctx_mpam(ctx, mpam2_el2));
 
 	if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
 		return;
 	}
 
-	write_mpamhcr_el2(read_ctx_reg(ctx, CTX_MPAMHCR_EL2));
-	write_mpamvpm0_el2(read_ctx_reg(ctx, CTX_MPAMVPM0_EL2));
-	write_mpamvpmv_el2(read_ctx_reg(ctx, CTX_MPAMVPMV_EL2));
+	write_mpamhcr_el2(read_el2_ctx_mpam(ctx, mpamhcr_el2));
+	write_mpamvpm0_el2(read_el2_ctx_mpam(ctx, mpamvpm0_el2));
+	write_mpamvpmv_el2(read_el2_ctx_mpam(ctx, mpamvpmv_el2));
 
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_mpamvpm7_el2(read_ctx_reg(ctx, CTX_MPAMVPM7_EL2));
+		write_mpamvpm7_el2(read_el2_ctx_mpam(ctx, mpamvpm7_el2));
 		__fallthrough;
 	case 6:
-		write_mpamvpm6_el2(read_ctx_reg(ctx, CTX_MPAMVPM6_EL2));
+		write_mpamvpm6_el2(read_el2_ctx_mpam(ctx, mpamvpm6_el2));
 		__fallthrough;
 	case 5:
-		write_mpamvpm5_el2(read_ctx_reg(ctx, CTX_MPAMVPM5_EL2));
+		write_mpamvpm5_el2(read_el2_ctx_mpam(ctx, mpamvpm5_el2));
 		__fallthrough;
 	case 4:
-		write_mpamvpm4_el2(read_ctx_reg(ctx, CTX_MPAMVPM4_EL2));
+		write_mpamvpm4_el2(read_el2_ctx_mpam(ctx, mpamvpm4_el2));
 		__fallthrough;
 	case 3:
-		write_mpamvpm3_el2(read_ctx_reg(ctx, CTX_MPAMVPM3_EL2));
+		write_mpamvpm3_el2(read_el2_ctx_mpam(ctx, mpamvpm3_el2));
 		__fallthrough;
 	case 2:
-		write_mpamvpm2_el2(read_ctx_reg(ctx, CTX_MPAMVPM2_EL2));
+		write_mpamvpm2_el2(read_el2_ctx_mpam(ctx, mpamvpm2_el2));
 		__fallthrough;
 	case 1:
-		write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
+		write_mpamvpm1_el2(read_el2_ctx_mpam(ctx, mpamvpm1_el2));
 		break;
 	}
 }
-#endif /* CTX_INCLUDE_MPAM_REGS */
 
 /* ---------------------------------------------------------------------------
  * The following registers are not added:
@@ -1148,38 +1202,37 @@
 static void el2_sysregs_context_save_gic(el2_sysregs_t *ctx)
 {
 #if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
-	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+	write_el2_ctx_common(ctx, icc_sre_el2, read_icc_sre_el2());
 #else
 	u_register_t scr_el3 = read_scr_el3();
 	write_scr_el3(scr_el3 | SCR_NS_BIT);
 	isb();
 
-	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+	write_el2_ctx_common(ctx, icc_sre_el2, read_icc_sre_el2());
 
 	write_scr_el3(scr_el3);
 	isb();
-
 #endif
-	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_el2_ctx_common(ctx, ich_hcr_el2, read_ich_hcr_el2());
+	write_el2_ctx_common(ctx, ich_vmcr_el2, read_ich_vmcr_el2());
 }
 
 static void el2_sysregs_context_restore_gic(el2_sysregs_t *ctx)
 {
 #if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
-	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+	write_icc_sre_el2(read_el2_ctx_common(ctx, icc_sre_el2));
 #else
 	u_register_t scr_el3 = read_scr_el3();
 	write_scr_el3(scr_el3 | SCR_NS_BIT);
 	isb();
 
-	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+	write_icc_sre_el2(read_el2_ctx_common(ctx, icc_sre_el2));
 
 	write_scr_el3(scr_el3);
 	isb();
 #endif
-	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_ich_hcr_el2(read_el2_ctx_common(ctx, ich_hcr_el2));
+	write_ich_vmcr_el2(read_el2_ctx_common(ctx, ich_vmcr_el2));
 }
 
 /* -----------------------------------------------------
@@ -1190,70 +1243,70 @@
  */
 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());
+	write_el2_ctx_common(ctx, actlr_el2, read_actlr_el2());
+	write_el2_ctx_common(ctx, afsr0_el2, read_afsr0_el2());
+	write_el2_ctx_common(ctx, afsr1_el2, read_afsr1_el2());
+	write_el2_ctx_common(ctx, amair_el2, read_amair_el2());
+	write_el2_ctx_common(ctx, cnthctl_el2, read_cnthctl_el2());
+	write_el2_ctx_common(ctx, cntvoff_el2, read_cntvoff_el2());
+	write_el2_ctx_common(ctx, cptr_el2, read_cptr_el2());
 	if (CTX_INCLUDE_AARCH32_REGS) {
-		write_ctx_reg(ctx, CTX_DBGVCR32_EL2, read_dbgvcr32_el2());
+		write_el2_ctx_common(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_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());
+	write_el2_ctx_common(ctx, elr_el2, read_elr_el2());
+	write_el2_ctx_common(ctx, esr_el2, read_esr_el2());
+	write_el2_ctx_common(ctx, far_el2, read_far_el2());
+	write_el2_ctx_common(ctx, hacr_el2, read_hacr_el2());
+	write_el2_ctx_common(ctx, hcr_el2, read_hcr_el2());
+	write_el2_ctx_common(ctx, hpfar_el2, read_hpfar_el2());
+	write_el2_ctx_common(ctx, hstr_el2, read_hstr_el2());
+	write_el2_ctx_common(ctx, mair_el2, read_mair_el2());
+	write_el2_ctx_common(ctx, mdcr_el2, read_mdcr_el2());
+	write_el2_ctx_common(ctx, sctlr_el2, read_sctlr_el2());
+	write_el2_ctx_common(ctx, spsr_el2, read_spsr_el2());
+	write_el2_ctx_common(ctx, sp_el2, read_sp_el2());
+	write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2());
+	write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2());
+	write_el2_ctx_common(ctx, ttbr0_el2, read_ttbr0_el2());
+	write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2());
+	write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2());
+	write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
+	write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
+	write_el2_ctx_common(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));
+	write_actlr_el2(read_el2_ctx_common(ctx, actlr_el2));
+	write_afsr0_el2(read_el2_ctx_common(ctx, afsr0_el2));
+	write_afsr1_el2(read_el2_ctx_common(ctx, afsr1_el2));
+	write_amair_el2(read_el2_ctx_common(ctx, amair_el2));
+	write_cnthctl_el2(read_el2_ctx_common(ctx, cnthctl_el2));
+	write_cntvoff_el2(read_el2_ctx_common(ctx, cntvoff_el2));
+	write_cptr_el2(read_el2_ctx_common(ctx, cptr_el2));
 	if (CTX_INCLUDE_AARCH32_REGS) {
-		write_dbgvcr32_el2(read_ctx_reg(ctx, CTX_DBGVCR32_EL2));
+		write_dbgvcr32_el2(read_el2_ctx_common(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_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));
+	write_elr_el2(read_el2_ctx_common(ctx, elr_el2));
+	write_esr_el2(read_el2_ctx_common(ctx, esr_el2));
+	write_far_el2(read_el2_ctx_common(ctx, far_el2));
+	write_hacr_el2(read_el2_ctx_common(ctx, hacr_el2));
+	write_hcr_el2(read_el2_ctx_common(ctx, hcr_el2));
+	write_hpfar_el2(read_el2_ctx_common(ctx, hpfar_el2));
+	write_hstr_el2(read_el2_ctx_common(ctx, hstr_el2));
+	write_mair_el2(read_el2_ctx_common(ctx, mair_el2));
+	write_mdcr_el2(read_el2_ctx_common(ctx, mdcr_el2));
+	write_sctlr_el2(read_el2_ctx_common(ctx, sctlr_el2));
+	write_spsr_el2(read_el2_ctx_common(ctx, spsr_el2));
+	write_sp_el2(read_el2_ctx_common(ctx, sp_el2));
+	write_tcr_el2(read_el2_ctx_common(ctx, tcr_el2));
+	write_tpidr_el2(read_el2_ctx_common(ctx, tpidr_el2));
+	write_ttbr0_el2(read_el2_ctx_common(ctx, ttbr0_el2));
+	write_vbar_el2(read_el2_ctx_common(ctx, vbar_el2));
+	write_vmpidr_el2(read_el2_ctx_common(ctx, vmpidr_el2));
+	write_vpidr_el2(read_el2_ctx_common(ctx, vpidr_el2));
+	write_vtcr_el2(read_el2_ctx_common(ctx, vtcr_el2));
+	write_vttbr_el2(read_el2_ctx_common(ctx, vttbr_el2));
 }
 
 /*******************************************************************************
@@ -1273,66 +1326,69 @@
 	el2_sysregs_context_save_gic(el2_sysregs_ctx);
 
 	if (is_feat_mte2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
+		write_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2, read_tfsr_el2());
 	}
 
-#if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
-		mpam_t *mpam_ctx = get_mpam_ctx(ctx);
-		el2_sysregs_context_save_mpam(mpam_ctx);
+		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
 	}
-#endif
 
 	if (is_feat_fgt_supported()) {
 		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
 	}
 
 	if (is_feat_ecv_v2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2, read_cntpoff_el2());
+		write_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2, read_cntpoff_el2());
 	}
 
 	if (is_feat_vhe_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2, read_contextidr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2, read_ttbr1_el2());
+		write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2,
+					read_contextidr_el2());
+		write_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
 	}
 
 	if (is_feat_ras_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2, read_vdisr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2, read_vsesr_el2());
+		write_el2_ctx_ras(el2_sysregs_ctx, vdisr_el2, read_vdisr_el2());
+		write_el2_ctx_ras(el2_sysregs_ctx, vsesr_el2, read_vsesr_el2());
 	}
 
 	if (is_feat_nv2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2, read_vncr_el2());
+		write_el2_ctx_neve(el2_sysregs_ctx, vncr_el2, read_vncr_el2());
 	}
 
 	if (is_feat_trf_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
+		write_el2_ctx_trf(el2_sysregs_ctx, trfcr_el2, read_trfcr_el2());
 	}
 
-	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2, read_scxtnum_el2());
+		write_el2_ctx_csv2_2(el2_sysregs_ctx, scxtnum_el2,
+					read_scxtnum_el2());
 	}
 
 	if (is_feat_hcx_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
+		write_el2_ctx_hcx(el2_sysregs_ctx, hcrx_el2, read_hcrx_el2());
 	}
+
 	if (is_feat_tcr2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
+		write_el2_ctx_tcr2(el2_sysregs_ctx, tcr2_el2, read_tcr2_el2());
 	}
+
 	if (is_feat_sxpie_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
-	}
-	if (is_feat_s2pie_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
+		write_el2_ctx_sxpie(el2_sysregs_ctx, pire0_el2, read_pire0_el2());
+		write_el2_ctx_sxpie(el2_sysregs_ctx, pir_el2, read_pir_el2());
 	}
+
 	if (is_feat_sxpoe_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+		write_el2_ctx_sxpoe(el2_sysregs_ctx, por_el2, read_por_el2());
+	}
+
+	if (is_feat_s2pie_supported()) {
+		write_el2_ctx_s2pie(el2_sysregs_ctx, s2pir_el2, read_s2pir_el2());
 	}
+
 	if (is_feat_gcs_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
+		write_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2, read_gcscr_el2());
+		write_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2, read_gcspr_el2());
 	}
 }
 
@@ -1353,65 +1409,69 @@
 	el2_sysregs_context_restore_gic(el2_sysregs_ctx);
 
 	if (is_feat_mte2_supported()) {
-		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
+		write_tfsr_el2(read_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2));
 	}
 
-#if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
-		mpam_t *mpam_ctx = get_mpam_ctx(ctx);
-		el2_sysregs_context_restore_mpam(mpam_ctx);
+		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
 	}
-#endif
 
 	if (is_feat_fgt_supported()) {
 		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
 	}
 
 	if (is_feat_ecv_v2_supported()) {
-		write_cntpoff_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2));
+		write_cntpoff_el2(read_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2));
 	}
 
 	if (is_feat_vhe_supported()) {
-		write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
-		write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
+		write_contextidr_el2(read_el2_ctx_vhe(el2_sysregs_ctx,
+					contextidr_el2));
+		write_ttbr1_el2(read_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2));
 	}
 
 	if (is_feat_ras_supported()) {
-		write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
-		write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
+		write_vdisr_el2(read_el2_ctx_ras(el2_sysregs_ctx, vdisr_el2));
+		write_vsesr_el2(read_el2_ctx_ras(el2_sysregs_ctx, vsesr_el2));
 	}
 
 	if (is_feat_nv2_supported()) {
-		write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));
+		write_vncr_el2(read_el2_ctx_neve(el2_sysregs_ctx, vncr_el2));
 	}
+
 	if (is_feat_trf_supported()) {
-		write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
+		write_trfcr_el2(read_el2_ctx_trf(el2_sysregs_ctx, trfcr_el2));
 	}
 
-	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
-		write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2));
+		write_scxtnum_el2(read_el2_ctx_csv2_2(el2_sysregs_ctx,
+					scxtnum_el2));
 	}
 
 	if (is_feat_hcx_supported()) {
-		write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
+		write_hcrx_el2(read_el2_ctx_hcx(el2_sysregs_ctx, hcrx_el2));
 	}
+
 	if (is_feat_tcr2_supported()) {
-		write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
+		write_tcr2_el2(read_el2_ctx_tcr2(el2_sysregs_ctx, tcr2_el2));
 	}
+
 	if (is_feat_sxpie_supported()) {
-		write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
-		write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
-	}
-	if (is_feat_s2pie_supported()) {
-		write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+		write_pire0_el2(read_el2_ctx_sxpie(el2_sysregs_ctx, pire0_el2));
+		write_pir_el2(read_el2_ctx_sxpie(el2_sysregs_ctx, pir_el2));
 	}
+
 	if (is_feat_sxpoe_supported()) {
-		write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+		write_por_el2(read_el2_ctx_sxpoe(el2_sysregs_ctx, por_el2));
 	}
+
+	if (is_feat_s2pie_supported()) {
+		write_s2pir_el2(read_el2_ctx_s2pie(el2_sysregs_ctx, s2pir_el2));
+	}
+
 	if (is_feat_gcs_supported()) {
-		write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
-		write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
+		write_gcscr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2));
+		write_gcspr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2));
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
@@ -1472,6 +1532,8 @@
 	write_ctx_reg(ctx, CTX_AFSR1_EL1, read_afsr1_el1());
 	write_ctx_reg(ctx, CTX_CONTEXTIDR_EL1, read_contextidr_el1());
 	write_ctx_reg(ctx, CTX_VBAR_EL1, read_vbar_el1());
+	write_ctx_reg(ctx, CTX_MDCCINT_EL1, read_mdccint_el1());
+	write_ctx_reg(ctx, CTX_MDSCR_EL1, read_mdscr_el1());
 
 #if CTX_INCLUDE_AARCH32_REGS
 	write_ctx_reg(ctx, CTX_SPSR_ABT, read_spsr_abt());
@@ -1490,13 +1552,65 @@
 	write_ctx_reg(ctx, CTX_CNTKCTL_EL1, read_cntkctl_el1());
 #endif /* NS_TIMER_SWITCH */
 
-#if ENABLE_FEAT_MTE
+#if ENABLE_FEAT_MTE2
 	write_ctx_reg(ctx, CTX_TFSRE0_EL1, read_tfsre0_el1());
 	write_ctx_reg(ctx, CTX_TFSR_EL1, read_tfsr_el1());
 	write_ctx_reg(ctx, CTX_RGSR_EL1, read_rgsr_el1());
 	write_ctx_reg(ctx, CTX_GCR_EL1, read_gcr_el1());
-#endif /* ENABLE_FEAT_MTE */
+#endif /* ENABLE_FEAT_MTE2 */
+
+#if ENABLE_FEAT_RAS
+	if (is_feat_ras_supported()) {
+		write_ctx_reg(ctx, CTX_DISR_EL1, read_disr_el1());
+	}
+#endif
+
+#if ENABLE_FEAT_S1PIE
+	if (is_feat_s1pie_supported()) {
+		write_ctx_reg(ctx, CTX_PIRE0_EL1, read_pire0_el1());
+		write_ctx_reg(ctx, CTX_PIR_EL1, read_pir_el1());
+	}
+#endif
+
+#if ENABLE_FEAT_S1POE
+	if (is_feat_s1poe_supported()) {
+		write_ctx_reg(ctx, CTX_POR_EL1, read_por_el1());
+	}
+#endif
+
+#if ENABLE_FEAT_S2POE
+	if (is_feat_s2poe_supported()) {
+		write_ctx_reg(ctx, CTX_S2POR_EL1, read_s2por_el1());
+	}
+#endif
+
+#if ENABLE_FEAT_TCR2
+	if (is_feat_tcr2_supported()) {
+		write_ctx_reg(ctx, CTX_TCR2_EL1, read_tcr2_el1());
+	}
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	if (is_feat_trf_supported()) {
+		write_ctx_reg(ctx, CTX_TRFCR_EL1, read_trfcr_el1());
+	}
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	if (is_feat_csv2_2_supported()) {
+		write_ctx_reg(ctx, CTX_SCXTNUM_EL0, read_scxtnum_el0());
+		write_ctx_reg(ctx, CTX_SCXTNUM_EL1, read_scxtnum_el1());
+	}
+#endif
 
+#if ENABLE_FEAT_GCS
+	if (is_feat_gcs_supported()) {
+		write_ctx_reg(ctx, CTX_GCSCR_EL1, read_gcscr_el1());
+		write_ctx_reg(ctx, CTX_GCSCRE0_EL1, read_gcscre0_el1());
+		write_ctx_reg(ctx, CTX_GCSPR_EL1, read_gcspr_el1());
+		write_ctx_reg(ctx, CTX_GCSPR_EL0, read_gcspr_el0());
+	}
+#endif
 }
 
 static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
@@ -1527,6 +1641,8 @@
 	write_afsr1_el1(read_ctx_reg(ctx, CTX_AFSR1_EL1));
 	write_contextidr_el1(read_ctx_reg(ctx, CTX_CONTEXTIDR_EL1));
 	write_vbar_el1(read_ctx_reg(ctx, CTX_VBAR_EL1));
+	write_mdccint_el1(read_ctx_reg(ctx, CTX_MDCCINT_EL1));
+	write_mdscr_el1(read_ctx_reg(ctx, CTX_MDSCR_EL1));
 
 #if CTX_INCLUDE_AARCH32_REGS
 	write_spsr_abt(read_ctx_reg(ctx, CTX_SPSR_ABT));
@@ -1545,13 +1661,65 @@
 	write_cntkctl_el1(read_ctx_reg(ctx, CTX_CNTKCTL_EL1));
 #endif /* NS_TIMER_SWITCH */
 
-#if ENABLE_FEAT_MTE
+#if ENABLE_FEAT_MTE2
 	write_tfsre0_el1(read_ctx_reg(ctx, CTX_TFSRE0_EL1));
 	write_tfsr_el1(read_ctx_reg(ctx, CTX_TFSR_EL1));
 	write_rgsr_el1(read_ctx_reg(ctx, CTX_RGSR_EL1));
 	write_gcr_el1(read_ctx_reg(ctx, CTX_GCR_EL1));
-#endif /* ENABLE_FEAT_MTE */
+#endif /* ENABLE_FEAT_MTE2 */
+
+#if ENABLE_FEAT_RAS
+	if (is_feat_ras_supported()) {
+		write_disr_el1(read_ctx_reg(ctx, CTX_DISR_EL1));
+	}
+#endif
+
+#if ENABLE_FEAT_S1PIE
+	if (is_feat_s1pie_supported()) {
+		write_pire0_el1(read_ctx_reg(ctx, CTX_PIRE0_EL1));
+		write_pir_el1(read_ctx_reg(ctx, CTX_PIR_EL1));
+	}
+#endif
+
+#if ENABLE_FEAT_S1POE
+	if (is_feat_s1poe_supported()) {
+		write_por_el1(read_ctx_reg(ctx, CTX_POR_EL1));
+	}
+#endif
 
+#if ENABLE_FEAT_S2POE
+	if (is_feat_s2poe_supported()) {
+		write_s2por_el1(read_ctx_reg(ctx, CTX_S2POR_EL1));
+	}
+#endif
+
+#if ENABLE_FEAT_TCR2
+	if (is_feat_tcr2_supported()) {
+		write_tcr2_el1(read_ctx_reg(ctx, CTX_TCR2_EL1));
+	}
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	if (is_feat_trf_supported()) {
+		write_trfcr_el1(read_ctx_reg(ctx, CTX_TRFCR_EL1));
+	}
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	if (is_feat_csv2_2_supported()) {
+		write_scxtnum_el0(read_ctx_reg(ctx, CTX_SCXTNUM_EL0));
+		write_scxtnum_el1(read_ctx_reg(ctx, CTX_SCXTNUM_EL1));
+	}
+#endif
+
+#if ENABLE_FEAT_GCS
+	if (is_feat_gcs_supported()) {
+		write_gcscr_el1(read_ctx_reg(ctx, CTX_GCSCR_EL1));
+		write_gcscre0_el1(read_ctx_reg(ctx, CTX_GCSCRE0_EL1));
+		write_gcspr_el1(read_ctx_reg(ctx, CTX_GCSPR_EL1));
+		write_gcspr_el0(read_ctx_reg(ctx, CTX_GCSPR_EL0));
+	}
+#endif
 }
 
 /*******************************************************************************
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index 37bd834..dde0266 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,10 @@
 #include <arch_helpers.h>
 #include <lib/extensions/brbe.h>
 
-void brbe_init_el3(void)
+void brbe_enable(cpu_context_t *ctx)
 {
-	uint64_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.SBRBE = 0b01
@@ -19,8 +20,7 @@
 	 * Allows BRBE usage in non-secure world and prohibited in
 	 * secure world.
 	 */
-	val = read_mdcr_el3();
-	val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
-	val |= (0x1UL << MDCR_SBRBE_SHIFT);
-	write_mdcr_el3(val);
+	mdcr_el3_val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+	mdcr_el3_val |= (0x1UL << MDCR_SBRBE_SHIFT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
diff --git a/lib/extensions/pmuv3/aarch32/pmuv3.c b/lib/extensions/pmuv3/aarch32/pmuv3.c
index effb7e0..456a48e 100644
--- a/lib/extensions/pmuv3/aarch32/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch32/pmuv3.c
@@ -25,10 +25,6 @@
 	return sdcr;
 }
 
-/*
- * 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_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 61fc47d..71aa303 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,11 +24,11 @@
 void pmuv3_enable(cpu_context_t *ctx)
 {
 #if CTX_INCLUDE_EL2_REGS
-	u_register_t mdcr_el2;
+	u_register_t mdcr_el2_val;
 
-	mdcr_el2 = read_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2);
-	mdcr_el2 = init_mdcr_el2_hpmn(mdcr_el2);
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
+	mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
+	mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
 #endif /* CTX_INCLUDE_EL2_REGS */
 }
 
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index b1409b9..98d57e9 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -53,7 +53,7 @@
 	 * using SMCR_EL2 and SMCR_EL1.
 	 */
 	smcr_el3 = SMCR_ELX_LEN_MAX;
-	if (read_feat_sme_fa64_id_field() != 0U) {
+	if (is_feat_sme_fa64_present()) {
 		VERBOSE("[SME] FA64 enabled\n");
 		smcr_el3 |= SMCR_ELX_FA64_BIT;
 	}
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index d1fb182..c6076fe 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -29,9 +29,10 @@
 	__asm__ volatile("hint #17");
 }
 
-void spe_init_el3(void)
+void spe_enable(cpu_context_t *ctx)
 {
-	uint64_t v;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in Non-secure state
@@ -46,10 +47,9 @@
 	 * Setting this bit to 1 doesn't have any effect on it when
 	 * FEAT_SPEv1p2 not implemented.
 	 */
-	v = read_mdcr_el3();
-	v |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
-	v &= ~(MDCR_NSPBE_BIT);
-	write_mdcr_el3(v);
+	mdcr_el3_val |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
+	mdcr_el3_val &= ~(MDCR_NSPBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void spe_init_el2_unused(void)
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index d4fbdfb..9157734 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +19,10 @@
 	__asm__ volatile("hint #18");
 }
 
-void trbe_init_el3(void)
+void trbe_enable(cpu_context_t *ctx)
 {
-	u_register_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.NSTBE = 0b0
@@ -33,10 +34,9 @@
 	 *  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);
+	mdcr_el3_val |= MDCR_NSTB(MDCR_NSTB_EL1);
+	mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void trbe_init_el2_unused(void)
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
index 83fbf85..d36853a 100644
--- a/lib/extensions/trf/aarch64/trf.c
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,10 @@
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-void trf_init_el3(void)
+void trf_enable(cpu_context_t *ctx)
 {
-	u_register_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.STE = b0
@@ -22,9 +23,8 @@
 	 * 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_STE_BIT | MDCR_TTRF_BIT);
-	write_mdcr_el3(val);
+	mdcr_el3_val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void trf_init_el2_unused(void)
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index 36f7a51..d028fce 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #if !ENABLE_RME
-#error "ENABLE_RME must be enabled to use the GPT library."
+#error "ENABLE_RME must be enabled to use the GPT library"
 #endif
 
 /*
@@ -57,8 +57,15 @@
  */
 static const gpt_p_val_e gpt_p_lookup[] = {PGS_4KB_P, PGS_64KB_P, PGS_16KB_P};
 
+static void shatter_2mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+static void shatter_32mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+static void shatter_512mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+
 /*
- * This structure contains GPT configuration data.
+ * This structure contains GPT configuration data
  */
 typedef struct {
 	uintptr_t plat_gpt_l0_base;
@@ -70,11 +77,188 @@
 
 static gpt_config_t gpt_config;
 
+/*
+ * Number of L1 entries in 2MB, depending on GPCCR_EL3.PGS:
+ * +-------+------------+
+ * |  PGS  | L1 entries |
+ * +-------+------------+
+ * |  4KB  |     32     |
+ * +-------+------------+
+ * |  16KB |     8      |
+ * +-------+------------+
+ * |  64KB |     2      |
+ * +-------+------------+
+ */
+static unsigned int gpt_l1_cnt_2mb;
+
-/* These variables are used during initialization of the L1 tables. */
-static unsigned int gpt_next_l1_tbl_idx;
+/*
+ * Mask for the L1 index field, depending on
+ * GPCCR_EL3.L0GPTSZ and GPCCR_EL3.PGS:
+ * +---------+-------------------------------+
+ * |         |             PGS               |
+ * +---------+----------+----------+---------+
+ * | L0GPTSZ |   4KB    |   16KB   |   64KB  |
+ * +---------+----------+----------+---------+
+ * |  1GB    |  0x3FFF  |  0xFFF   |  0x3FF  |
+ * +---------+----------+----------+---------+
+ * |  16GB   | 0x3FFFF  |  0xFFFF  | 0x3FFF  |
+ * +---------+----------+----------+---------+
+ * |  64GB   | 0xFFFFF  | 0x3FFFF  | 0xFFFF  |
+ * +---------+----------+----------+---------+
+ * |  512GB  | 0x7FFFFF | 0x1FFFFF | 0x7FFFF |
+ * +---------+----------+----------+---------+
+ */
+static uint64_t gpt_l1_index_mask;
+
+/* Number of 128-bit L1 entries in 2MB, 32MB and 512MB */
+#define L1_QWORDS_2MB	(gpt_l1_cnt_2mb / 2U)
+#define L1_QWORDS_32MB	(L1_QWORDS_2MB * 16U)
+#define L1_QWORDS_512MB	(L1_QWORDS_32MB * 16U)
+
+/* Size in bytes of L1 entries in 2MB, 32MB */
+#define L1_BYTES_2MB	(gpt_l1_cnt_2mb * sizeof(uint64_t))
+#define L1_BYTES_32MB	(L1_BYTES_2MB * 16U)
+
+/* Get the index into the L1 table from a physical address */
+#define GPT_L1_INDEX(_pa)	\
+	(((_pa) >> (unsigned int)GPT_L1_IDX_SHIFT(gpt_config.p)) & gpt_l1_index_mask)
+
+/* These variables are used during initialization of the L1 tables */
 static uintptr_t gpt_l1_tbl;
 
+/* These variable is used during runtime */
+#if (RME_GPT_BITLOCK_BLOCK == 0)
+/*
+ * The GPTs are protected by a global spinlock to ensure
+ * that multiple CPUs do not attempt to change the descriptors at once.
+ */
+static spinlock_t gpt_lock;
+#else
+
+/* Bitlocks base address */
+static bitlock_t *gpt_bitlock_base;
+#endif
+
+/* Lock/unlock macros for GPT entries */
+#if (RME_GPT_BITLOCK_BLOCK == 0)
+/*
+ * Access to GPT is controlled by a global lock to ensure
+ * that no more than one CPU is allowed to make changes at any
+ * given time.
+ */
+#define GPT_LOCK	spin_lock(&gpt_lock)
+#define GPT_UNLOCK	spin_unlock(&gpt_lock)
+#else
+/*
+ * Access to a block of memory is controlled by a bitlock.
+ * Size of block = RME_GPT_BITLOCK_BLOCK * 512MB.
+ */
+#define GPT_LOCK	bit_lock(gpi_info.lock, gpi_info.mask)
+#define GPT_UNLOCK	bit_unlock(gpi_info.lock, gpi_info.mask)
+#endif
+
+static void tlbi_page_dsbosh(uintptr_t base)
+{
+	/* Look-up table for invalidation TLBs for 4KB, 16KB and 64KB pages */
+	static const gpt_tlbi_lookup_t tlbi_page_lookup[] = {
+		{ tlbirpalos_4k, ~(SZ_4K - 1UL) },
+		{ tlbirpalos_64k, ~(SZ_64K - 1UL) },
+		{ tlbirpalos_16k, ~(SZ_16K - 1UL) }
+	};
+
+	tlbi_page_lookup[gpt_config.pgs].function(
+			base & tlbi_page_lookup[gpt_config.pgs].mask);
+	dsbosh();
+}
+
 /*
+ * Helper function to fill out GPI entries in a single L1 table
+ * with Granules or Contiguous descriptor.
+ *
+ * Parameters
+ *   l1			Pointer to 2MB, 32MB or 512MB aligned L1 table entry to fill out
+ *   l1_desc		GPT Granules or Contiguous descriptor set this range to
+ *   cnt		Number of double 128-bit L1 entries to fill
+ *
+ */
+static void fill_desc(uint64_t *l1, uint64_t l1_desc, unsigned int cnt)
+{
+	uint128_t *l1_quad = (uint128_t *)l1;
+	uint128_t l1_quad_desc = (uint128_t)l1_desc | ((uint128_t)l1_desc << 64);
+
+	VERBOSE("GPT: %s(%p 0x%"PRIx64" %u)\n", __func__, l1, l1_desc, cnt);
+
+	for (unsigned int i = 0U; i < cnt; i++) {
+		*l1_quad++ = l1_quad_desc;
+	}
+}
+
+static void shatter_2mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_2MB(base));
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Convert 2MB Contiguous block to Granules */
+	fill_desc(&gpi_info->gpt_l1_addr[idx], l1_desc, L1_QWORDS_2MB);
+}
+
+static void shatter_32mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_2MB(base));
+	const uint64_t *l1_gran = &gpi_info->gpt_l1_addr[idx];
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+	uint64_t *l1;
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Get index corresponding to 32MB aligned address */
+	idx = GPT_L1_INDEX(ALIGN_32MB(base));
+	l1 = &gpi_info->gpt_l1_addr[idx];
+
+	/* 16 x 2MB blocks in 32MB */
+	for (unsigned int i = 0U; i < 16U; i++) {
+		/* Fill with Granules or Contiguous descriptors */
+		fill_desc(l1, (l1 == l1_gran) ? l1_desc : l1_cont_desc,
+							L1_QWORDS_2MB);
+		l1 = (uint64_t *)((uintptr_t)l1 + L1_BYTES_2MB);
+	}
+}
+
+static void shatter_512mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_32MB(base));
+	const uint64_t *l1_32mb = &gpi_info->gpt_l1_addr[idx];
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+	uint64_t *l1;
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Get index corresponding to 512MB aligned address */
+	idx = GPT_L1_INDEX(ALIGN_512MB(base));
+	l1 = &gpi_info->gpt_l1_addr[idx];
+
+	/* 16 x 32MB blocks in 512MB */
+	for (unsigned int i = 0U; i < 16U; i++) {
+		if (l1 == l1_32mb) {
+			/* Shatter this 32MB block */
+			shatter_32mb(base, gpi_info, l1_desc);
+		} else {
+			/* Fill 32MB with Contiguous descriptors */
+			fill_desc(l1, l1_cont_desc, L1_QWORDS_32MB);
+		}
+
+		l1 = (uint64_t *)((uintptr_t)l1 + L1_BYTES_32MB);
+	}
+}
+
+/*
  * This function checks to see if a GPI value is valid.
  *
  * These are valid GPI values.
@@ -91,7 +275,7 @@
  * Return
  *   true for a valid GPI, false for an invalid one.
  */
-static bool gpt_is_gpi_valid(unsigned int gpi)
+static bool is_gpi_valid(unsigned int gpi)
 {
 	if ((gpi == GPT_GPI_NO_ACCESS) || (gpi == GPT_GPI_ANY) ||
 	    ((gpi >= GPT_GPI_SECURE) && (gpi <= GPT_GPI_REALM))) {
@@ -112,8 +296,8 @@
  * Return
  *   True if PAS regions overlap, false if they do not.
  */
-static bool gpt_check_pas_overlap(uintptr_t base_1, size_t size_1,
-				  uintptr_t base_2, size_t size_2)
+static bool check_pas_overlap(uintptr_t base_1, size_t size_1,
+			      uintptr_t base_2, size_t size_2)
 {
 	if (((base_1 + size_1) > base_2) && ((base_2 + size_2) > base_1)) {
 		return true;
@@ -133,13 +317,13 @@
  * Return
  *   True if a PAS region occupies the L0 region in question, false if not.
  */
-static bool gpt_does_previous_pas_exist_here(unsigned int l0_idx,
-					     pas_region_t *pas_regions,
-					     unsigned int pas_idx)
+static bool does_previous_pas_exist_here(unsigned int l0_idx,
+					 pas_region_t *pas_regions,
+					 unsigned int pas_idx)
 {
-	/* Iterate over PAS regions up to pas_idx. */
+	/* Iterate over PAS regions up to pas_idx */
 	for (unsigned int i = 0U; i < pas_idx; i++) {
-		if (gpt_check_pas_overlap((GPT_L0GPTSZ_ACTUAL_SIZE * l0_idx),
+		if (check_pas_overlap((GPT_L0GPTSZ_ACTUAL_SIZE * l0_idx),
 		    GPT_L0GPTSZ_ACTUAL_SIZE,
 		    pas_regions[i].base_pa, pas_regions[i].size)) {
 			return true;
@@ -164,8 +348,8 @@
  *   Negative Linux error code in the event of a failure, number of L1 regions
  *   required when successful.
  */
-static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
-				     unsigned int pas_region_cnt)
+static int validate_pas_mappings(pas_region_t *pas_regions,
+				 unsigned int pas_region_cnt)
 {
 	unsigned int idx;
 	unsigned int l1_cnt = 0U;
@@ -176,18 +360,18 @@
 	assert(pas_region_cnt != 0U);
 
 	for (idx = 0U; idx < pas_region_cnt; idx++) {
-		/* Check for arithmetic overflow in region. */
+		/* Check for arithmetic overflow in region */
 		if ((ULONG_MAX - pas_regions[idx].base_pa) <
 		    pas_regions[idx].size) {
-			ERROR("[GPT] Address overflow in PAS[%u]!\n", idx);
+			ERROR("GPT: Address overflow in PAS[%u]!\n", idx);
 			return -EOVERFLOW;
 		}
 
-		/* Initial checks for PAS validity. */
+		/* Initial checks for PAS validity */
 		if (((pas_regions[idx].base_pa + pas_regions[idx].size) >
 		    GPT_PPS_ACTUAL_SIZE(gpt_config.t)) ||
-		    !gpt_is_gpi_valid(GPT_PAS_ATTR_GPI(pas_regions[idx].attrs))) {
-			ERROR("[GPT] PAS[%u] is invalid!\n", idx);
+		    !is_gpi_valid(GPT_PAS_ATTR_GPI(pas_regions[idx].attrs))) {
+			ERROR("GPT: PAS[%u] is invalid!\n", idx);
 			return -EFAULT;
 		}
 
@@ -196,12 +380,12 @@
 		 * start from idx + 1 instead of 0 since prior PAS mappings will
 		 * have already checked themselves against this one.
 		 */
-		for (unsigned int i = idx + 1; i < pas_region_cnt; i++) {
-			if (gpt_check_pas_overlap(pas_regions[idx].base_pa,
+		for (unsigned int i = idx + 1U; i < pas_region_cnt; i++) {
+			if (check_pas_overlap(pas_regions[idx].base_pa,
 			    pas_regions[idx].size,
 			    pas_regions[i].base_pa,
 			    pas_regions[i].size)) {
-				ERROR("[GPT] PAS[%u] overlaps with PAS[%u]\n",
+				ERROR("GPT: PAS[%u] overlaps with PAS[%u]\n",
 					i, idx);
 				return -EFAULT;
 			}
@@ -213,12 +397,14 @@
 		 * to see if this PAS would fall into one that has already been
 		 * initialized.
 		 */
-		for (unsigned int i = GPT_L0_IDX(pas_regions[idx].base_pa);
-		     i <= GPT_L0_IDX(pas_regions[idx].base_pa + pas_regions[idx].size - 1);
-		     i++) {
+		for (unsigned int i =
+			(unsigned int)GPT_L0_IDX(pas_regions[idx].base_pa);
+			i <= GPT_L0_IDX(pas_regions[idx].base_pa +
+					pas_regions[idx].size - 1UL);
+			i++) {
 			if ((GPT_L0_TYPE(l0_desc[i]) == GPT_L0_TYPE_BLK_DESC) &&
 			    (GPT_L0_BLKD_GPI(l0_desc[i]) == GPT_GPI_ANY)) {
-				/* This descriptor is unused so continue. */
+				/* This descriptor is unused so continue */
 				continue;
 			}
 
@@ -226,18 +412,18 @@
 			 * This descriptor has been initialized in a previous
 			 * call to this function so cannot be initialized again.
 			 */
-			ERROR("[GPT] PAS[%u] overlaps with previous L0[%d]!\n",
+			ERROR("GPT: PAS[%u] overlaps with previous L0[%u]!\n",
 			      idx, i);
 			return -EFAULT;
 		}
 
-		/* Check for block mapping (L0) type. */
+		/* Check for block mapping (L0) type */
 		if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) ==
 		    GPT_PAS_ATTR_MAP_TYPE_BLOCK) {
-			/* Make sure base and size are block-aligned. */
+			/* Make sure base and size are block-aligned */
 			if (!GPT_IS_L0_ALIGNED(pas_regions[idx].base_pa) ||
 			    !GPT_IS_L0_ALIGNED(pas_regions[idx].size)) {
-				ERROR("[GPT] PAS[%u] is not block-aligned!\n",
+				ERROR("GPT: PAS[%u] is not block-aligned!\n",
 				      idx);
 				return -EFAULT;
 			}
@@ -245,21 +431,21 @@
 			continue;
 		}
 
-		/* Check for granule mapping (L1) type. */
+		/* Check for granule mapping (L1) type */
 		if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) ==
 		    GPT_PAS_ATTR_MAP_TYPE_GRANULE) {
-			/* Make sure base and size are granule-aligned. */
+			/* Make sure base and size are granule-aligned */
 			if (!GPT_IS_L1_ALIGNED(gpt_config.p, pas_regions[idx].base_pa) ||
 			    !GPT_IS_L1_ALIGNED(gpt_config.p, pas_regions[idx].size)) {
-				ERROR("[GPT] PAS[%u] is not granule-aligned!\n",
+				ERROR("GPT: PAS[%u] is not granule-aligned!\n",
 				      idx);
 				return -EFAULT;
 			}
 
-			/* Find how many L1 tables this PAS occupies. */
+			/* Find how many L1 tables this PAS occupies */
 			pas_l1_cnt = (GPT_L0_IDX(pas_regions[idx].base_pa +
-				     pas_regions[idx].size - 1) -
-				     GPT_L0_IDX(pas_regions[idx].base_pa) + 1);
+				     pas_regions[idx].size - 1UL) -
+				     GPT_L0_IDX(pas_regions[idx].base_pa) + 1U);
 
 			/*
 			 * This creates a situation where, if multiple PAS
@@ -277,26 +463,26 @@
 			 * both for overlap against other PAS.
 			 */
 			if (pas_l1_cnt > 1) {
-				if (gpt_does_previous_pas_exist_here(
+				if (does_previous_pas_exist_here(
 				    GPT_L0_IDX(pas_regions[idx].base_pa +
-				    pas_regions[idx].size - 1),
+				    pas_regions[idx].size - 1UL),
 				    pas_regions, idx)) {
-					pas_l1_cnt = pas_l1_cnt - 1;
+					pas_l1_cnt--;
 				}
 			}
 
-			if (gpt_does_previous_pas_exist_here(
+			if (does_previous_pas_exist_here(
 			    GPT_L0_IDX(pas_regions[idx].base_pa),
 			    pas_regions, idx)) {
-				pas_l1_cnt = pas_l1_cnt - 1;
+				pas_l1_cnt--;
 			}
 
 			l1_cnt += pas_l1_cnt;
 			continue;
 		}
 
-		/* If execution reaches this point, mapping type is invalid. */
-		ERROR("[GPT] PAS[%u] has invalid mapping type 0x%x.\n", idx,
+		/* If execution reaches this point, mapping type is invalid */
+		ERROR("GPT: PAS[%u] has invalid mapping type 0x%x.\n", idx,
 		      GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs));
 		return -EINVAL;
 	}
@@ -314,39 +500,57 @@
  * Return
  *   Negative Linux error code in the event of a failure, 0 for success.
  */
-static int gpt_validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
-				  size_t l0_mem_size)
+static int validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
+				size_t l0_mem_size)
 {
-	size_t l0_alignment;
+	size_t l0_alignment, locks_size = 0;
 
 	/*
 	 * Make sure PPS is valid and then store it since macros need this value
 	 * to work.
 	 */
 	if (pps > GPT_PPS_MAX) {
-		ERROR("[GPT] Invalid PPS: 0x%x\n", pps);
+		ERROR("GPT: Invalid PPS: 0x%x\n", pps);
 		return -EINVAL;
 	}
 	gpt_config.pps = pps;
 	gpt_config.t = gpt_t_lookup[pps];
 
-	/* Alignment must be the greater of 4k or l0 table size. */
+	/* Alignment must be the greater of 4KB or l0 table size */
 	l0_alignment = PAGE_SIZE_4KB;
 	if (l0_alignment < GPT_L0_TABLE_SIZE(gpt_config.t)) {
 		l0_alignment = GPT_L0_TABLE_SIZE(gpt_config.t);
 	}
 
-	/* Check base address. */
-	if ((l0_mem_base == 0U) || ((l0_mem_base & (l0_alignment - 1)) != 0U)) {
-		ERROR("[GPT] Invalid L0 base address: 0x%lx\n", l0_mem_base);
+	/* Check base address */
+	if ((l0_mem_base == 0UL) ||
+	   ((l0_mem_base & (l0_alignment - 1UL)) != 0UL)) {
+		ERROR("GPT: Invalid L0 base address: 0x%lx\n", l0_mem_base);
 		return -EFAULT;
 	}
 
-	/* Check size. */
-	if (l0_mem_size < GPT_L0_TABLE_SIZE(gpt_config.t)) {
-		ERROR("[GPT] Inadequate L0 memory: need 0x%lx, have 0x%lx)\n",
-		      GPT_L0_TABLE_SIZE(gpt_config.t),
-		      l0_mem_size);
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/*
+	 * Size of bitlocks in bytes for the protected address space
+	 * with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
+	 */
+	locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
+			(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
+
+	/*
+	 * If protected space size is less than the size covered
+	 * by 'bitlock' structure, check for a single bitlock.
+	 */
+	if (locks_size < LOCK_SIZE) {
+		locks_size = LOCK_SIZE;
+	}
+#endif
+	/* Check size for L0 tables and bitlocks */
+	if (l0_mem_size < (GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size)) {
+		ERROR("GPT: Inadequate L0 memory\n");
+		ERROR("      Expected 0x%lx bytes, got 0x%lx bytes\n",
+			GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size,
+			l0_mem_size);
 		return -ENOMEM;
 	}
 
@@ -365,8 +569,8 @@
  * Return
  *   Negative Linux error code in the event of a failure, 0 for success.
  */
-static int gpt_validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
-				  unsigned int l1_gpt_cnt)
+static int validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
+				unsigned int l1_gpt_cnt)
 {
 	size_t l1_gpt_mem_sz;
 
@@ -376,31 +580,32 @@
 		return -EPERM;
 	}
 
-	/* Make sure L1 tables are aligned to their size. */
-	if ((l1_mem_base & (GPT_L1_TABLE_SIZE(gpt_config.p) - 1)) != 0U) {
-		ERROR("[GPT] Unaligned L1 GPT base address: 0x%lx\n",
+	/* Make sure L1 tables are aligned to their size */
+	if ((l1_mem_base & (GPT_L1_TABLE_SIZE(gpt_config.p) - 1UL)) != 0UL) {
+		ERROR("GPT: Unaligned L1 GPT base address: 0x%"PRIxPTR"\n",
 		      l1_mem_base);
 		return -EFAULT;
 	}
 
-	/* Get total memory needed for L1 tables. */
+	/* Get total memory needed for L1 tables */
 	l1_gpt_mem_sz = l1_gpt_cnt * GPT_L1_TABLE_SIZE(gpt_config.p);
 
-	/* Check for overflow. */
+	/* Check for overflow */
 	if ((l1_gpt_mem_sz / GPT_L1_TABLE_SIZE(gpt_config.p)) != l1_gpt_cnt) {
-		ERROR("[GPT] Overflow calculating L1 memory size.\n");
+		ERROR("GPT: Overflow calculating L1 memory size\n");
 		return -ENOMEM;
 	}
 
-	/* Make sure enough space was supplied. */
+	/* Make sure enough space was supplied */
 	if (l1_mem_size < l1_gpt_mem_sz) {
-		ERROR("[GPT] Inadequate memory for L1 GPTs. ");
-		ERROR("      Expected 0x%lx bytes. Got 0x%lx bytes\n",
-		      l1_gpt_mem_sz, l1_mem_size);
+		ERROR("%sL1 GPTs%s", (const char *)"GPT: Inadequate ",
+			(const char *)" memory\n");
+		ERROR("      Expected 0x%lx bytes, got 0x%lx bytes\n",
+			l1_gpt_mem_sz, l1_mem_size);
 		return -ENOMEM;
 	}
 
-	VERBOSE("[GPT] Requested 0x%lx bytes for L1 GPTs.\n", l1_gpt_mem_sz);
+	VERBOSE("GPT: Requested 0x%lx bytes for L1 GPTs\n", l1_gpt_mem_sz);
 	return 0;
 }
 
@@ -412,11 +617,10 @@
  *   *pas		Pointer to the structure defining the PAS region to
  *			initialize.
  */
-static void gpt_generate_l0_blk_desc(pas_region_t *pas)
+static void generate_l0_blk_desc(pas_region_t *pas)
 {
 	uint64_t gpt_desc;
-	unsigned int end_idx;
-	unsigned int idx;
+	unsigned long idx, end_idx;
 	uint64_t *l0_gpt_arr;
 
 	assert(gpt_config.plat_gpt_l0_base != 0U);
@@ -424,7 +628,7 @@
 
 	/*
 	 * Checking of PAS parameters has already been done in
-	 * gpt_validate_pas_mappings so no need to check the same things again.
+	 * validate_pas_mappings so no need to check the same things again.
 	 */
 
 	l0_gpt_arr = (uint64_t *)gpt_config.plat_gpt_l0_base;
@@ -442,10 +646,10 @@
 	 */
 	end_idx = GPT_L0_IDX(pas->base_pa + pas->size);
 
-	/* Generate the needed block descriptors. */
+	/* Generate the needed block descriptors */
 	for (; idx < end_idx; idx++) {
 		l0_gpt_arr[idx] = gpt_desc;
-		VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
+		VERBOSE("GPT: L0 entry (BLOCK) index %lu [%p]: GPI = 0x%"PRIx64" (0x%"PRIx64")\n",
 			idx, &l0_gpt_arr[idx],
 			(gpt_desc >> GPT_L0_BLK_DESC_GPI_SHIFT) &
 			GPT_L0_BLK_DESC_GPI_MASK, l0_gpt_arr[idx]);
@@ -465,7 +669,7 @@
  * Return
  *   The PA of the end of the current range.
  */
-static uintptr_t gpt_get_l1_end_pa(uintptr_t cur_pa, uintptr_t end_pa)
+static uintptr_t get_l1_end_pa(uintptr_t cur_pa, uintptr_t end_pa)
 {
 	uintptr_t cur_idx;
 	uintptr_t end_idx;
@@ -479,54 +683,208 @@
 		return end_pa;
 	}
 
-	return (cur_idx + 1U) << GPT_L0_IDX_SHIFT;
+	return (cur_idx + 1UL) << GPT_L0_IDX_SHIFT;
 }
 
 /*
- * Helper function to fill out GPI entries in a single L1 table. This function
- * fills out entire L1 descriptors at a time to save memory writes.
+ * Helper function to fill out GPI entries from 'first' granule address of
+ * the specified 'length' in a single L1 table with 'l1_desc' Contiguous
+ * descriptor.
  *
  * Parameters
- *   gpi		GPI to set this range to
  *   l1			Pointer to L1 table to fill out
- *   first		Address of first granule in range.
- *   last		Address of last granule in range (inclusive).
+ *   first		Address of first granule in range
+ *   length		Length of the range in bytes
+ *   gpi		GPI set this range to
+ *
+ * Return
+ *   Address of next granule in range.
  */
-static void gpt_fill_l1_tbl(uint64_t gpi, uint64_t *l1, uintptr_t first,
-			    uintptr_t last)
+__unused static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
+					    size_t length, unsigned int gpi)
 {
-	uint64_t gpi_field = GPT_BUILD_L1_DESC(gpi);
-	uint64_t gpi_mask = 0xFFFFFFFFFFFFFFFF;
+	/*
+	 * Look up table for contiguous blocks and descriptors.
+	 * Entries should be defined in descending block sizes:
+	 * 512MB, 32MB and 2MB.
+	 */
+	static const gpt_fill_lookup_t gpt_fill_lookup[] = {
+#if (RME_GPT_MAX_BLOCK == 512)
+		{ SZ_512M, GPT_L1_CONT_DESC_512MB },
+#endif
+#if (RME_GPT_MAX_BLOCK >= 32)
+		{ SZ_32M, GPT_L1_CONT_DESC_32MB },
+#endif
+#if (RME_GPT_MAX_BLOCK != 0)
+		{ SZ_2M, GPT_L1_CONT_DESC_2MB }
+#endif
+	};
 
-	assert(first <= last);
-	assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U);
-	assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U);
-	assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
-	assert(l1 != NULL);
+	/*
+	 * Iterate through all block sizes (512MB, 32MB and 2MB)
+	 * starting with maximum supported.
+	 */
+	for (unsigned long i = 0UL; i < ARRAY_SIZE(gpt_fill_lookup); i++) {
+		/* Calculate index */
+		unsigned long idx = GPT_L1_INDEX(first);
+
+		/* Contiguous block size */
+		size_t cont_size = gpt_fill_lookup[i].size;
+
+		if (GPT_REGION_IS_CONT(length, first, cont_size)) {
+
+			/* Generate Contiguous descriptor */
+			uint64_t l1_desc = GPT_L1_GPI_CONT_DESC(gpi,
+						gpt_fill_lookup[i].desc);
+
+			/* Number of 128-bit L1 entries in block */
+			unsigned int cnt;
+
+			switch (cont_size) {
+			case SZ_512M:
+				cnt = L1_QWORDS_512MB;
+				break;
+			case SZ_32M:
+				cnt = L1_QWORDS_32MB;
+				break;
+			default:			/* SZ_2MB */
+				cnt = L1_QWORDS_2MB;
+			}
+
+			VERBOSE("GPT: Contiguous descriptor 0x%"PRIxPTR" %luMB\n",
+				first, cont_size / SZ_1M);
 
-	/* Shift the mask if we're starting in the middle of an L1 entry. */
-	gpi_mask = gpi_mask << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2);
+			/* Fill Contiguous descriptors */
+			fill_desc(&l1[idx], l1_desc, cnt);
+			first += cont_size;
+			length -= cont_size;
 
-	/* Fill out each L1 entry for this region. */
-	for (unsigned int i = GPT_L1_IDX(gpt_config.p, first);
-	     i <= GPT_L1_IDX(gpt_config.p, last); i++) {
-		/* Account for stopping in the middle of an L1 entry. */
-		if (i == GPT_L1_IDX(gpt_config.p, last)) {
-			gpi_mask &= (gpi_mask >> ((15 -
+			if (length == 0UL) {
+				break;
+			}
+		}
+	}
+
+	return first;
+}
+
+/* Build Granules descriptor with the same 'gpi' for every GPI entry */
+static uint64_t build_l1_desc(unsigned int gpi)
+{
+	uint64_t l1_desc = (uint64_t)gpi | ((uint64_t)gpi << 4);
+
+	l1_desc |= (l1_desc << 8);
+	l1_desc |= (l1_desc << 16);
+	return (l1_desc | (l1_desc << 32));
+}
+
+/*
+ * Helper function to fill out GPI entries from 'first' to 'last' granule
+ * address in a single L1 table with 'l1_desc' Granules descriptor.
+ *
+ * Parameters
+ *   l1			Pointer to L1 table to fill out
+ *   first		Address of first granule in range
+ *   last		Address of last granule in range (inclusive)
+ *   gpi		GPI set this range to
+ *
+ * Return
+ *   Address of next granule in range.
+ */
+static uintptr_t fill_l1_gran_desc(uint64_t *l1, uintptr_t first,
+				   uintptr_t last, unsigned int gpi)
+{
+	uint64_t gpi_mask;
+	unsigned long i;
+
+	/* Generate Granules descriptor */
+	uint64_t l1_desc = build_l1_desc(gpi);
+
+	/* Shift the mask if we're starting in the middle of an L1 entry */
+	gpi_mask = ULONG_MAX << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2);
+
+	/* Fill out each L1 entry for this region */
+	for (i = GPT_L1_INDEX(first); i <= GPT_L1_INDEX(last); i++) {
+
+		/* Account for stopping in the middle of an L1 entry */
+		if (i == GPT_L1_INDEX(last)) {
+			gpi_mask &= (gpi_mask >> ((15U -
 				    GPT_L1_GPI_IDX(gpt_config.p, last)) << 2));
 		}
 
-		/* Write GPI values. */
-		assert((l1[i] & gpi_mask) ==
-		       (GPT_BUILD_L1_DESC(GPT_GPI_ANY) & gpi_mask));
-		l1[i] = (l1[i] & ~gpi_mask) | (gpi_mask & gpi_field);
+		assert((l1[i] & gpi_mask) == (GPT_L1_ANY_DESC & gpi_mask));
 
-		/* Reset mask. */
-		gpi_mask = 0xFFFFFFFFFFFFFFFF;
+		/* Write GPI values */
+		l1[i] = (l1[i] & ~gpi_mask) | (l1_desc & gpi_mask);
+
+		/* Reset mask */
+		gpi_mask = ULONG_MAX;
 	}
+
+	return last + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
 }
 
 /*
+ * Helper function to fill out GPI entries in a single L1 table.
+ * This function fills out an entire L1 table with either Granules or Contiguous
+ * (RME_GPT_MAX_BLOCK != 0) descriptors depending on region length and alignment.
+ * Note. If RME_GPT_MAX_BLOCK == 0, then the L1 tables are filled with regular
+ * Granules descriptors.
+ *
+ * Parameters
+ *   l1			Pointer to L1 table to fill out
+ *   first		Address of first granule in range
+ *   last		Address of last granule in range (inclusive)
+ *   gpi		GPI set this range to
+ */
+static void fill_l1_tbl(uint64_t *l1, uintptr_t first, uintptr_t last,
+			unsigned int gpi)
+{
+	assert(l1 != NULL);
+	assert(first <= last);
+	assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
+	assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
+	assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
+
+#if (RME_GPT_MAX_BLOCK != 0)
+	while (first <= last) {
+		/* Region length */
+		size_t length = last - first + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+		if (length < SZ_2M) {
+			/*
+			 * Fill with Granule descriptors in case of
+			 * region length < 2MB.
+			 */
+			first = fill_l1_gran_desc(l1, first, last, gpi);
+
+		} else if ((first & (SZ_2M - UL(1))) == UL(0)) {
+			/*
+			 * For region length >= 2MB and at least 2MB aligned
+			 * call to fill_l1_cont_desc will iterate through
+			 * all block sizes (512MB, 32MB and 2MB) supported and
+			 * fill corresponding Contiguous descriptors.
+			 */
+			first = fill_l1_cont_desc(l1, first, length, gpi);
+		} else {
+			/*
+			 * For not aligned region >= 2MB fill with Granules
+			 * descriptors up to the next 2MB aligned address.
+			 */
+			uintptr_t new_last = ALIGN_2MB(first + SZ_2M) -
+					GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+			first = fill_l1_gran_desc(l1, first, new_last, gpi);
+		}
+	}
+#else
+	/* Fill with Granule descriptors */
+	first = fill_l1_gran_desc(l1, first, last, gpi);
+#endif
+	assert(first == (last + GPT_PGS_ACTUAL_SIZE(gpt_config.p)));
+}
+
+/*
  * This function finds the next available unused L1 table and initializes all
  * granules descriptor entries to GPI_ANY. This ensures that there are no chunks
  * of GPI_NO_ACCESS (0b0000) memory floating around in the system in the
@@ -537,19 +895,17 @@
  * Return
  *   Pointer to the next available L1 table.
  */
-static uint64_t *gpt_get_new_l1_tbl(void)
+static uint64_t *get_new_l1_tbl(void)
 {
-	/* Retrieve the next L1 table. */
-	uint64_t *l1 = (uint64_t *)((uint64_t)(gpt_l1_tbl) +
-		       (GPT_L1_TABLE_SIZE(gpt_config.p) *
-		       gpt_next_l1_tbl_idx));
+	/* Retrieve the next L1 table */
+	uint64_t *l1 = (uint64_t *)gpt_l1_tbl;
 
-	/* Increment L1 counter. */
-	gpt_next_l1_tbl_idx++;
+	/* Increment L1 GPT address */
+	gpt_l1_tbl += GPT_L1_TABLE_SIZE(gpt_config.p);
 
 	/* Initialize all GPIs to GPT_GPI_ANY */
 	for (unsigned int i = 0U; i < GPT_L1_ENTRY_COUNT(gpt_config.p); i++) {
-		l1[i] = GPT_BUILD_L1_DESC(GPT_GPI_ANY);
+		l1[i] = GPT_L1_ANY_DESC;
 	}
 
 	return l1;
@@ -563,58 +919,57 @@
  * Parameters
  *   *pas		Pointer to the structure defining the PAS region.
  */
-static void gpt_generate_l0_tbl_desc(pas_region_t *pas)
+static void generate_l0_tbl_desc(pas_region_t *pas)
 {
 	uintptr_t end_pa;
 	uintptr_t cur_pa;
 	uintptr_t last_gran_pa;
 	uint64_t *l0_gpt_base;
 	uint64_t *l1_gpt_arr;
-	unsigned int l0_idx;
+	unsigned int l0_idx, gpi;
 
 	assert(gpt_config.plat_gpt_l0_base != 0U);
 	assert(pas != NULL);
 
 	/*
 	 * Checking of PAS parameters has already been done in
-	 * gpt_validate_pas_mappings so no need to check the same things again.
+	 * validate_pas_mappings so no need to check the same things again.
 	 */
-
 	end_pa = pas->base_pa + pas->size;
 	l0_gpt_base = (uint64_t *)gpt_config.plat_gpt_l0_base;
 
 	/* We start working from the granule at base PA */
 	cur_pa = pas->base_pa;
 
-	/* Iterate over each L0 region in this memory range. */
-	for (l0_idx = GPT_L0_IDX(pas->base_pa);
-	     l0_idx <= GPT_L0_IDX(end_pa - 1U);
-	     l0_idx++) {
+	/* Get GPI */
+	gpi = GPT_PAS_ATTR_GPI(pas->attrs);
 
+	/* Iterate over each L0 region in this memory range */
+	for (l0_idx = (unsigned int)GPT_L0_IDX(pas->base_pa);
+	     l0_idx <= (unsigned int)GPT_L0_IDX(end_pa - 1UL);
+	     l0_idx++) {
 		/*
 		 * See if the L0 entry is already a table descriptor or if we
 		 * need to create one.
 		 */
 		if (GPT_L0_TYPE(l0_gpt_base[l0_idx]) == GPT_L0_TYPE_TBL_DESC) {
-			/* Get the L1 array from the L0 entry. */
+			/* Get the L1 array from the L0 entry */
 			l1_gpt_arr = GPT_L0_TBLD_ADDR(l0_gpt_base[l0_idx]);
 		} else {
-			/* Get a new L1 table from the L1 memory space. */
-			l1_gpt_arr = gpt_get_new_l1_tbl();
+			/* Get a new L1 table from the L1 memory space */
+			l1_gpt_arr = get_new_l1_tbl();
 
-			/* Fill out the L0 descriptor and flush it. */
+			/* Fill out the L0 descriptor and flush it */
 			l0_gpt_base[l0_idx] = GPT_L0_TBL_DESC(l1_gpt_arr);
 		}
 
-		VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%" PRIx64 ")\n",
-			l0_idx, &l0_gpt_base[l0_idx],
-			(unsigned long long)(l1_gpt_arr),
-			l0_gpt_base[l0_idx]);
+		VERBOSE("GPT: L0 entry (TABLE) index %u [%p] ==> L1 Addr %p (0x%"PRIx64")\n",
+			l0_idx, &l0_gpt_base[l0_idx], l1_gpt_arr, l0_gpt_base[l0_idx]);
 
 		/*
 		 * Determine the PA of the last granule in this L0 descriptor.
 		 */
-		last_gran_pa = gpt_get_l1_end_pa(cur_pa, end_pa) -
+		last_gran_pa = get_l1_end_pa(cur_pa, end_pa) -
 			       GPT_PGS_ACTUAL_SIZE(gpt_config.p);
 
 		/*
@@ -622,11 +977,10 @@
 		 * function needs the addresses of the first granule and last
 		 * granule in the range.
 		 */
-		gpt_fill_l1_tbl(GPT_PAS_ATTR_GPI(pas->attrs), l1_gpt_arr,
-				cur_pa, last_gran_pa);
+		fill_l1_tbl(l1_gpt_arr, cur_pa, last_gran_pa, gpi);
 
-		/* Advance cur_pa to first granule in next L0 region. */
-		cur_pa = gpt_get_l1_end_pa(cur_pa, end_pa);
+		/* Advance cur_pa to first granule in next L0 region */
+		cur_pa = get_l1_end_pa(cur_pa, end_pa);
 	}
 }
 
@@ -643,25 +997,25 @@
  */
 static void flush_l0_for_pas_array(pas_region_t *pas, unsigned int pas_count)
 {
-	unsigned int idx;
-	unsigned int start_idx;
-	unsigned int end_idx;
+	unsigned long idx;
+	unsigned long start_idx;
+	unsigned long end_idx;
 	uint64_t *l0 = (uint64_t *)gpt_config.plat_gpt_l0_base;
 
 	assert(pas != NULL);
-	assert(pas_count > 0);
+	assert(pas_count != 0U);
 
-	/* Initial start and end values. */
+	/* Initial start and end values */
 	start_idx = GPT_L0_IDX(pas[0].base_pa);
-	end_idx = GPT_L0_IDX(pas[0].base_pa + pas[0].size - 1);
+	end_idx = GPT_L0_IDX(pas[0].base_pa + pas[0].size - 1UL);
 
-	/* Find lowest and highest L0 indices used in this PAS array. */
-	for (idx = 1; idx < pas_count; idx++) {
+	/* Find lowest and highest L0 indices used in this PAS array */
+	for (idx = 1UL; idx < pas_count; idx++) {
 		if (GPT_L0_IDX(pas[idx].base_pa) < start_idx) {
 			start_idx = GPT_L0_IDX(pas[idx].base_pa);
 		}
-		if (GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1) > end_idx) {
-			end_idx = GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1);
+		if (GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1UL) > end_idx) {
+			end_idx = GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1UL);
 		}
 	}
 
@@ -670,7 +1024,7 @@
 	 * the end index value.
 	 */
 	flush_dcache_range((uintptr_t)&l0[start_idx],
-			   ((end_idx + 1) - start_idx) * sizeof(uint64_t));
+			   ((end_idx + 1UL) - start_idx) * sizeof(uint64_t));
 }
 
 /*
@@ -689,8 +1043,8 @@
 	 * Granule tables must be initialised before enabling
 	 * granule protection.
 	 */
-	if (gpt_config.plat_gpt_l0_base == 0U) {
-		ERROR("[GPT] Tables have not been initialized!\n");
+	if (gpt_config.plat_gpt_l0_base == 0UL) {
+		ERROR("GPT: Tables have not been initialized!\n");
 		return -EPERM;
 	}
 
@@ -711,7 +1065,7 @@
 	 */
 	gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_IS);
 
-	/* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */
+	/* Outer and Inner cacheability set to Normal memory, WB, RA, WA */
 	gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA);
 	gpccr_el3 |= SET_GPCCR_IRGN(GPCCR_IRGN_WB_RA_WA);
 
@@ -727,7 +1081,7 @@
 	/* Enable GPT */
 	gpccr_el3 |= GPCCR_GPC_BIT;
 
-	/* TODO: Configure GPCCR_EL3_GPCP for Fault control. */
+	/* TODO: Configure GPCCR_EL3_GPCP for Fault control */
 	write_gpccr_el3(gpccr_el3);
 	isb();
 	tlbipaallos();
@@ -766,19 +1120,21 @@
 int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
 		       size_t l0_mem_size)
 {
-	int ret;
 	uint64_t gpt_desc;
+	size_t locks_size = 0;
+	__unused bitlock_t *bit_locks;
+	int ret;
 
-	/* Ensure that MMU and Data caches are enabled. */
+	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 
-	/* Validate other parameters. */
-	ret = gpt_validate_l0_params(pps, l0_mem_base, l0_mem_size);
+	/* Validate other parameters */
+	ret = validate_l0_params(pps, l0_mem_base, l0_mem_size);
 	if (ret != 0) {
 		return ret;
 	}
 
-	/* Create the descriptor to initialize L0 entries with. */
+	/* Create the descriptor to initialize L0 entries with */
 	gpt_desc = GPT_L0_BLK_DESC(GPT_GPI_ANY);
 
 	/* Iterate through all L0 entries */
@@ -786,11 +1142,33 @@
 		((uint64_t *)l0_mem_base)[i] = gpt_desc;
 	}
 
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Initialise bitlocks at the end of L0 table */
+	bit_locks = (bitlock_t *)(l0_mem_base +
+					GPT_L0_TABLE_SIZE(gpt_config.t));
+
+	/* Size of bitlocks in bytes */
+	locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
+					(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
+
-	/* Flush updated L0 tables to memory. */
+	/*
+	 * If protected space size is less than the size covered
+	 * by 'bitlock' structure, initialise a single bitlock.
+	 */
+	if (locks_size < LOCK_SIZE) {
+		locks_size = LOCK_SIZE;
+	}
+
+	for (size_t i = 0UL; i < (locks_size/LOCK_SIZE); i++) {
+		bit_locks[i].lock = 0U;
+	}
+#endif
+
+	/* Flush updated L0 tables and bitlocks to memory */
 	flush_dcache_range((uintptr_t)l0_mem_base,
-			   (size_t)GPT_L0_TABLE_SIZE(gpt_config.t));
+				GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size);
 
-	/* Stash the L0 base address once initial setup is complete. */
+	/* Stash the L0 base address once initial setup is complete */
 	gpt_config.plat_gpt_l0_base = l0_mem_base;
 
 	return 0;
@@ -805,7 +1183,7 @@
  * This function can be called multiple times with different L1 memory ranges
  * and PAS regions if it is desirable to place L1 tables in different locations
  * in memory. (ex: you have multiple DDR banks and want to place the L1 tables
- * in the DDR bank that they control)
+ * in the DDR bank that they control).
  *
  * Parameters
  *   pgs		PGS value to use for table generation.
@@ -821,82 +1199,86 @@
 			   size_t l1_mem_size, pas_region_t *pas_regions,
 			   unsigned int pas_count)
 {
-	int ret;
-	int l1_gpt_cnt;
+	int l1_gpt_cnt, ret;
 
-	/* Ensure that MMU and Data caches are enabled. */
+	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 
-	/* PGS is needed for gpt_validate_pas_mappings so check it now. */
+	/* PGS is needed for validate_pas_mappings so check it now */
 	if (pgs > GPT_PGS_MAX) {
-		ERROR("[GPT] Invalid PGS: 0x%x\n", pgs);
+		ERROR("GPT: Invalid PGS: 0x%x\n", pgs);
 		return -EINVAL;
 	}
 	gpt_config.pgs = pgs;
 	gpt_config.p = gpt_p_lookup[pgs];
 
-	/* Make sure L0 tables have been initialized. */
+	/* Make sure L0 tables have been initialized */
 	if (gpt_config.plat_gpt_l0_base == 0U) {
-		ERROR("[GPT] L0 tables must be initialized first!\n");
+		ERROR("GPT: L0 tables must be initialized first!\n");
 		return -EPERM;
 	}
 
-	/* Check if L1 GPTs are required and how many. */
-	l1_gpt_cnt = gpt_validate_pas_mappings(pas_regions, pas_count);
+	/* Check if L1 GPTs are required and how many */
+	l1_gpt_cnt = validate_pas_mappings(pas_regions, pas_count);
 	if (l1_gpt_cnt < 0) {
 		return l1_gpt_cnt;
 	}
 
-	VERBOSE("[GPT] %u L1 GPTs requested.\n", l1_gpt_cnt);
+	VERBOSE("GPT: %i L1 GPTs requested\n", l1_gpt_cnt);
 
-	/* If L1 tables are needed then validate the L1 parameters. */
+	/* If L1 tables are needed then validate the L1 parameters */
 	if (l1_gpt_cnt > 0) {
-		ret = gpt_validate_l1_params(l1_mem_base, l1_mem_size,
-		      l1_gpt_cnt);
+		ret = validate_l1_params(l1_mem_base, l1_mem_size,
+					(unsigned int)l1_gpt_cnt);
 		if (ret != 0) {
 			return ret;
 		}
 
-		/* Set up parameters for L1 table generation. */
+		/* Set up parameters for L1 table generation */
 		gpt_l1_tbl = l1_mem_base;
-		gpt_next_l1_tbl_idx = 0U;
 	}
 
-	INFO("[GPT] Boot Configuration\n");
+	/* Number of L1 entries in 2MB depends on GPCCR_EL3.PGS value */
+	gpt_l1_cnt_2mb = (unsigned int)GPT_L1_ENTRY_COUNT_2MB(gpt_config.p);
+
+	/* Mask for the L1 index field */
+	gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
+
+	INFO("GPT: Boot Configuration\n");
 	INFO("  PPS/T:     0x%x/%u\n", gpt_config.pps, gpt_config.t);
 	INFO("  PGS/P:     0x%x/%u\n", gpt_config.pgs, gpt_config.p);
 	INFO("  L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL);
-	INFO("  PAS count: 0x%x\n", pas_count);
-	INFO("  L0 base:   0x%lx\n", gpt_config.plat_gpt_l0_base);
+	INFO("  PAS count: %u\n", pas_count);
+	INFO("  L0 base:   0x%"PRIxPTR"\n", gpt_config.plat_gpt_l0_base);
 
-	/* Generate the tables in memory. */
+	/* Generate the tables in memory */
 	for (unsigned int idx = 0U; idx < pas_count; idx++) {
-		INFO("[GPT] PAS[%u]: base 0x%lx, size 0x%lx, GPI 0x%x, type 0x%x\n",
-		     idx, pas_regions[idx].base_pa, pas_regions[idx].size,
-		     GPT_PAS_ATTR_GPI(pas_regions[idx].attrs),
-		     GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs));
+		VERBOSE("GPT: PAS[%u]: base 0x%"PRIxPTR"\tsize 0x%lx\tGPI 0x%x\ttype 0x%x\n",
+			idx, pas_regions[idx].base_pa, pas_regions[idx].size,
+			GPT_PAS_ATTR_GPI(pas_regions[idx].attrs),
+			GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs));
 
 		/* Check if a block or table descriptor is required */
 		if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) ==
 		    GPT_PAS_ATTR_MAP_TYPE_BLOCK) {
-			gpt_generate_l0_blk_desc(&pas_regions[idx]);
+			generate_l0_blk_desc(&pas_regions[idx]);
 
 		} else {
-			gpt_generate_l0_tbl_desc(&pas_regions[idx]);
+			generate_l0_tbl_desc(&pas_regions[idx]);
 		}
 	}
 
-	/* Flush modified L0 tables. */
+	/* Flush modified L0 tables */
 	flush_l0_for_pas_array(pas_regions, pas_count);
 
-	/* Flush L1 tables if needed. */
+	/* Flush L1 tables if needed */
 	if (l1_gpt_cnt > 0) {
 		flush_dcache_range(l1_mem_base,
 				   GPT_L1_TABLE_SIZE(gpt_config.p) *
-				   l1_gpt_cnt);
+				   (size_t)l1_gpt_cnt);
 	}
 
-	/* Make sure that all the entries are written to the memory. */
+	/* Make sure that all the entries are written to the memory */
 	dsbishst();
 	tlbipaallos();
 	dsb();
@@ -920,12 +1302,12 @@
 {
 	u_register_t reg;
 
-	/* Ensure that MMU and Data caches are enabled. */
+	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 
-	/* Ensure GPC are already enabled. */
+	/* Ensure GPC are already enabled */
 	if ((read_gpccr_el3() & GPCCR_GPC_BIT) == 0U) {
-		ERROR("[GPT] Granule protection checks are not enabled!\n");
+		ERROR("GPT: Granule protection checks are not enabled!\n");
 		return -EPERM;
 	}
 
@@ -938,32 +1320,38 @@
 				      GPTBR_BADDR_MASK) <<
 				      GPTBR_BADDR_VAL_SHIFT;
 
-	/* Read GPCCR to get PGS and PPS values. */
+	/* Read GPCCR to get PGS and PPS values */
 	reg = read_gpccr_el3();
 	gpt_config.pps = (reg >> GPCCR_PPS_SHIFT) & GPCCR_PPS_MASK;
 	gpt_config.t = gpt_t_lookup[gpt_config.pps];
 	gpt_config.pgs = (reg >> GPCCR_PGS_SHIFT) & GPCCR_PGS_MASK;
 	gpt_config.p = gpt_p_lookup[gpt_config.pgs];
 
+	/* Number of L1 entries in 2MB depends on GPCCR_EL3.PGS value */
+	gpt_l1_cnt_2mb = (unsigned int)GPT_L1_ENTRY_COUNT_2MB(gpt_config.p);
+
-	VERBOSE("[GPT] Runtime Configuration\n");
+	/* Mask for the L1 index field */
+	gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
+
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Bitlocks at the end of L0 table */
+	gpt_bitlock_base = (bitlock_t *)(gpt_config.plat_gpt_l0_base +
+					GPT_L0_TABLE_SIZE(gpt_config.t));
+#endif
+	VERBOSE("GPT: Runtime Configuration\n");
 	VERBOSE("  PPS/T:     0x%x/%u\n", gpt_config.pps, gpt_config.t);
 	VERBOSE("  PGS/P:     0x%x/%u\n", gpt_config.pgs, gpt_config.p);
 	VERBOSE("  L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL);
-	VERBOSE("  L0 base:   0x%lx\n", gpt_config.plat_gpt_l0_base);
-
+	VERBOSE("  L0 base:   0x%"PRIxPTR"\n", gpt_config.plat_gpt_l0_base);
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	VERBOSE("  Bitlocks:  0x%"PRIxPTR"\n", (uintptr_t)gpt_bitlock_base);
+#endif
 	return 0;
 }
 
 /*
- * The L1 descriptors are protected by a spinlock to ensure that multiple
- * CPUs do not attempt to change the descriptors at once. In the future it
- * would be better to have separate spinlocks for each L1 descriptor.
- */
-static spinlock_t gpt_lock;
-
-/*
  * A helper to write the value (target_pas << gpi_shift) to the index of
- * the gpt_l1_addr
+ * the gpt_l1_addr.
  */
 static inline void write_gpt(uint64_t *gpt_l1_desc, uint64_t *gpt_l1_addr,
 			     unsigned int gpi_shift, unsigned int idx,
@@ -972,39 +1360,334 @@
 	*gpt_l1_desc &= ~(GPT_L1_GRAN_DESC_GPI_MASK << gpi_shift);
 	*gpt_l1_desc |= ((uint64_t)target_pas << gpi_shift);
 	gpt_l1_addr[idx] = *gpt_l1_desc;
+
+	dsboshst();
 }
 
 /*
  * Helper to retrieve the gpt_l1_* information from the base address
- * returned in gpi_info
+ * returned in gpi_info.
  */
 static int get_gpi_params(uint64_t base, gpi_info_t *gpi_info)
 {
 	uint64_t gpt_l0_desc, *gpt_l0_base;
+	__unused unsigned int block_idx;
 
 	gpt_l0_base = (uint64_t *)gpt_config.plat_gpt_l0_base;
 	gpt_l0_desc = gpt_l0_base[GPT_L0_IDX(base)];
 	if (GPT_L0_TYPE(gpt_l0_desc) != GPT_L0_TYPE_TBL_DESC) {
-		VERBOSE("[GPT] Granule is not covered by a table descriptor!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Granule is not covered by a table descriptor!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		return -EINVAL;
 	}
 
-	/* Get the table index and GPI shift from PA. */
+	/* Get the table index and GPI shift from PA */
 	gpi_info->gpt_l1_addr = GPT_L0_TBLD_ADDR(gpt_l0_desc);
-	gpi_info->idx = GPT_L1_IDX(gpt_config.p, base);
+	gpi_info->idx = (unsigned int)GPT_L1_INDEX(base);
 	gpi_info->gpi_shift = GPT_L1_GPI_IDX(gpt_config.p, base) << 2;
 
-	gpi_info->gpt_l1_desc = (gpi_info->gpt_l1_addr)[gpi_info->idx];
-	gpi_info->gpi = (gpi_info->gpt_l1_desc >> gpi_info->gpi_shift) &
-		GPT_L1_GRAN_DESC_GPI_MASK;
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Block index */
+	block_idx = (unsigned int)(base / (RME_GPT_BITLOCK_BLOCK * SZ_512M));
+
+	/* Bitlock address and mask */
+	gpi_info->lock = &gpt_bitlock_base[block_idx / LOCK_BITS];
+	gpi_info->mask = 1U << (block_idx & (LOCK_BITS - 1U));
+#endif
 	return 0;
 }
 
 /*
+ * Helper to retrieve the gpt_l1_desc and GPI information from gpi_info.
+ * This function is called with bitlock or spinlock acquired.
+ */
+static void read_gpi(gpi_info_t *gpi_info)
+{
+	gpi_info->gpt_l1_desc = (gpi_info->gpt_l1_addr)[gpi_info->idx];
+
+	if ((gpi_info->gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+				 GPT_L1_TYPE_CONT_DESC) {
+		/* Read GPI from Contiguous descriptor */
+		gpi_info->gpi = (unsigned int)GPT_L1_CONT_GPI(gpi_info->gpt_l1_desc);
+	} else {
+		/* Read GPI from Granules descriptor */
+		gpi_info->gpi = (unsigned int)((gpi_info->gpt_l1_desc >> gpi_info->gpi_shift) &
+						GPT_L1_GRAN_DESC_GPI_MASK);
+	}
+}
+
+static void flush_page_to_popa(uintptr_t addr)
+{
+	size_t size = GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+	if (is_feat_mte2_supported()) {
+		flush_dcache_to_popa_range_mte2(addr, size);
+	} else {
+		flush_dcache_to_popa_range(addr, size);
+	}
+}
+
+/*
+ * Helper function to check if all L1 entries in 2MB block have
+ * the same Granules descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor with all entries
+ *			set to the same GPI.
+ *
+ * Return
+ *   true if L1 all entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_2mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* Last L1 entry index in 2MB block */
+	unsigned int long idx = GPT_L1_INDEX(ALIGN_2MB(base)) +
+						gpt_l1_cnt_2mb - 1UL;
+
+	/* Number of L1 entries in 2MB block */
+	unsigned int cnt = gpt_l1_cnt_2mb;
+
+	/*
+	 * Start check from the last L1 entry and continue until the first
+	 * non-matching to the passed Granules descriptor value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx--] != l1_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+	}
+
+	return true;
+}
+
+__unused static void fuse_2mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 2MB block */
+	unsigned long idx_2 = GPT_L1_INDEX(ALIGN_2MB(base));
+
+	/* 2MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_2], l1_cont_desc, L1_QWORDS_2MB);
+}
+
+/*
+ * Helper function to check if all 1st L1 entries of 2MB blocks
+ * in 32MB have the same 2MB Contiguous descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor.
+ *
+ * Return
+ *   true if all L1 entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_32mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* The 1st L1 entry index of the last 2MB block in 32MB */
+	unsigned long idx = GPT_L1_INDEX(ALIGN_32MB(base)) +
+					(15UL * gpt_l1_cnt_2mb);
+
+	/* 2MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+
+	/* Number of 2MB blocks in 32MB */
+	unsigned int cnt = 16U;
+
+	/* Set the first L1 entry to 2MB Contiguous descriptor */
+	gpi_info->gpt_l1_addr[GPT_L1_INDEX(ALIGN_2MB(base))] = l1_cont_desc;
+
+	/*
+	 * Start check from the 1st L1 entry of the last 2MB block and
+	 * continue until the first non-matching to 2MB Contiguous descriptor
+	 * value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx] != l1_cont_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+		idx -= gpt_l1_cnt_2mb;
+	}
+
+	return true;
+}
+
+__unused static void fuse_32mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 32MB block */
+	unsigned long idx_32 = GPT_L1_INDEX(ALIGN_32MB(base));
+
+	/* 32MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_32], l1_cont_desc, L1_QWORDS_32MB);
+}
+
+/*
+ * Helper function to check if all 1st L1 entries of 32MB blocks
+ * in 512MB have the same 32MB Contiguous descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor.
+ *
+ * Return
+ *   true if all L1 entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_512mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* The 1st L1 entry index of the last 32MB block in 512MB */
+	unsigned long idx = GPT_L1_INDEX(ALIGN_512MB(base)) +
+					(15UL * 16UL * gpt_l1_cnt_2mb);
+
+	/* 32MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+
+	/* Number of 32MB blocks in 512MB */
+	unsigned int cnt = 16U;
+
+	/* Set the first L1 entry to 2MB Contiguous descriptor */
+	gpi_info->gpt_l1_addr[GPT_L1_INDEX(ALIGN_32MB(base))] = l1_cont_desc;
+
+	/*
+	 * Start check from the 1st L1 entry of the last 32MB block and
+	 * continue until the first non-matching to 32MB Contiguous descriptor
+	 * value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx] != l1_cont_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+		idx -= 16UL * gpt_l1_cnt_2mb;
+	}
+
+	return true;
+}
+
+__unused static void fuse_512mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 512MB block */
+	unsigned long idx_512 = GPT_L1_INDEX(ALIGN_512MB(base));
+
+	/* 512MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 512MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_512], l1_cont_desc, L1_QWORDS_512MB);
+}
+
+/*
+ * Helper function to convert GPI entries in a single L1 table
+ * from Granules to Contiguous descriptor.
+ *
+ * Parameters
+ *   base		Base address of the region to be written
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor with all entries
+ *			set to the same GPI.
+ */
+__unused static void fuse_block(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* Start with check for 2MB block */
+	if (!check_fuse_2mb(base, gpi_info, l1_desc)) {
+		/* Check for 2MB fusing failed */
+		return;
+	}
+
+#if (RME_GPT_MAX_BLOCK == 2)
+	fuse_2mb(base, gpi_info, l1_desc);
+#else
+	/* Check for 32MB block */
+	if (!check_fuse_32mb(base, gpi_info, l1_desc)) {
+		/* Check for 32MB fusing failed, fuse to 2MB */
+		fuse_2mb(base, gpi_info, l1_desc);
+		return;
+	}
+
+#if (RME_GPT_MAX_BLOCK == 32)
+	fuse_32mb(base, gpi_info, l1_desc);
+#else
+	/* Check for 512MB block */
+	if (!check_fuse_512mb(base, gpi_info, l1_desc)) {
+		/* Check for 512MB fusing failed, fuse to 32MB */
+		fuse_32mb(base, gpi_info, l1_desc);
+		return;
+	}
+
+	/* Fuse to 512MB */
+	fuse_512mb(base, gpi_info, l1_desc);
+
+#endif	/* RME_GPT_MAX_BLOCK == 32 */
+#endif	/* RME_GPT_MAX_BLOCK == 2 */
+}
+
+/*
+ * Helper function to convert GPI entries in a single L1 table
+ * from Contiguous to Granules descriptor. This function updates
+ * descriptor to Granules in passed 'gpt_config_t' structure as
+ * the result of shuttering.
+ *
+ * Parameters
+ *   base		Base address of the region to be written
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor set this range to.
+ */
+__unused static void shatter_block(uint64_t base, gpi_info_t *gpi_info,
+				   uint64_t l1_desc)
+{
+	/* Look-up table for 2MB, 32MB and 512MB locks shattering */
+	static const gpt_shatter_func gpt_shatter_lookup[] = {
+		shatter_2mb,
+		shatter_32mb,
+		shatter_512mb
+	};
+
+	/* Look-up table for invalidation TLBs for 2MB, 32MB and 512MB blocks */
+	static const gpt_tlbi_lookup_t tlbi_lookup[] = {
+		{ tlbirpalos_2m, ~(SZ_2M - 1UL) },
+		{ tlbirpalos_32m, ~(SZ_32M - 1UL) },
+		{ tlbirpalos_512m, ~(SZ_512M - 1UL) }
+	};
+
+	/* Get shattering level from Contig field of Contiguous descriptor */
+	unsigned long level = GPT_L1_CONT_CONTIG(gpi_info->gpt_l1_desc) - 1UL;
+
+	/* Shatter contiguous block */
+	gpt_shatter_lookup[level](base, gpi_info, l1_desc);
+
+	tlbi_lookup[level].function(base & tlbi_lookup[level].mask);
+	dsbosh();
+
+	/*
+	 * Update 'gpt_config_t' structure's descriptor to Granules to reflect
+	 * the shattered GPI back to caller.
+	 */
+	gpi_info->gpt_l1_desc = l1_desc;
+}
+
+/*
  * This function is the granule transition delegate service. When a granule
  * transition request occurs it is routed to this function to have the request,
- * if valid, fulfilled following A1.1.1 Delegate of RME supplement
+ * if valid, fulfilled following A1.1.1 Delegate of RME supplement.
  *
  * TODO: implement support for transitioning multiple granules at once.
  *
@@ -1021,114 +1704,120 @@
 int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 {
 	gpi_info_t gpi_info;
-	uint64_t nse;
-	int res;
+	uint64_t nse, __unused l1_desc;
 	unsigned int target_pas;
+	int res;
 
-	/* Ensure that the tables have been set up before taking requests. */
+	/* Ensure that the tables have been set up before taking requests */
 	assert(gpt_config.plat_gpt_l0_base != 0UL);
 
-	/* Ensure that caches are enabled. */
+	/* Ensure that caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
 
-	/* Delegate request can only come from REALM or SECURE */
-	assert(src_sec_state == SMC_FROM_REALM ||
-	       src_sec_state == SMC_FROM_SECURE);
-
-	/* See if this is a single or a range of granule transition. */
+	/* See if this is a single or a range of granule transition */
 	if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) {
 		return -EINVAL;
 	}
 
 	/* Check that base and size are valid */
 	if ((ULONG_MAX - base) < size) {
-		VERBOSE("[GPT] Transition request address overflow!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Transition request address overflow!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	/* Make sure base and size are valid. */
-	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
-	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
+	/* Make sure base and size are valid */
+	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
+	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
 	    (size == 0UL) ||
 	    ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) {
-		VERBOSE("[GPT] Invalid granule transition address range!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Invalid granule transition address range!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	target_pas = GPT_GPI_REALM;
-	if (src_sec_state == SMC_FROM_SECURE) {
+	/* Delegate request can only come from REALM or SECURE */
+	if ((src_sec_state != SMC_FROM_REALM) &&
+	    (src_sec_state != SMC_FROM_SECURE)) {
+		VERBOSE("GPT: Invalid caller security state 0x%x\n",
+							src_sec_state);
+		return -EINVAL;
+	}
+
+	if (src_sec_state == SMC_FROM_REALM) {
+		target_pas = GPT_GPI_REALM;
+		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+		l1_desc = GPT_L1_REALM_DESC;
+	} else {
 		target_pas = GPT_GPI_SECURE;
+		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
+		l1_desc = GPT_L1_SECURE_DESC;
 	}
 
-	/*
-	 * Access to L1 tables is controlled by a global lock to ensure
-	 * that no more than one CPU is allowed to make changes at any
-	 * given time.
-	 */
-	spin_lock(&gpt_lock);
 	res = get_gpi_params(base, &gpi_info);
 	if (res != 0) {
-		spin_unlock(&gpt_lock);
 		return res;
 	}
 
+	/*
+	 * Access to GPT is controlled by a lock to ensure that no more
+	 * than one CPU is allowed to make changes at any given time.
+	 */
+	GPT_LOCK;
+	read_gpi(&gpi_info);
+
 	/* Check that the current address is in NS state */
 	if (gpi_info.gpi != GPT_GPI_NS) {
-		VERBOSE("[GPT] Only Granule in NS state can be delegated.\n");
+		VERBOSE("GPT: Only Granule in NS state can be delegated.\n");
 		VERBOSE("      Caller: %u, Current GPI: %u\n", src_sec_state,
 			gpi_info.gpi);
-		spin_unlock(&gpt_lock);
+		GPT_UNLOCK;
 		return -EPERM;
 	}
 
-	if (src_sec_state == SMC_FROM_SECURE) {
-		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
-	} else {
-		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+#if (RME_GPT_MAX_BLOCK != 0)
+	/* Check for Contiguous descriptor */
+	if ((gpi_info.gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+					GPT_L1_TYPE_CONT_DESC) {
+		shatter_block(base, &gpi_info, GPT_L1_NS_DESC);
 	}
-
+#endif
 	/*
 	 * In order to maintain mutual distrust between Realm and Secure
 	 * states, remove any data speculatively fetched into the target
-	 * physical address space. Issue DC CIPAPA over address range
+	 * physical address space.
+	 * Issue DC CIPAPA or DC_CIGDPAPA on implementations with FEAT_MTE2.
 	 */
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	flush_page_to_popa(base | nse);
 
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, target_pas);
-	dsboshst();
 
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	/* Ensure that all agents observe the new configuration */
+	tlbi_page_dsbosh(base);
 
 	nse = (uint64_t)GPT_NSE_NS << GPT_NSE_SHIFT;
 
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
+	/* Ensure that the scrubbed data have made it past the PoPA */
+	flush_page_to_popa(base | nse);
+
+#if (RME_GPT_MAX_BLOCK != 0)
+	if (gpi_info.gpt_l1_desc == l1_desc) {
+		/* Try to fuse */
+		fuse_block(base, &gpi_info, l1_desc);
 	}
+#endif
 
-	/* Unlock access to the L1 tables. */
-	spin_unlock(&gpt_lock);
+	/* Unlock the lock to GPT */
+	GPT_UNLOCK;
 
 	/*
 	 * The isb() will be done as part of context
-	 * synchronization when returning to lower EL
+	 * synchronization when returning to lower EL.
 	 */
-	VERBOSE("[GPT] Granule 0x%" PRIx64 ", GPI 0x%x->0x%x\n",
+	VERBOSE("GPT: Granule 0x%"PRIx64" GPI 0x%x->0x%x\n",
 		base, gpi_info.gpi, target_pas);
 
 	return 0;
@@ -1154,127 +1843,119 @@
 int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 {
 	gpi_info_t gpi_info;
-	uint64_t nse;
+	uint64_t nse, __unused l1_desc;
 	int res;
 
-	/* Ensure that the tables have been set up before taking requests. */
+	/* Ensure that the tables have been set up before taking requests */
 	assert(gpt_config.plat_gpt_l0_base != 0UL);
 
-	/* Ensure that MMU and caches are enabled. */
+	/* Ensure that MMU and caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
 
-	/* Delegate request can only come from REALM or SECURE */
-	assert(src_sec_state == SMC_FROM_REALM ||
-	       src_sec_state == SMC_FROM_SECURE);
-
-	/* See if this is a single or a range of granule transition. */
+	/* See if this is a single or a range of granule transition */
 	if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) {
 		return -EINVAL;
 	}
 
 	/* Check that base and size are valid */
 	if ((ULONG_MAX - base) < size) {
-		VERBOSE("[GPT] Transition request address overflow!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Transition request address overflow!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	/* Make sure base and size are valid. */
-	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
-	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
+	/* Make sure base and size are valid */
+	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
+	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
 	    (size == 0UL) ||
 	    ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) {
-		VERBOSE("[GPT] Invalid granule transition address range!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Invalid granule transition address range!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	/*
-	 * Access to L1 tables is controlled by a global lock to ensure
-	 * that no more than one CPU is allowed to make changes at any
-	 * given time.
-	 */
-	spin_lock(&gpt_lock);
-
 	res = get_gpi_params(base, &gpi_info);
 	if (res != 0) {
-		spin_unlock(&gpt_lock);
 		return res;
 	}
 
+	/*
+	 * Access to GPT is controlled by a lock to ensure that no more
+	 * than one CPU is allowed to make changes at any given time.
+	 */
+	GPT_LOCK;
+	read_gpi(&gpi_info);
+
 	/* Check that the current address is in the delegated state */
-	if ((src_sec_state == SMC_FROM_REALM  &&
-	     gpi_info.gpi != GPT_GPI_REALM) ||
-	    (src_sec_state == SMC_FROM_SECURE &&
-	     gpi_info.gpi != GPT_GPI_SECURE)) {
-		VERBOSE("[GPT] Only Granule in REALM or SECURE state can be undelegated.\n");
-		VERBOSE("      Caller: %u, Current GPI: %u\n", src_sec_state,
+	if ((src_sec_state == SMC_FROM_REALM) &&
+		(gpi_info.gpi == GPT_GPI_REALM)) {
+		l1_desc = GPT_L1_REALM_DESC;
+		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+	} else if ((src_sec_state == SMC_FROM_SECURE) &&
+		(gpi_info.gpi == GPT_GPI_SECURE)) {
+		l1_desc = GPT_L1_SECURE_DESC;
+		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
+	} else {
+		VERBOSE("GPT: Only Granule in REALM or SECURE state can be undelegated\n");
+		VERBOSE("      Caller: %u Current GPI: %u\n", src_sec_state,
 			gpi_info.gpi);
-		spin_unlock(&gpt_lock);
+		GPT_UNLOCK;
 		return -EPERM;
 	}
 
-
-	/* In order to maintain mutual distrust between Realm and Secure
+#if (RME_GPT_MAX_BLOCK != 0)
+	/* Check for Contiguous descriptor */
+	if ((gpi_info.gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+					GPT_L1_TYPE_CONT_DESC) {
+		shatter_block(base, &gpi_info, l1_desc);
+	}
+#endif
+	/*
+	 * In order to maintain mutual distrust between Realm and Secure
 	 * states, remove access now, in order to guarantee that writes
 	 * to the currently-accessible physical address space will not
 	 * later become observable.
 	 */
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, GPT_GPI_NO_ACCESS);
-	dsboshst();
 
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	/* Ensure that all agents observe the new NO_ACCESS configuration */
+	tlbi_page_dsbosh(base);
 
-	if (src_sec_state == SMC_FROM_SECURE) {
-		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
-	} else {
-		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
-	}
-
-	/* Ensure that the scrubbed data has made it past the PoPA */
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	/* Ensure that the scrubbed data have made it past the PoPA */
+	flush_page_to_popa(base | nse);
 
 	/*
-	 * Remove any data loaded speculatively
-	 * in NS space from before the scrubbing
+	 * Remove any data loaded speculatively in NS space from before
+	 * the scrubbing.
 	 */
 	nse = (uint64_t)GPT_NSE_NS << GPT_NSE_SHIFT;
 
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	flush_page_to_popa(base | nse);
 
-	/* Clear existing GPI encoding and transition granule. */
+	/* Clear existing GPI encoding and transition granule */
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, GPT_GPI_NS);
-	dsboshst();
 
 	/* Ensure that all agents observe the new NS configuration */
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	tlbi_page_dsbosh(base);
 
-	/* Unlock access to the L1 tables. */
-	spin_unlock(&gpt_lock);
+#if (RME_GPT_MAX_BLOCK != 0)
+	if (gpi_info.gpt_l1_desc == GPT_L1_NS_DESC) {
+		/* Try to fuse */
+		fuse_block(base, &gpi_info, GPT_L1_NS_DESC);
+	}
+#endif
+	/* Unlock the lock to GPT */
+	GPT_UNLOCK;
 
 	/*
 	 * The isb() will be done as part of context
-	 * synchronization when returning to lower EL
+	 * synchronization when returning to lower EL.
 	 */
-	VERBOSE("[GPT] Granule 0x%" PRIx64 ", GPI 0x%x->0x%x\n",
+	VERBOSE("GPT: Granule 0x%"PRIx64" GPI 0x%x->0x%x\n",
 		base, gpi_info.gpi, GPT_GPI_NS);
 
 	return 0;
diff --git a/lib/gpt_rme/gpt_rme.mk b/lib/gpt_rme/gpt_rme.mk
index 60176f4..7d6b61f 100644
--- a/lib/gpt_rme/gpt_rme.mk
+++ b/lib/gpt_rme/gpt_rme.mk
@@ -1,8 +1,22 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Process RME_GPT_BITLOCK_BLOCK value
+ifeq ($(filter 0 1 2 4 8 16 32 64 128 256 512, ${RME_GPT_BITLOCK_BLOCK}),)
+    $(error "Invalid value for RME_GPT_BITLOCK_BLOCK: ${RME_GPT_BITLOCK_BLOCK}")
+endif
+
+ifeq (${RME_GPT_BITLOCK_BLOCK},0)
+    $(warning "GPT library uses global spinlock")
+endif
+
+# Process RME_GPT_MAX_BLOCK value
+ifeq ($(filter 0 2 32 512, ${RME_GPT_MAX_BLOCK}),)
+    $(error "Invalid value for RME_GPT_MAX_BLOCK: ${RME_GPT_MAX_BLOCK}")
+endif
+
 GPT_LIB_SRCS	:=	$(addprefix lib/gpt_rme/,        \
 			gpt_rme.c)
diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h
index 3c817f3..31dad20 100644
--- a/lib/gpt_rme/gpt_rme_private.h
+++ b/lib/gpt_rme/gpt_rme_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,19 +9,20 @@
 
 #include <arch.h>
 #include <lib/gpt_rme/gpt_rme.h>
+#include <lib/spinlock.h>
 #include <lib/utils_def.h>
 
 /******************************************************************************/
 /* GPT descriptor definitions                                                 */
 /******************************************************************************/
 
-/* GPT level 0 descriptor bit definitions. */
+/* GPT level 0 descriptor bit definitions */
 #define GPT_L0_TYPE_MASK		UL(0xF)
 #define GPT_L0_TYPE_SHIFT		U(0)
 
-/* For now, we don't support contiguous descriptors, only table and block. */
-#define GPT_L0_TYPE_TBL_DESC		UL(0x3)
-#define GPT_L0_TYPE_BLK_DESC		UL(0x1)
+/* GPT level 0 table and block descriptors */
+#define GPT_L0_TYPE_TBL_DESC		UL(3)
+#define GPT_L0_TYPE_BLK_DESC		UL(1)
 
 #define GPT_L0_TBL_DESC_L1ADDR_MASK	UL(0xFFFFFFFFFF)
 #define GPT_L0_TBL_DESC_L1ADDR_SHIFT	U(12)
@@ -29,35 +30,69 @@
 #define GPT_L0_BLK_DESC_GPI_MASK	UL(0xF)
 #define GPT_L0_BLK_DESC_GPI_SHIFT	U(4)
 
-/* GPT level 1 descriptor bit definitions */
+/* GPT level 1 Contiguous descriptor */
+#define GPT_L1_TYPE_CONT_DESC_MASK	UL(0xF)
+#define GPT_L1_TYPE_CONT_DESC		UL(1)
+
+/* GPT level 1 Contiguous descriptor definitions */
+#define GPT_L1_CONTIG_2MB		UL(1)
+#define GPT_L1_CONTIG_32MB		UL(2)
+#define GPT_L1_CONTIG_512MB		UL(3)
+
+#define GPT_L1_CONT_DESC_GPI_SHIFT	U(4)
+#define GPT_L1_CONT_DESC_GPI_MASK	UL(0xF)
+#define GPT_L1_CONT_DESC_CONTIG_SHIFT	U(8)
+#define GPT_L1_CONT_DESC_CONTIG_MASK	UL(3)
+
+/* GPT level 1 Granules descriptor bit definitions */
 #define GPT_L1_GRAN_DESC_GPI_MASK	UL(0xF)
 
+/* L1 Contiguous descriptors templates */
+#define GPT_L1_CONT_DESC_2MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_2MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+#define GPT_L1_CONT_DESC_32MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_32MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+#define GPT_L1_CONT_DESC_512MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_512MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+
+/* Create L1 Contiguous descriptor from GPI and template */
+#define GPT_L1_GPI_CONT_DESC(_gpi, _desc)	\
+			((_desc) | ((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
+
+/* Create L1 Contiguous descriptor from Granules descriptor and size */
+#define GPT_L1_CONT_DESC(_desc, _size) \
+				(GPT_L1_CONT_DESC_##_size	| \
+				(((_desc) & GPT_L1_GRAN_DESC_GPI_MASK) << \
+				GPT_L1_CONT_DESC_GPI_SHIFT))
+
+/* Create L1 Contiguous descriptor from GPI and size */
+#define GPT_L1_CONT_DESC_SIZE(_gpi, _size) \
+				(GPT_L1_CONT_DESC_##_size	| \
+				(((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
+
+#define GPT_L1_GPI_BYTE(_gpi)		(uint64_t)((_gpi) | ((_gpi) << 4))
+#define GPT_L1_GPI_HALF(_gpi)		(GPT_L1_GPI_BYTE(_gpi) | (GPT_L1_GPI_BYTE(_gpi) << 8))
+#define GPT_L1_GPI_WORD(_gpi)		(GPT_L1_GPI_HALF(_gpi) | (GPT_L1_GPI_HALF(_gpi) << 16))
+
 /*
- * This macro fills out every GPI entry in a granules descriptor to the same
- * value.
+ * This macro generates a Granules descriptor
+ * with the same value for every GPI entry.
  */
-#define GPT_BUILD_L1_DESC(_gpi)		(((uint64_t)(_gpi) << 4*0) | \
-					 ((uint64_t)(_gpi) << 4*1) | \
-					 ((uint64_t)(_gpi) << 4*2) | \
-					 ((uint64_t)(_gpi) << 4*3) | \
-					 ((uint64_t)(_gpi) << 4*4) | \
-					 ((uint64_t)(_gpi) << 4*5) | \
-					 ((uint64_t)(_gpi) << 4*6) | \
-					 ((uint64_t)(_gpi) << 4*7) | \
-					 ((uint64_t)(_gpi) << 4*8) | \
-					 ((uint64_t)(_gpi) << 4*9) | \
-					 ((uint64_t)(_gpi) << 4*10) | \
-					 ((uint64_t)(_gpi) << 4*11) | \
-					 ((uint64_t)(_gpi) << 4*12) | \
-					 ((uint64_t)(_gpi) << 4*13) | \
-					 ((uint64_t)(_gpi) << 4*14) | \
-					 ((uint64_t)(_gpi) << 4*15))
+#define GPT_BUILD_L1_DESC(_gpi)		(GPT_L1_GPI_WORD(_gpi) | (GPT_L1_GPI_WORD(_gpi) << 32))
+
+#define GPT_L1_SECURE_DESC	GPT_BUILD_L1_DESC(GPT_GPI_SECURE)
+#define GPT_L1_NS_DESC		GPT_BUILD_L1_DESC(GPT_GPI_NS)
+#define GPT_L1_REALM_DESC	GPT_BUILD_L1_DESC(GPT_GPI_REALM)
+#define GPT_L1_ANY_DESC		GPT_BUILD_L1_DESC(GPT_GPI_ANY)
 
 /******************************************************************************/
 /* GPT platform configuration                                                 */
 /******************************************************************************/
 
-/* This value comes from GPCCR_EL3 so no externally supplied definition. */
+/* This value comes from GPCCR_EL3 so no externally supplied definition */
 #define GPT_L0GPTSZ		((unsigned int)((read_gpccr_el3() >> \
 				GPCCR_L0GPTSZ_SHIFT) & GPCCR_L0GPTSZ_MASK))
 
@@ -106,21 +141,50 @@
 	PGS_64KB_P =	16U
 } gpt_p_val_e;
 
+#define LOCK_SIZE	sizeof(((bitlock_t *)NULL)->lock)
+#define LOCK_TYPE	typeof(((bitlock_t *)NULL)->lock)
+#define LOCK_BITS	(LOCK_SIZE * 8U)
+
 /*
- * Internal structure to retrieve the values from get_gpi_info();
+ * Internal structure to retrieve the values from get_gpi_params();
  */
-typedef struct gpi_info {
+typedef struct {
 	uint64_t gpt_l1_desc;
 	uint64_t *gpt_l1_addr;
 	unsigned int idx;
 	unsigned int gpi_shift;
 	unsigned int gpi;
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	bitlock_t *lock;
+	LOCK_TYPE mask;
+#endif
 } gpi_info_t;
 
+/*
+ * Look up structure for contiguous blocks and descriptors
+ */
+typedef struct {
+	size_t size;
+	unsigned int desc;
+} gpt_fill_lookup_t;
+
-/* Max valid value for PGS. */
+typedef void (*gpt_shatter_func)(uintptr_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc);
+typedef void (*gpt_tlbi_func)(uintptr_t base);
+
+/*
+ * Look-up structure for
+ * invalidating TLBs of GPT entries by Physical address, last level.
+ */
+typedef struct {
+	gpt_tlbi_func function;
+	size_t mask;
+} gpt_tlbi_lookup_t;
+
+/* Max valid value for PGS */
 #define GPT_PGS_MAX			(2U)
 
-/* Max valid value for PPS. */
+/* Max valid value for PPS */
 #define GPT_PPS_MAX			(6U)
 
 /******************************************************************************/
@@ -136,10 +200,10 @@
  * special case we'll get a negative width value which does not make sense and
  * would cause problems.
  */
-#define GPT_L0_IDX_WIDTH(_t)		(((_t) > GPT_S_VAL) ? \
-					((_t) - GPT_S_VAL) : (0U))
+#define GPT_L0_IDX_WIDTH(_t)		(((unsigned int)(_t) > GPT_S_VAL) ? \
+					((unsigned int)(_t) - GPT_S_VAL) : (0U))
 
-/* Bit shift for the L0 index field in a PA. */
+/* Bit shift for the L0 index field in a PA */
 #define GPT_L0_IDX_SHIFT		(GPT_S_VAL)
 
 /*
@@ -153,13 +217,13 @@
 #define GPT_L0_IDX_MASK(_t)		(0x3FFFFFUL >> (22U - \
 					(GPT_L0_IDX_WIDTH(_t))))
 
-/* Total number of L0 regions. */
+/* Total number of L0 regions */
 #define GPT_L0_REGION_COUNT(_t)		((GPT_L0_IDX_MASK(_t)) + 1U)
 
-/* Total size of each GPT L0 region in bytes. */
+/* Total size of each GPT L0 region in bytes */
 #define GPT_L0_REGION_SIZE		(1UL << (GPT_L0_IDX_SHIFT))
 
-/* Total size in bytes of the whole L0 table. */
+/* Total size in bytes of the whole L0 table */
 #define GPT_L0_TABLE_SIZE(_t)		((GPT_L0_REGION_COUNT(_t)) << 3U)
 
 /******************************************************************************/
@@ -173,89 +237,124 @@
  * the L0 index field above since all valid combinations of PGS (p) and L0GPTSZ
  * (s) will result in a positive width value.
  */
-#define GPT_L1_IDX_WIDTH(_p)		((GPT_S_VAL - 1U) - ((_p) + 3U))
+#define GPT_L1_IDX_WIDTH(_p)		((GPT_S_VAL - 1U) - \
+					((unsigned int)(_p) + 3U))
 
-/* Bit shift for the L1 index field. */
-#define GPT_L1_IDX_SHIFT(_p)		((_p) + 4U)
+/* Bit shift for the L1 index field */
+#define GPT_L1_IDX_SHIFT(_p)		((unsigned int)(_p) + 4U)
 
 /*
  * Mask for the L1 index field, must be shifted.
  *
  * The value 0x7FFFFF is 23 bits wide and is the maximum possible width of the
  * L1 index within a physical address. It is calculated by
- * ((s_max - 1) - (p_min + 4) + 1) where s_max is 39 for 512gb, the largest
+ * ((s_max - 1) - (p_min + 4) + 1) where s_max is 39 for 512GB, the largest
  * L0GPTSZ, and p_min is 12 for 4KB granules, the smallest PGS.
  */
 #define GPT_L1_IDX_MASK(_p)		(0x7FFFFFUL >> (23U - \
 					(GPT_L1_IDX_WIDTH(_p))))
 
-/* Bit shift for the index of the L1 GPI in a PA. */
+/* Bit shift for the index of the L1 GPI in a PA */
 #define GPT_L1_GPI_IDX_SHIFT(_p)	(_p)
 
-/* Mask for the index of the L1 GPI in a PA. */
+/* Mask for the index of the L1 GPI in a PA */
 #define GPT_L1_GPI_IDX_MASK		(0xF)
 
-/* Total number of entries in each L1 table. */
-#define GPT_L1_ENTRY_COUNT(_p)		((GPT_L1_IDX_MASK(_p)) + 1U)
+/* Total number of entries in each L1 table */
+#define GPT_L1_ENTRY_COUNT(_p)		((GPT_L1_IDX_MASK(_p)) + 1UL)
 
-/* Total size in bytes of each L1 table. */
+/* Number of L1 entries in 2MB block */
+#define GPT_L1_ENTRY_COUNT_2MB(_p)	(SZ_2M >> GPT_L1_IDX_SHIFT(_p))
+
+/* Total size in bytes of each L1 table */
 #define GPT_L1_TABLE_SIZE(_p)		((GPT_L1_ENTRY_COUNT(_p)) << 3U)
 
 /******************************************************************************/
 /* General helper macros                                                      */
 /******************************************************************************/
 
-/* Protected space actual size in bytes. */
-#define GPT_PPS_ACTUAL_SIZE(_t)	(1UL << (_t))
+/* Protected space actual size in bytes */
+#define GPT_PPS_ACTUAL_SIZE(_t)	(1UL << (unsigned int)(_t))
 
-/* Granule actual size in bytes. */
-#define GPT_PGS_ACTUAL_SIZE(_p)	(1UL << (_p))
+/* Granule actual size in bytes */
+#define GPT_PGS_ACTUAL_SIZE(_p)	(1UL << (unsigned int)(_p))
 
-/* L0 GPT region size in bytes. */
+/* Number of granules in 2MB block */
+#define GPT_PGS_COUNT_2MB(_p)	(1UL << (21U - (unsigned int)(_p)))
+
+/* L0 GPT region size in bytes */
 #define GPT_L0GPTSZ_ACTUAL_SIZE	(1UL << GPT_S_VAL)
 
-/* Get the index of the L0 entry from a physical address. */
+/* Get the index of the L0 entry from a physical address */
 #define GPT_L0_IDX(_pa)		((_pa) >> GPT_L0_IDX_SHIFT)
 
 /*
  * This definition is used to determine if a physical address lies on an L0
  * region boundary.
  */
-#define GPT_IS_L0_ALIGNED(_pa)	(((_pa) & (GPT_L0_REGION_SIZE - U(1))) == U(0))
+#define GPT_IS_L0_ALIGNED(_pa)	\
+	(((_pa) & (GPT_L0_REGION_SIZE - UL(1))) == UL(0))
 
-/* Get the type field from an L0 descriptor. */
+/* Get the type field from an L0 descriptor */
 #define GPT_L0_TYPE(_desc)	(((_desc) >> GPT_L0_TYPE_SHIFT) & \
 				GPT_L0_TYPE_MASK)
 
-/* Create an L0 block descriptor. */
+/* Create an L0 block descriptor */
 #define GPT_L0_BLK_DESC(_gpi)	(GPT_L0_TYPE_BLK_DESC | \
 				(((_gpi) & GPT_L0_BLK_DESC_GPI_MASK) << \
 				GPT_L0_BLK_DESC_GPI_SHIFT))
 
-/* Create an L0 table descriptor with an L1 table address. */
+/* Create an L0 table descriptor with an L1 table address */
 #define GPT_L0_TBL_DESC(_pa)	(GPT_L0_TYPE_TBL_DESC | ((uint64_t)(_pa) & \
 				(GPT_L0_TBL_DESC_L1ADDR_MASK << \
 				GPT_L0_TBL_DESC_L1ADDR_SHIFT)))
 
-/* Get the GPI from an L0 block descriptor. */
+/* Get the GPI from an L0 block descriptor */
 #define GPT_L0_BLKD_GPI(_desc)	(((_desc) >> GPT_L0_BLK_DESC_GPI_SHIFT) & \
 				GPT_L0_BLK_DESC_GPI_MASK)
 
-/* Get the L1 address from an L0 table descriptor. */
+/* Get the L1 address from an L0 table descriptor */
 #define GPT_L0_TBLD_ADDR(_desc)	((uint64_t *)(((_desc) & \
 				(GPT_L0_TBL_DESC_L1ADDR_MASK << \
 				GPT_L0_TBL_DESC_L1ADDR_SHIFT))))
 
+/* Get the GPI from L1 Contiguous descriptor */
+#define GPT_L1_CONT_GPI(_desc)		\
+	(((_desc) >> GPT_L1_CONT_DESC_GPI_SHIFT) & GPT_L1_CONT_DESC_GPI_MASK)
+
-/* Get the index into the L1 table from a physical address. */
-#define GPT_L1_IDX(_p, _pa)	(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & \
-				GPT_L1_IDX_MASK(_p))
+/* Get the GPI from L1 Granules descriptor */
+#define GPT_L1_GRAN_GPI(_desc)	((_desc) & GPT_L1_GRAN_DESC_GPI_MASK)
 
-/* Get the index of the GPI within an L1 table entry from a physical address. */
-#define GPT_L1_GPI_IDX(_p, _pa)	(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & \
-				GPT_L1_GPI_IDX_MASK)
+/* Get the Contig from L1 Contiguous descriptor */
+#define GPT_L1_CONT_CONTIG(_desc)	\
+	(((_desc) >> GPT_L1_CONT_DESC_CONTIG_SHIFT) & \
+					GPT_L1_CONT_DESC_CONTIG_MASK)
+
+/* Get the index into the L1 table from a physical address */
+#define GPT_L1_IDX(_p, _pa)		\
+	(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & GPT_L1_IDX_MASK(_p))
+
+/* Get the index of the GPI within an L1 table entry from a physical address */
+#define GPT_L1_GPI_IDX(_p, _pa)		\
+	(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & GPT_L1_GPI_IDX_MASK)
+
+/* Determine if an address is granule-aligned */
+#define GPT_IS_L1_ALIGNED(_p, _pa)	\
+	(((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - UL(1))) == UL(0))
+
+/* Get aligned addresses */
+#define ALIGN_2MB(_addr)	((_addr) & ~(SZ_2M - 1UL))
+#define ALIGN_32MB(_addr)	((_addr) & ~(SZ_32M - 1UL))
+#define ALIGN_512MB(_addr)	((_addr) & ~(SZ_512M - 1UL))
+
+/* Determine if region is contiguous */
+#define GPT_REGION_IS_CONT(_len, _addr, _size)	\
+	(((_len) >= (_size)) && (((_addr) & ((_size) - UL(1))) == UL(0)))
+
+/* Get 32MB block number in 512MB block: 0-15 */
+#define GET_32MB_NUM(_addr)	((_addr >> 25) & 0xF)
 
-/* Determine if an address is granule-aligned. */
-#define GPT_IS_L1_ALIGNED(_p, _pa) (((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - U(1))) \
-				   == U(0))
+/* Get 2MB block number in 32MB block: 0-15 */
+#define GET_2MB_NUM(_addr)	((_addr >> 21) & 0xF)
 
 #endif /* GPT_RME_PRIVATE_H */
diff --git a/lib/libfdt/libfdt.mk b/lib/libfdt/libfdt.mk
index 812057d..c7f5404 100644
--- a/lib/libfdt/libfdt.mk
+++ b/lib/libfdt/libfdt.mk
@@ -1,19 +1,23 @@
 #
-# Copyright (c) 2016, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-LIBFDT_SRCS	:=	$(addprefix lib/libfdt/,	\
-			fdt.c				\
-			fdt_addresses.c			\
-			fdt_empty_tree.c		\
-			fdt_ro.c			\
-			fdt_rw.c			\
-			fdt_strerror.c			\
-			fdt_sw.c			\
-			fdt_wip.c)			\
+ifndef libfdt-mk
+        libfdt-mk := 1
 
-INCLUDES	+=	-Iinclude/lib/libfdt
+        LIBFDT_SRCS := $(addprefix lib/libfdt/, \
+                fdt.c \
+                fdt_addresses.c \
+                fdt_empty_tree.c \
+                fdt_ro.c \
+                fdt_rw.c \
+                fdt_strerror.c \
+                fdt_sw.c \
+                fdt_wip.c)
+
+        INCLUDES += -Iinclude/lib/libfdt
 
-$(eval $(call MAKE_LIB,fdt))
+        $(eval $(call MAKE_LIB,fdt))
+endif
diff --git a/lib/locks/exclusive/aarch64/spinlock.S b/lib/locks/exclusive/aarch64/spinlock.S
index 5144bf7..77bb7fe 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 
 	.globl	spin_lock
 	.globl	spin_unlock
+	.globl	bit_lock
+	.globl	bit_unlock
 
 #if USE_SPINLOCK_CAS
 #if !ARM_ARCH_AT_LEAST(8, 1)
@@ -73,3 +75,43 @@
 	stlr	wzr, [x0]
 	ret
 endfunc spin_unlock
+
+/*
+ * Atomic bit clear and set instructions require FEAT_LSE which is
+ * mandatory from Armv8.1.
+ */
+#if ARM_ARCH_AT_LEAST(8, 1)
+
+/*
+ * Acquire bitlock using atomic bit set on byte. If the original read value
+ * has the bit set, use load exclusive semantics to monitor the address and
+ * enter WFE.
+ *
+ * void bit_lock(bitlock_t *lock, uint8_t mask);
+ */
+func bit_lock
+1:	ldsetab	w1, w2, [x0]
+	tst	w2, w1
+	b.eq	2f
+	ldxrb	w2, [x0]
+	tst	w2, w1
+	b.eq	1b
+	wfe
+	b	1b
+2:
+	ret
+endfunc bit_lock
+
+/*
+ * Use atomic bit clear store-release to unconditionally clear bitlock variable.
+ * Store operation generates an event to all cores waiting in WFE when address
+ * is monitored by the global monitor.
+ *
+ * void bit_unlock(bitlock_t *lock, uint8_t mask);
+ */
+func bit_unlock
+	stclrlb	w1, [x0]
+	ret
+endfunc bit_unlock
+
+#endif /* ARM_ARCH_AT_LEAST(8, 1) */
diff --git a/lib/pmf/pmf_smc.c b/lib/pmf/pmf_smc.c
index f3dd112..ac7f53a 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,8 @@
 		x2 = (uint32_t)x2;
 		x3 = (uint32_t)x3;
 
-		if (smc_fid == PMF_SMC_GET_TIMESTAMP_32) {
+		if (smc_fid == PMF_SMC_GET_TIMESTAMP_32 ||
+		   smc_fid == PMF_SMC_GET_TIMESTAMP_32_DEP) {
 			/*
 			 * Return error code and the captured
 			 * time-stamp to the caller.
@@ -48,8 +49,13 @@
 			SMC_RET3(handle, rc, (uint32_t)ts_value,
 					(uint32_t)(ts_value >> 32));
 		}
+
+		if (smc_fid == PMF_SMC_GET_VERSION_32) {
+			SMC_RET2(handle, SMC_OK, PMF_SMC_VERSION);
+		}
 	} else {
-		if (smc_fid == PMF_SMC_GET_TIMESTAMP_64) {
+		if (smc_fid == PMF_SMC_GET_TIMESTAMP_64 ||
+		    smc_fid == PMF_SMC_GET_TIMESTAMP_64_DEP) {
 			/*
 			 * Return error code and the captured
 			 * time-stamp to the caller.
@@ -60,6 +66,10 @@
 					(unsigned int)x3, &ts_value);
 			SMC_RET2(handle, rc, ts_value);
 		}
+
+		if (smc_fid == PMF_SMC_GET_VERSION_64) {
+			SMC_RET2(handle, SMC_OK, PMF_SMC_VERSION);
+		}
 	}
 
 	WARN("Unimplemented PMF Call: 0x%x \n", smc_fid);
diff --git a/lib/psa/cca_attestation.c b/lib/psa/cca_attestation.c
new file mode 100644
index 0000000..9e9e0c1
--- /dev/null
+++ b/lib/psa/cca_attestation.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <psa/crypto_sizes.h>
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <cca_attestation.h>
+#include <delegated_attestation.h>
+#include <services/rmmd_svc.h>
+
+psa_status_t
+cca_attestation_get_realm_key(uintptr_t buf, size_t *len, unsigned int type)
+{
+	size_t dak_len;
+	psa_status_t ret = PSA_SUCCESS;
+
+	/*
+	 * Current RMM implementations only support the public key size for
+	 * ECC-P384, i.e. ATTEST_KEY_CURVE_ECC_SECP384R1 attestation key.
+	 *
+	 * This ECC key has following properties:
+	 * ecc_curve:	0x12 (PSA_ECC_FAMILY_SECP_R1)
+	 * key_bits:	384
+	 * hash_alg:	0x02000009 (PSA_ALG_SHA_256)
+	 */
+	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
+
+	ret = rse_delegated_attest_get_delegated_key(PSA_ECC_FAMILY_SECP_R1,
+						     384, (uint8_t *)buf, *len,
+						     &dak_len, PSA_ALG_SHA_256);
+	if (ret != PSA_SUCCESS) {
+		return ret;
+	}
+
+	if (dak_len != PSA_BITS_TO_BYTES(384)) {
+		return PSA_ERROR_INVALID_ARGUMENT;
+	}
+
+	*len = dak_len;
+
+	return ret;
+}
+
+psa_status_t
+cca_attestation_get_plat_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size)
+{
+	size_t token_len = 0;
+	psa_status_t ret = PSA_SUCCESS;
+
+	ret = rse_delegated_attest_get_token((const uint8_t *)hash, hash_size,
+					     (uint8_t *)buf, *len, &token_len);
+	if (ret != PSA_SUCCESS) {
+		return ret;
+	}
+
+	*len = token_len;
+
+	return ret;
+}
diff --git a/lib/psa/delegated_attestation.c b/lib/psa/delegated_attestation.c
index 81e2621..805a941 100644
--- a/lib/psa/delegated_attestation.c
+++ b/lib/psa/delegated_attestation.c
@@ -10,7 +10,7 @@
 #include <psa_manifest/sid.h>
 
 psa_status_t
-rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+rse_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 				       uint32_t  key_bits,
 				       uint8_t  *key_buf,
 				       size_t    key_buf_size,
@@ -31,8 +31,8 @@
 		return PSA_ERROR_INVALID_ARGUMENT;
 	}
 
-	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
-			  RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY,
+	status = psa_call(RSE_DELEGATED_SERVICE_HANDLE,
+			  RSE_DELEGATED_ATTEST_GET_DELEGATED_KEY,
 			  in_vec,  IOVEC_LEN(in_vec),
 			  out_vec, IOVEC_LEN(out_vec));
 	if (status == PSA_SUCCESS) {
@@ -43,7 +43,7 @@
 }
 
 psa_status_t
-rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+rse_delegated_attest_get_token(const uint8_t *dak_pub_hash,
 			       size_t         dak_pub_hash_size,
 			       uint8_t       *token_buf,
 			       size_t         token_buf_size,
@@ -61,8 +61,8 @@
 		return PSA_ERROR_INVALID_ARGUMENT;
 	}
 
-	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
-			  RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN,
+	status = psa_call(RSE_DELEGATED_SERVICE_HANDLE,
+			  RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN,
 			  in_vec, IOVEC_LEN(in_vec),
 			  out_vec, IOVEC_LEN(out_vec));
 	if (status == PSA_SUCCESS) {
diff --git a/lib/psa/dice_protection_environment.c b/lib/psa/dice_protection_environment.c
new file mode 100644
index 0000000..2145611
--- /dev/null
+++ b/lib/psa/dice_protection_environment.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <qcbor/qcbor_decode.h>
+#include <qcbor/qcbor_encode.h>
+#include <qcbor/qcbor_spiffy_decode.h>
+
+#include <common/debug.h>
+#include <dice.h>
+#include <dice_protection_environment.h>
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+
+enum dpe_command_id_t {
+	/* Standard commands */
+	DPE_GET_PROFILE = 1,
+	DPE_OPEN_SESSION = 2,
+	DPE_CLOSE_SESSION = 3,
+	DPE_SYNC_SESSION = 4,
+	DPE_EXPORT_SESSION = 5,
+	DPE_IMPORT_SESSION = 6,
+	DPE_INITIALIZE_CONTEXT = 7,
+	DPE_DERIVE_CONTEXT = 8,
+	DPE_CERTIFY_KEY = 9,
+	DPE_SIGN = 10,
+	DPE_SEAL = 11,
+	DPE_UNSEAL = 12,
+	DPE_DERIVE_SEALING_PUBLIC_KEY = 13,
+	DPE_ROTATE_CONTEXT_HANDLE = 14,
+	DPE_DESTROY_CONTEXT = 15,
+};
+
+enum dice_input_labels_t {
+	DICE_CODE_HASH = 1,
+	DICE_CODE_DESCRIPTOR = 2,
+	DICE_CONFIG_TYPE = 3,
+	DICE_CONFIG_VALUE = 4,
+	DICE_CONFIG_DESCRIPTOR = 5,
+	DICE_AUTHORITY_HASH = 6,
+	DICE_AUTHORITY_DESCRIPTOR = 7,
+	DICE_MODE = 8,
+	DICE_HIDDEN = 9,
+};
+
+enum dpe_derive_context_input_labels_t {
+	DPE_DERIVE_CONTEXT_CONTEXT_HANDLE = 1,
+	DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT = 2,
+	DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE = 3,
+	DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE = 4,
+	DPE_DERIVE_CONTEXT_NEW_SESSION_INITIATOR_HANDSHAKE = 5,
+	DPE_DERIVE_CONTEXT_INPUT_DATA = 6,
+	DPE_DERIVE_CONTEXT_INTERNAL_INPUTS = 7,
+	DPE_DERIVE_CONTEXT_TARGET_LOCALITY = 8,
+	DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE = 9,
+	DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT = 10,
+	DPE_DERIVE_CONTEXT_EXPORT_CDI = 11,
+	/* enum values 256 and onwards are reserved for custom arguments */
+	DPE_DERIVE_CONTEXT_CERT_ID = 256,
+};
+
+enum dpe_derive_context_output_labels_t {
+	DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE = 1,
+	DPE_DERIVE_CONTEXT_NEW_SESSION_RESPONDER_HANDSHAKE = 2,
+	DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE = 3,
+	DPE_DERIVE_CONTEXT_NEW_CERTIFICATE = 4,
+	DPE_DERIVE_CONTEXT_EXPORTED_CDI = 5,
+};
+
+struct derive_context_input_t {
+	int context_handle;
+	uint32_t cert_id;
+	bool retain_parent_context;
+	bool allow_new_context_to_derive;
+	bool create_certificate;
+	const DiceInputValues *dice_inputs;
+	int32_t target_locality;
+	bool return_certificate;
+	bool allow_new_context_to_export;
+	bool export_cdi;
+};
+
+struct derive_context_output_t {
+	int new_context_handle;
+	int new_parent_context_handle;
+	const uint8_t *new_certificate;
+	size_t new_certificate_size;
+	const uint8_t *exported_cdi;
+	size_t exported_cdi_size;
+};
+
+static void encode_dice_inputs(QCBOREncodeContext *encode_ctx,
+			       const DiceInputValues *input)
+{
+	/* Wrap the DICE inputs into a byte string */
+	QCBOREncode_BstrWrapInMapN(encode_ctx, DPE_DERIVE_CONTEXT_INPUT_DATA);
+
+	/* Inside the byte string the DICE inputs are encoded as a map */
+	QCBOREncode_OpenMap(encode_ctx);
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_HASH,
+				  (UsefulBufC) { input->code_hash,
+						 sizeof(input->code_hash) });
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_DESCRIPTOR,
+				   (UsefulBufC) { input->code_descriptor,
+						  input->code_descriptor_size });
+
+	QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_CONFIG_TYPE,
+				   input->config_type);
+
+	if (input->config_type == kDiceConfigTypeInline) {
+		QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_VALUE,
+					   (UsefulBufC) { input->config_value,
+							  sizeof(input->config_value) });
+	} else {
+		QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_DESCRIPTOR,
+					   (UsefulBufC) { input->config_descriptor,
+							  input->config_descriptor_size });
+	}
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_HASH,
+				   (UsefulBufC) { input->authority_hash,
+						  sizeof(input->authority_hash) });
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_DESCRIPTOR,
+				   (UsefulBufC) { input->authority_descriptor,
+						  input->authority_descriptor_size });
+
+	QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_MODE, input->mode);
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_HIDDEN,
+				   (UsefulBufC) { input->hidden,
+						  sizeof(input->hidden) });
+
+	QCBOREncode_CloseMap(encode_ctx);
+	QCBOREncode_CloseBstrWrap2(encode_ctx, true, NULL);
+}
+
+static QCBORError encode_derive_context(const struct derive_context_input_t *args,
+					UsefulBuf buf,
+					UsefulBufC *encoded_buf)
+{
+	QCBOREncodeContext encode_ctx;
+
+	QCBOREncode_Init(&encode_ctx, buf);
+
+	QCBOREncode_OpenArray(&encode_ctx);
+	QCBOREncode_AddUInt64(&encode_ctx, DPE_DERIVE_CONTEXT);
+
+	/* Encode DeriveContext command */
+	QCBOREncode_OpenMap(&encode_ctx);
+	QCBOREncode_AddBytesToMapN(&encode_ctx,
+				   DPE_DERIVE_CONTEXT_CONTEXT_HANDLE,
+				   (UsefulBufC) { &args->context_handle,
+						  sizeof(args->context_handle) });
+	QCBOREncode_AddUInt64ToMapN(&encode_ctx,
+				    DPE_DERIVE_CONTEXT_CERT_ID,
+				    args->cert_id);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT,
+				  args->retain_parent_context);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE,
+				  args->allow_new_context_to_derive);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE,
+				  args->create_certificate);
+	encode_dice_inputs(&encode_ctx, args->dice_inputs);
+	QCBOREncode_AddBytesToMapN(&encode_ctx,
+				   DPE_DERIVE_CONTEXT_TARGET_LOCALITY,
+				   (UsefulBufC) { &args->target_locality,
+						  sizeof(args->target_locality) });
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE,
+				  args->return_certificate);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT,
+				  args->allow_new_context_to_export);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_EXPORT_CDI,
+				  args->export_cdi);
+	QCBOREncode_CloseMap(&encode_ctx);
+
+	QCBOREncode_CloseArray(&encode_ctx);
+
+	return QCBOREncode_Finish(&encode_ctx, encoded_buf);
+}
+
+static QCBORError decode_derive_context_response(UsefulBufC encoded_buf,
+						 struct derive_context_output_t *args,
+						 dpe_error_t *dpe_err)
+{
+	QCBORDecodeContext decode_ctx;
+	UsefulBufC out;
+	int64_t response_dpe_err;
+
+	QCBORDecode_Init(&decode_ctx, encoded_buf, QCBOR_DECODE_MODE_NORMAL);
+
+	QCBORDecode_EnterArray(&decode_ctx, NULL);
+
+	/* Get the error code from the response. DPE returns int32_t */
+	QCBORDecode_GetInt64(&decode_ctx, &response_dpe_err);
+	*dpe_err = (dpe_error_t)response_dpe_err;
+
+	/* Decode DeriveContext response if successful */
+	if (*dpe_err == DPE_NO_ERROR) {
+		QCBORDecode_EnterMap(&decode_ctx, NULL);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE,
+						&out);
+		if (out.len != sizeof(args->new_context_handle)) {
+			return QCBORDecode_Finish(&decode_ctx);
+		}
+		memcpy(&args->new_context_handle, out.ptr, out.len);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE,
+						&out);
+		if (out.len != sizeof(args->new_parent_context_handle)) {
+			return QCBORDecode_Finish(&decode_ctx);
+		}
+		memcpy(&args->new_parent_context_handle, out.ptr, out.len);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_NEW_CERTIFICATE,
+						&out);
+		args->new_certificate = out.ptr;
+		args->new_certificate_size = out.len;
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_EXPORTED_CDI,
+						&out);
+		args->exported_cdi = out.ptr;
+		args->exported_cdi_size = out.len;
+
+		QCBORDecode_ExitMap(&decode_ctx);
+	}
+
+	QCBORDecode_ExitArray(&decode_ctx);
+
+	return QCBORDecode_Finish(&decode_ctx);
+}
+
+static int32_t dpe_client_call(const char *cmd_input, size_t cmd_input_size,
+			       char *cmd_output, size_t *cmd_output_size)
+{
+	int32_t err;
+
+	psa_invec in_vec[] = {
+		{ cmd_input, cmd_input_size },
+	};
+	psa_outvec out_vec[] = {
+		{ cmd_output, *cmd_output_size },
+	};
+
+	err = psa_call(RSE_DPE_SERVICE_HANDLE, 0,
+			in_vec, IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+	if (err == PSA_SUCCESS) {
+		*cmd_output_size = out_vec[0].len;
+	}
+
+	return err;
+}
+
+dpe_error_t dpe_derive_context(int context_handle,
+			       uint32_t cert_id,
+			       bool retain_parent_context,
+			       bool allow_new_context_to_derive,
+			       bool create_certificate,
+			       const DiceInputValues *dice_inputs,
+			       int32_t target_locality,
+			       bool return_certificate,
+			       bool allow_new_context_to_export,
+			       bool export_cdi,
+			       int *new_context_handle,
+			       int *new_parent_context_handle,
+			       uint8_t *new_certificate_buf,
+			       size_t new_certificate_buf_size,
+			       size_t *new_certificate_actual_size,
+			       uint8_t *exported_cdi_buf,
+			       size_t exported_cdi_buf_size,
+			       size_t *exported_cdi_actual_size)
+{
+	int32_t service_err;
+	dpe_error_t dpe_err;
+	QCBORError qcbor_err;
+	UsefulBufC encoded_buf;
+	UsefulBuf_MAKE_STACK_UB(cmd_buf, 612);
+
+	const struct derive_context_input_t in_args = {
+		context_handle,
+		cert_id,
+		retain_parent_context,
+		allow_new_context_to_derive,
+		create_certificate,
+		dice_inputs,
+		target_locality,
+		return_certificate,
+		allow_new_context_to_export,
+		export_cdi,
+	};
+	struct derive_context_output_t out_args;
+
+	/*
+	 * Validate the output params here because they are not sent to the
+	 * service. Input params are validated by the DPE service.
+	 */
+	if ((new_context_handle == NULL) ||
+	    (retain_parent_context == true && new_parent_context_handle == NULL) ||
+	    (return_certificate == true &&
+		(new_certificate_buf == NULL || new_certificate_actual_size == NULL)) ||
+	    (export_cdi == true &&
+		(exported_cdi_buf == NULL || exported_cdi_actual_size == NULL))) {
+		return DPE_INVALID_ARGUMENT;
+	}
+
+	qcbor_err = encode_derive_context(&in_args, cmd_buf, &encoded_buf);
+	if (qcbor_err != QCBOR_SUCCESS) {
+		return DPE_INTERNAL_ERROR;
+	}
+
+	service_err = dpe_client_call(encoded_buf.ptr, encoded_buf.len,
+				      cmd_buf.ptr, &cmd_buf.len);
+	if (service_err != 0) {
+		return DPE_INTERNAL_ERROR;
+	}
+
+	qcbor_err = decode_derive_context_response(UsefulBuf_Const(cmd_buf),
+						   &out_args, &dpe_err);
+	if (qcbor_err != QCBOR_SUCCESS) {
+		return DPE_INTERNAL_ERROR;
+	} else if (dpe_err != DPE_NO_ERROR) {
+		return dpe_err;
+	}
+
+	/* Copy returned values into caller's memory */
+	*new_context_handle = out_args.new_context_handle;
+
+	if (retain_parent_context == true) {
+		*new_parent_context_handle = out_args.new_parent_context_handle;
+	}
+
+	if (return_certificate == true) {
+		if (out_args.new_certificate_size > new_certificate_buf_size) {
+			return DPE_INVALID_ARGUMENT;
+		}
+
+		memcpy(new_certificate_buf, out_args.new_certificate,
+			out_args.new_certificate_size);
+		*new_certificate_actual_size = out_args.new_certificate_size;
+	}
+
+	if (export_cdi == true) {
+		if (out_args.exported_cdi_size > exported_cdi_buf_size) {
+			return DPE_INVALID_ARGUMENT;
+		}
+
+		memcpy(exported_cdi_buf, out_args.exported_cdi,
+			out_args.exported_cdi_size);
+		*exported_cdi_actual_size = out_args.exported_cdi_size;
+	}
+
+	return DPE_NO_ERROR;
+}
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 38990b5..c66b8da 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include <common/debug.h>
+#include <drivers/measured_boot/metadata.h>
 #include <measured_boot.h>
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
@@ -62,7 +63,7 @@
 }
 
 psa_status_t
-rss_measured_boot_extend_measurement(uint8_t index,
+rse_measured_boot_extend_measurement(uint8_t index,
 				     const uint8_t *signer_id,
 				     size_t signer_id_size,
 				     const uint8_t *version,
@@ -114,13 +115,13 @@
 			measurement_algo, measurement_value,
 			measurement_value_size, lock_measurement);
 
-	return psa_call(RSS_MEASURED_BOOT_HANDLE,
-			RSS_MEASURED_BOOT_EXTEND,
+	return psa_call(RSE_MEASURED_BOOT_HANDLE,
+			RSE_MEASURED_BOOT_EXTEND,
 			in_vec, IOVEC_LEN(in_vec),
 			NULL, 0);
 }
 
-psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+psa_status_t rse_measured_boot_read_measurement(uint8_t index,
 					uint8_t *signer_id,
 					size_t signer_id_size,
 					size_t *signer_id_len,
@@ -157,7 +158,7 @@
 		{.base = measurement_value, .len = measurement_value_size}
 	};
 
-	status = psa_call(RSS_MEASURED_BOOT_HANDLE, RSS_MEASURED_BOOT_READ,
+	status = psa_call(RSE_MEASURED_BOOT_HANDLE, RSE_MEASURED_BOOT_READ,
 					  in_vec, IOVEC_LEN(in_vec),
 					  out_vec, IOVEC_LEN(out_vec));
 
diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h
index 80d2c19..bf2ae48 100644
--- a/lib/psa/measured_boot_private.h
+++ b/lib/psa/measured_boot_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -10,9 +10,11 @@
 
 #include <stdint.h>
 
+#include <drivers/measured_boot/metadata.h>
+
 /* Measured boot message types that distinguish its services */
-#define RSS_MEASURED_BOOT_READ		1001U
-#define RSS_MEASURED_BOOT_EXTEND	1002U
+#define RSE_MEASURED_BOOT_READ		1001U
+#define RSE_MEASURED_BOOT_EXTEND	1002U
 
 struct measured_boot_read_iovec_in_t {
     uint8_t index;
diff --git a/lib/psa/rse_platform.c b/lib/psa/rse_platform.c
new file mode 100644
index 0000000..7fc2382
--- /dev/null
+++ b/lib/psa/rse_platform.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+#include <rse_crypto_defs.h>
+#include <rse_platform_api.h>
+
+psa_status_t
+rse_platform_nv_counter_increment(uint32_t counter_id)
+{
+	struct psa_invec in_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	return psa_call(RSE_PLATFORM_SERVICE_HANDLE,
+			RSE_PLATFORM_API_ID_NV_INCREMENT,
+			in_vec, 1, NULL, 0);
+}
+
+psa_status_t
+rse_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val)
+{
+	struct psa_invec in_vec[1];
+	struct psa_outvec out_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	out_vec[0].base = val;
+	out_vec[0].len = size;
+
+	return psa_call(RSE_PLATFORM_SERVICE_HANDLE,
+			RSE_PLATFORM_API_ID_NV_READ,
+			in_vec, 1, out_vec, 1);
+}
+
+psa_status_t
+rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data,
+		size_t data_size, size_t *data_length)
+{
+	psa_status_t status;
+
+	struct rse_crypto_pack_iovec iov = {
+		.function_id = RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID,
+		.key_id = key,
+	};
+
+	psa_invec in_vec[] = {
+		{.base = &iov, .len = sizeof(struct rse_crypto_pack_iovec)},
+	};
+	psa_outvec out_vec[] = {
+		{.base = data, .len = data_size}
+	};
+
+	status = psa_call(RSE_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/psa/rss_platform.c b/lib/psa/rss_platform.c
deleted file mode 100644
index 7d90bfc..0000000
--- a/lib/psa/rss_platform.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include <psa/client.h>
-#include <psa_manifest/sid.h>
-#include <rss_crypto_defs.h>
-#include <rss_platform_api.h>
-
-psa_status_t
-rss_platform_nv_counter_increment(uint32_t counter_id)
-{
-	struct psa_invec in_vec[1];
-
-	in_vec[0].base = &counter_id;
-	in_vec[0].len = sizeof(counter_id);
-
-	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
-			RSS_PLATFORM_API_ID_NV_INCREMENT,
-			in_vec, 1, NULL, 0);
-}
-
-psa_status_t
-rss_platform_nv_counter_read(uint32_t counter_id,
-		uint32_t size, uint8_t *val)
-{
-	struct psa_invec in_vec[1];
-	struct psa_outvec out_vec[1];
-
-	in_vec[0].base = &counter_id;
-	in_vec[0].len = sizeof(counter_id);
-
-	out_vec[0].base = val;
-	out_vec[0].len = size;
-
-	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
-			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/psci_common.c b/lib/psci/psci_common.c
index 41c7919..60449f6 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -172,7 +172,8 @@
  ******************************************************************************/
 static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int end_pwrlvl)
 {
-	unsigned int my_idx, lvl, parent_idx;
+	unsigned int my_idx, lvl;
+	unsigned int parent_idx = 0;
 	unsigned int cpu_start_idx, ncpus, cpu_idx;
 	plat_local_state_t local_state;
 
@@ -664,6 +665,8 @@
 			}
 			goto exit;
 		}
+
+		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
 
 	/*
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index f11e577..9ade331 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -4,8 +4,13 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := aarch64
+ifeq ($(filter-out clean,$(or $(MAKECMDGOALS),all)),)
+        toolchains :=
+else
+        toolchains := aarch64
+endif
 
+include ../../make_helpers/common.mk
 include ../../make_helpers/toolchain.mk
 
 ROMLIB_GEN  = ./romlib_generator.py
@@ -19,20 +24,16 @@
 MAPFILE     = $(BUILD_PLAT)/romlib/romlib.map
 
 ifneq ($(PLAT_DIR),)
-  WRAPPER_SOURCES   = $(shell $(ROMLIB_GEN) genwrappers -b $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i)
-  WRAPPER_OBJS      = $(WRAPPER_SOURCES:.s=.o)
-endif
+        WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+                $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
 
-V ?= 0
-ifeq ($(V),0)
-  Q := @
-else
-  Q :=
+        WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
 endif
 
-LDFLAGS := --gc-sections -O1
+LDFLAGS := -Wl,--gc-sections -nostdlib
+
 ifeq ($(DEBUG),1)
-   LDFLAGS += -Map=$(MAPFILE)
+   LDFLAGS += -Wl,-Map=$(MAPFILE)
 endif
 
 ifeq (${ARM_ARCH_MINOR},0)
@@ -46,52 +47,49 @@
 all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a
 
 %.o: %.s
-	@echo "  AS      $@"
-	$(Q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
+	$(s)echo "  AS      $@"
+	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
 $(BUILD_DIR)/%.o: %.s
-	@echo "  AS      $@"
-	$(Q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
+	$(s)echo "  AS      $@"
+	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
 $(BUILD_DIR)/romlib.ld: romlib.ld.S
-	@echo "  PP      $@"
-	$(Q)$(aarch64-cpp) -E $(PPFLAGS) -o $@ romlib.ld.S
+	$(s)echo "  PP      $@"
+	$(q)$(aarch64-cpp) -E $(PPFLAGS) -o $@ romlib.ld.S
 
 $(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld
-	@echo "  LD      $@"
-	$(Q)$(aarch64-ld) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+	$(s)echo "  LD      $@"
+	$(q)$(aarch64-ld) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
 
 $(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf
-	@echo "  BIN     $@"
-	$(Q)$(aarch64-oc) -O binary $(BUILD_DIR)/romlib.elf $@
+	$(s)echo "  BIN     $@"
+	$(q)$(aarch64-oc) -O binary $(BUILD_DIR)/romlib.elf $@
 
 $(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf
-	@echo "  VAR     $@"
-	$(Q)$(ROMLIB_GEN) genvar --output $@ $<
+	$(s)echo "  VAR     $@"
+	$(q)$(ROMLIB_GEN) genvar --output $@ $<
 
 $(LIB_DIR)/libwrappers.a: $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
-	@echo "  AR      $@"
-	$(Q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
+	$(s)echo "  AR      $@"
+	$(q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
 
 $(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i
-	@echo "  PRE     $@"
-	$(Q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
+	$(s)echo "  PRE     $@"
+	$(q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
 
-$(BUILD_DIR)/wrappers.stamp: $(BUILD_DIR)/jmptbl.i
-	@echo "  WRP     $<"
-	$(Q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
-	@touch $@
+$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i
+	$(s)echo "  WRP     $<"
+	$(q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
 
-$(WRAPPER_SOURCES): $(BUILD_DIR)/wrappers.stamp
-
-$(WRAPPER_OBJS): $(WRAPPER_SOURCES) $(BUILD_DIR)/wrappers.stamp
+$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s
 
 $(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i
-	@echo "  TBL     $@"
-	$(Q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
+	$(s)echo "  TBL     $@"
+	$(q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
 
 clean:
-	@rm -f $(BUILD_DIR)/*
+	$(q)rm -f $(BUILD_DIR)/*
 
 -include $(BUILD_DIR)/romlib.d
 -include $(BUILD_DIR)/jmptbl.d
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index 63969e9..b7fedfa 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -366,7 +366,6 @@
 		/* create a dummy TE to fill up the gap */
 		dummy_te = (struct transfer_list_entry *)new_ev;
 		dummy_te->tag_id = TL_TAG_EMPTY;
-		dummy_te->reserved0 = 0;
 		dummy_te->hdr_size = sizeof(*dummy_te);
 		dummy_te->data_size = gap - sizeof(*dummy_te);
 	}
@@ -388,7 +387,6 @@
 		return false;
 	}
 	te->tag_id = TL_TAG_EMPTY;
-	te->reserved0 = 0;
 	transfer_list_update_checksum(tl);
 	return true;
 }
@@ -399,7 +397,7 @@
  * Return pointer to the added transfer entry or NULL on error
  ******************************************************************************/
 struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
-					      uint16_t tag_id,
+					      uint32_t tag_id,
 					      uint32_t data_size,
 					      const void *data)
 {
@@ -428,7 +426,6 @@
 
 	te = (struct transfer_list_entry *)tl_ev;
 	te->tag_id = tag_id;
-	te->reserved0 = 0;
 	te->hdr_size = sizeof(*te);
 	te->data_size = data_size;
 	tl->size += ev - tl_ev;
@@ -454,7 +451,7 @@
  * Return pointer to the added transfer entry or NULL on error
  ******************************************************************************/
 struct transfer_list_entry *
-transfer_list_add_with_align(struct transfer_list_header *tl, uint16_t tag_id,
+transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
 			     uint32_t data_size, const void *data,
 			     uint8_t alignment)
 {
@@ -501,13 +498,13 @@
  * Return pointer to the found transfer entry or NULL on error
  ******************************************************************************/
 struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
-					       uint16_t tag_id)
+					       uint32_t tag_id)
 {
 	struct transfer_list_entry *te = NULL;
 
 	do {
 		te = transfer_list_next(tl, te);
-	} while (te && (te->tag_id != tag_id || te->reserved0 != 0));
+	} while (te && (te->tag_id != tag_id));
 
 	return te;
 }
diff --git a/lib/transfer_list/transfer_list.mk b/lib/transfer_list/transfer_list.mk
index 42574e8..3ec4df2 100644
--- a/lib/transfer_list/transfer_list.mk
+++ b/lib/transfer_list/transfer_list.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,6 +15,7 @@
 
 BL31_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
 BL2_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
+BL1_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
 
 endif	# TRANSFER_LIST
 
diff --git a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
index 5a2120b..b462de0 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@
 {
 	uintptr_t ret;
 
-	if (is_armv8_4_ttst_present()) {
+	if (is_feat_ttst_present()) {
 		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
 	} else {
 		ret = MIN_VIRT_ADDR_SPACE_SIZE;
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 4dbfc11..f4195f4 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -87,7 +87,7 @@
 {
 	uintptr_t ret;
 
-	if (is_armv8_4_ttst_present())
+	if (is_feat_ttst_present())
 		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
 	else
 		ret = MIN_VIRT_ADDR_SPACE_SIZE;
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 920754b..b63543c 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-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -248,7 +248,7 @@
 	/* Set TTBR0 bits as well */
 	ttbr0 = (uint64_t)(uintptr_t) base_table;
 
-	if (is_armv8_2_ttcnp_present()) {
+	if (is_feat_ttcnp_present()) {
 		/* Enable CnP bit so as to share page tables with all PEs. */
 		ttbr0 |= TTBR_CNP_BIT;
 	}
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index bb6a35c..18e001b 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,19 +22,14 @@
  */
 bool xlat_arch_is_granule_size_supported(size_t size)
 {
-	unsigned int tgranx;
-
 	if (size == PAGE_SIZE_4KB) {
-		tgranx = read_id_aa64mmfr0_el0_tgran4_field();
 		/* MSB of TGRAN4 field will be '1' for unsupported feature */
-		return (tgranx < 8U);
+		return is_feat_tgran4K_present();
 	} else if (size == PAGE_SIZE_16KB) {
-		tgranx = read_id_aa64mmfr0_el0_tgran16_field();
-		return (tgranx >= ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED);
+		return is_feat_tgran16K_present();
 	} 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 < 8U);
+		return is_feat_tgran64K_present();
 	} else {
 		return false;
 	}
@@ -135,7 +130,7 @@
 {
 	uintptr_t ret;
 
-	if (is_armv8_4_ttst_present())
+	if (is_feat_ttst_present())
 		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
 	else
 		ret = MIN_VIRT_ADDR_SPACE_SIZE;
@@ -312,7 +307,7 @@
 	/* Set TTBR bits as well */
 	ttbr0 = (uint64_t) base_table;
 
-	if (is_armv8_2_ttcnp_present()) {
+	if (is_feat_ttcnp_present()) {
 		/* Enable CnP bit so as to share page tables with all PEs. */
 		ttbr0 |= TTBR_CNP_BIT;
 	}
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index 3a9c058..971dba4 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -214,7 +214,7 @@
 			/* Set GP bit for block and page code entries
 			 * if BTI mechanism is implemented.
 			 */
-			if (is_armv8_5_bti_present() &&
+			if (is_feat_bti_present() &&
 			   ((attr & (MT_TYPE_MASK | MT_RW |
 				MT_EXECUTE_NEVER)) == MT_CODE)) {
 				desc |= GP;
diff --git a/licenses/LICENSE-APACHE-2.0.txt b/licenses/LICENSE-APACHE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/licenses/LICENSE-APACHE-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 643d550..ac47960 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -307,27 +307,16 @@
 # registers, by setting SCR_EL3.TRNDR.
 ENABLE_FEAT_RNG_TRAP			?=	0
 
-# Enable Memory Tagging Extension. This must be set to 1 if the platform wants
-# to use this feature in the Secure world and MTE is enabled at ELX.
 ifeq ($(CTX_INCLUDE_MTE_REGS),1)
-        $(warning CTX_INCLUDE_MTE_REGS option is deprecated use ENABLE_FEAT_MTE, Enabling ENABLE_FEAT_MTE)
-        ENABLE_FEAT_MTE                 ?=      1
+        $(warning CTX_INCLUDE_MTE_REGS option is deprecated, Check ENABLE_FEAT_MTE2 usage)
 endif
-ifeq (${ARCH},aarch32)
-        ifneq ($(or $(ENABLE_FEAT_MTE),0),0)
-                $(error ENABLE_FEAT_MTE is not supported for AArch32)
-        endif
+ifeq ($(ENABLE_FEAT_MTE),1)
+        $(warning ENABLE_FEAT_MTE option is deprecated, Check ENABLE_FEAT_MTE2 usage)
 endif
-ENABLE_FEAT_MTE		                ?=	0
-ENABLE_FEAT_MTE2		        ?=	0
-
 
-# Add a error message to indicate incorrect MTE2 selection without MTE enabled.
-ifneq ($(ENABLE_FEAT_MTE2),0)
-        ifeq ($(ENABLE_FEAT_MTE),0)
-               $(error ENABLE_FEAT_MTE2 is not supported without enabling ENABLE_FEAT_MTE)
-        endif
-endif
+# Enable FEAT_MTE2. This must be set to 1 if the platform wants
+# to use this feature and is enabled at ELX.
+ENABLE_FEAT_MTE2		        ?=	0
 
 #----
 # 8.6
@@ -352,9 +341,6 @@
 # 8.9
 #----
 
-# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
-ENABLE_FEAT_MTE_PERM			?=	0
-
 # Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE).
 ENABLE_FEAT_S2PIE			?=	0
 
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index a99d516..d27408c 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -10,11 +10,6 @@
     $(error This makefile only works with a Make program that supports $$(eval))
 endif
 
-# Some utility macros for manipulating awkward (whitespace) characters.
-blank			:=
-space			:=${blank} ${blank}
-comma			:= ,
-
 # A user defined function to recursively search for a filename below a directory
 #    $1 is the directory root of the recursive search (blank for current directory).
 #    $2 is the file name to search for.
@@ -22,22 +17,6 @@
 $(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
 endef
 
-# This table is used in converting lower case to upper case.
-uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
-
-# Internal macro used for converting lower case to upper case.
-#   $(1) = upper case table
-#   $(2) = String to convert
-define uppercase_internal
-$(if $(1),$$(subst $(firstword $(1)),$(call uppercase_internal,$(wordlist 2,$(words $(1)),$(1)),$(2))),$(2))
-endef
-
-# A macro for converting a string to upper case
-#   $(1) = String to convert
-define uppercase
-$(eval uppercase_result:=$(call uppercase_internal,$(uppercase_table),$(1)))$(uppercase_result)
-endef
-
 # Convenience function for setting a variable to 0 if not previously set
 # $(eval $(call default_zero,FOO))
 define default_zero
@@ -169,8 +148,8 @@
 #   $(2) = output encrypted firmware binary
 define ENCRYPT_FW
 $(2): $(1) enctool
-	$$(ECHO) "  ENC     $$<"
-	$$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+	$$(s)echo "  ENC     $$<"
+	$$(q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
 endef
 
 # TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
@@ -288,8 +267,8 @@
 # GZIP
 define GZIP_RULE
 $(1): $(2)
-	$(ECHO) "  GZIP    $$@"
-	$(Q)gzip -n -f -9 $$< --stdout > $$@
+	$(s)echo "  GZIP    $$@"
+	$(q)gzip -n -f -9 $$< --stdout > $$@
 endef
 
 GZIP_SUFFIX := .gz
@@ -311,8 +290,8 @@
 $(eval LIB := $(call uppercase, $(notdir $(1))))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -327,8 +306,8 @@
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  AS      $$<"
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -350,8 +329,8 @@
 $(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -373,8 +352,8 @@
 $(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  AS      $$<"
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -394,8 +373,8 @@
 $(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      $$<"
-	$$(Q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
+	$$(s)echo "  PP      $$<"
+	$$(q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
 
 -include $(DEP)
 
@@ -443,11 +422,6 @@
         $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
 endef
 
-# Allow overriding the timestamp, for example for reproducible builds, or to
-# synchronize timestamps across multiple projects.
-# This must be set to a C string (including quotes where applicable).
-BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
-
 .PHONY: libraries
 
 # MAKE_LIB_DIRS macro defines the target for the directory where
@@ -492,8 +466,8 @@
 all: ${LIB_DIR}/lib$(1).a
 
 ${LIB_DIR}/lib$(1).a: $(OBJS)
-	$$(ECHO) "  AR      $$@"
-	$$(Q)$($(ARCH)-ar) cr $$@ $$?
+	$$(s)echo "  AR      $$@"
+	$$(q)$($(ARCH)-ar) cr $$@ $$?
 endef
 
 # Generate the path to one or more preprocessed linker scripts given the paths
@@ -566,49 +540,38 @@
 $(eval OBJS += $(MODULE_OBJS))
 
 $(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
-	$$(ECHO) "  LD      $$@"
-ifdef MAKE_BUILD_STRINGS
-	$(call MAKE_BUILD_STRINGS,$(BUILD_DIR)/build_message.o)
-else
-	@echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \
-	       const char version_string[] = "${VERSION_STRING}"; \
-	       const char version[] = "${VERSION}";' | \
-		$($(ARCH)-cc) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
-endif
+	$$(s)echo "  LD      $$@"
 ifeq ($($(ARCH)-ld-id),arm-link)
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
-		--predefine="-D__LINKER__=$(__LINKER__)" \
-		--predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
+		--predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
+		--predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
 		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
-		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
-		$(BUILD_DIR)/build_message.o $(OBJS)
+		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
 else ifeq ($($(ARCH)-ld-id),gnu-gcc)
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
 		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
-		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
 		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
-		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 endif
 
 $(DUMP): $(ELF)
-	$${ECHO} "  OD      $$@"
-	$${Q}$($(ARCH)-od) -dx $$< > $$@
+	$$(s)echo "  OD      $$@"
+	$$(q)$($(ARCH)-od) -dx $$< > $$@
 
 $(BIN): $(ELF)
-	$${ECHO} "  BIN     $$@"
-	$$(Q)$($(ARCH)-oc) -O binary $$< $$@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+	$$(s)echo "  BIN     $$@"
+	$$(q)$($(ARCH)-oc) -O binary $$< $$@
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 
 .PHONY: $(1)
 ifeq ($(DISABLE_BIN_GENERATION),1)
@@ -665,12 +628,14 @@
 # Dependencies of the DT compilation on its pre-compiled DTS
 $(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
 
-$(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
-	$${ECHO} "  CPP     $$<"
+$(DPRE): $(2) | fdt_dirs
+	$$(s)echo "  CPP     $$<"
 	$(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-	$$(Q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
-	$${ECHO} "  DTC     $$<"
-	$$(Q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $(DPRE)
+	$$(q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+
+$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
+	$$(s)echo "  DTC     $$<"
+	$$(q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
 
 -include $(DTBDEP)
 -include $(DTSDEP)
diff --git a/make_helpers/common.mk b/make_helpers/common.mk
new file mode 100644
index 0000000..75d9f71
--- /dev/null
+++ b/make_helpers/common.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifndef common-mk
+        common-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(common-mk))utilities.mk
+
+        silent = $(call bool,$(findstring s,$(firstword ~$(MAKEFLAGS))))
+        verbose = $(if $(silent),,$(call bool,$(V)))
+
+        s = @$(if $(or $(verbose),$(silent)),: )
+        q = $(if $(verbose),,@)
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 1802077..368d26d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -139,6 +139,12 @@
 # For Chain of Trust
 GENERATE_COT			:= 0
 
+# Default number of 512 blocks per bitlock
+RME_GPT_BITLOCK_BLOCK		:= 1
+
+# Default maximum size of GPT contiguous block
+RME_GPT_MAX_BLOCK		:= 2
+
 # Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
 # default, they are for Secure EL1.
 GICV2_G0_FOR_EL3		:= 0
@@ -176,6 +182,9 @@
 # Option to build TF with Measured Boot support
 MEASURED_BOOT			:= 0
 
+# Option to enable the DICE Protection Environmnet as a Measured Boot backend
+DICE_PROTECTION_ENVIRONMENT	:=0
+
 # NS timer register save and restore
 NS_TIMER_SWITCH			:= 0
 
@@ -285,9 +294,6 @@
 # Use tbbr_oid.h instead of platform_oid.h
 USE_TBBR_DEFS			:= 1
 
-# Build verbosity
-V				:= 0
-
 # Whether to enable D-Cache early during warm boot. This is usually
 # applicable for platforms wherein interconnect programming is not
 # required to enable cache coherency after warm reset (eg: single cluster
@@ -351,6 +357,14 @@
 # Disable Firmware update support by default
 PSA_FWU_SUPPORT			:= 0
 
+# Enable image description in FWU metadata by default when PSA_FWU_SUPPORT
+# is enabled.
+ifeq ($(PSA_FWU_SUPPORT),1)
+PSA_FWU_METADATA_FW_STORE_DESC	:= 1
+else
+PSA_FWU_METADATA_FW_STORE_DESC	:= 0
+endif
+
 # Dynamic Root of Trust for Measurement support
 DRTM_SUPPORT			:= 0
 
@@ -381,3 +395,10 @@
 
 # Enable context memory usage reporting during BL31 setup.
 PLATFORM_REPORT_CTX_MEM_USE	:= 0
+
+# Enable early console
+EARLY_CONSOLE			:= 0
+
+# Allow platforms to save/restore DSU PMU registers over a power cycle.
+# Disabled by default and must be enabled by individual platforms.
+PRESERVE_DSU_PMU_REGS		:= 0
diff --git a/make_helpers/march.mk b/make_helpers/march.mk
index 25bb936..8e73116 100644
--- a/make_helpers/march.mk
+++ b/make_helpers/march.mk
@@ -21,7 +21,7 @@
 # armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
 # [...]
 #
-GCC_MARCH_OUTPUT := $(shell $($(ARCH)-cc) -march=foo -Q --help=target -v 2>&1)
+GCC_MARCH_OUTPUT := $(if $($(ARCH)-cc),$(shell $($(ARCH)-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
diff --git a/make_helpers/toolchain.mk b/make_helpers/toolchain.mk
index 7255509..96e43a8 100644
--- a/make_helpers/toolchain.mk
+++ b/make_helpers/toolchain.mk
@@ -8,336 +8,339 @@
 # TF-A uses three toolchains:
 #
 #   - The host toolchain (`host`) for building native tools
-#   - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
+#   - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
 #   - The AArch64 toolchain (`aarch64`) for building Arm AArch64 images
 #
 # In the main Makefile only one of the two Arm toolchains is enabled in any
 # given build, but individual tools and libraries may need access to both.
 #
 
-toolchains ?= host $(ARCH)
+ifndef toolchain-mk
+        toolchain-mk := $(lastword $(MAKEFILE_LIST))
 
-ifneq ($(filter host,$(toolchains)),)
-        host-cc := $(HOSTCC)
-        host-cpp := $(HOSTCPP)
+        toolchains ?= host $(ARCH)
 
-        host-as := $(HOSTAS)
+        include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
+        include $(dir $(lastword $(MAKEFILE_LIST)))utilities.mk
 
-        host-ld := $(HOSTLD)
-        host-oc := $(HOSTOC)
-        host-od := $(HOSTOD)
-        host-ar := $(HOSTAR)
+        include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
+                $(addsuffix .mk,$(toolchains)))
 
-        host-dtc := $(HOSTDTC)
-endif
+        #
+        # Configure tool classes that we recognize.
+        #
+        # In the context of this build system, a tool class identifies a
+        # specific role or type of tool in the toolchain.
+        #
 
-ifneq ($(filter aarch32,$(toolchains)),)
-        aarch32-cc := $(if $(filter-out default,$(origin CC)),$(CC))
-        aarch32-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
+        tool-classes := cc
+        tool-class-name-cc := C compiler
 
-        aarch32-as := $(if $(filter-out default,$(origin AS)),$(AS))
+        tool-classes += cpp
+        tool-class-name-cpp := C preprocessor
 
-        aarch32-ld := $(if $(filter-out default,$(origin LD)),$(LD))
-        aarch32-oc := $(if $(filter-out default,$(origin OC)),$(OC))
-        aarch32-od := $(if $(filter-out default,$(origin OD)),$(OD))
-        aarch32-ar := $(if $(filter-out default,$(origin AR)),$(AR))
+        tool-classes += as
+        tool-class-name-as := assembler
 
-        aarch32-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
-endif
+        tool-classes += ld
+        tool-class-name-ld := linker
 
-ifneq ($(filter aarch64,$(toolchains)),)
-        aarch64-cc := $(if $(filter-out default,$(origin CC)),$(CC))
-        aarch64-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
+        tool-classes += oc
+        tool-class-name-oc := object copier
 
-        aarch64-as := $(if $(filter-out default,$(origin AS)),$(AS))
+        tool-classes += od
+        tool-class-name-od := object dumper
 
-        aarch64-ld := $(if $(filter-out default,$(origin LD)),$(LD))
-        aarch64-oc := $(if $(filter-out default,$(origin OC)),$(OC))
-        aarch64-od := $(if $(filter-out default,$(origin OD)),$(OD))
-        aarch64-ar := $(if $(filter-out default,$(origin AR)),$(AR))
+        tool-classes += ar
+        tool-class-name-ar := archiver
 
-        aarch64-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
-endif
+        tool-classes += dtc
+        tool-class-name-dtc := device tree compiler
 
-include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
-include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
-        $(addsuffix .mk,$(toolchains)))
+        #
+        # Configure tools that we recognize.
+        #
+        # Here we declare the list of specific toolchain tools that we know how
+        # to interact with. We don't organize these into tool classes yet - that
+        # happens further down.
+        #
 
-#
-# Configure tool classes that we recognize.
-#
-# In the context of this build system, a tool class identifies a specific role
-# or type of tool in the toolchain.
-#
+        # Arm® Compiler for Embedded
+        tools := arm-clang
+        tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
 
-# C-related tools
-tool-classes := cc # C compilers
-tool-classes += cpp # C preprocessors
+        tools += arm-link
+        tool-name-arm-link := Arm® Compiler for Embedded `armlink`
 
-# Assembly-related tools
-tool-classes += as # Assemblers
+        tools += arm-ar
+        tool-name-arm-ar := Arm® Compiler for Embedded `armar`
 
-# Linking and object-handling tools
-tool-classes += ld # Linkers
-tool-classes += oc # Object copiers
-tool-classes += od # Object dumpers
-tool-classes += ar # Archivers
+        tools += arm-fromelf
+        tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
 
-# Other tools
-tool-classes += dtc # Device tree compilers
+        # LLVM Project
+        tools += llvm-clang
+        tool-name-llvm-clang := LLVM Clang (`clang`)
 
-#
-# Configure tools that we recognize.
-#
-# Here we declare the list of specific toolchain tools that we know how to
-# interact with. We don't organize these into tool classes yet - that happens
-# further down.
-#
+        tools += llvm-lld
+        tool-name-llvm-lld := LLVM LLD (`lld`)
 
-# Arm Compiler for Embedded
-tools := arm-clang # armclang
-tools += arm-link # armlink
-tools += arm-ar # armar
-tools += arm-fromelf # fromelf
+        tools += llvm-objcopy
+        tool-name-llvm-objcopy := LLVM `llvm-objcopy`
 
-# LLVM Project
-tools += llvm-clang # clang
-tools += llvm-lld # lld
-tools += llvm-objcopy # llvm-objcopy
-tools += llvm-objdump # llvm-objdump
-tools += llvm-ar # llvm-ar
+        tools += llvm-objdump
+        tool-name-llvm-objdump := LLVM `llvm-objdump`
 
-# GNU Compiler Collection & GNU Binary Utilities
-tools += gnu-gcc # gcc
-tools += gnu-ld # ld
-tools += gnu-objcopy # objcopy
-tools += gnu-objdump # objdump
-tools += gnu-ar # gcc-ar
+        tools += llvm-ar
+        tool-name-llvm-ar := LLVM `llvm-ar`
 
-# Other tools
-tools += dtc # Device Tree Compiler
+        # GNU Compiler Collection & GNU Binary Utilities
+        tools += gnu-gcc
+        tool-name-gnu-gcc := GNU GCC (`gcc`)
 
-#
-# Assign tools to tool classes.
-#
-# Multifunctional tools, i.e. tools which can perform multiple roles in a
-# toolchain, may be specified in multiple tool class lists. For example, a C
-# compiler which can also perform the role of a linker may be placed in both
-# `tools-cc` and `tools-ld`.
-#
+        tools += gnu-ld
+        tool-name-gnu-ld := GNU LD (`ld.bfd`)
 
-# C-related tools
-tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
-tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
+        tools += gnu-objcopy
+        tool-name-gnu-objcopy := GNU `objcopy`
 
-# Assembly-related tools
-tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
+        tools += gnu-objdump
+        tool-name-gnu-objdump := GNU `objdump`
 
-# Linking and object-handling tools
-tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
-tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
-tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
-tools-ar := arm-ar llvm-ar gnu-ar # Archivers
+        tools += gnu-ar
+        tool-name-gnu-ar := GNU `ar`
 
-# Other tools
-tools-dtc := dtc # Device tree compilers
+        # Other tools
+        tools += generic-dtc
+        tool-name-generic-dtc := Device Tree Compiler (`dtc`)
 
-define check-tool-class-tools
-        $(eval tool-class := $(1))
+        #
+        # Assign tools to tool classes.
+        #
+        # Multifunctional tools, i.e. tools which can perform multiple roles in
+        # a toolchain, may be specified in multiple tool class lists. For
+        # example, a C compiler which can also perform the role of a linker may
+        # be placed in both `tools-cc` and `tools-ld`.
+        #
 
-        ifndef tools-$(tool-class)
-                $$(error no tools registered to handle tool class `$(tool-class)`)
-        endif
-endef
+        # C-related tools
+        tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
+        tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
 
-$(foreach tool-class,$(tool-classes), \
-        $(eval $(call check-tool-class-tools,$(tool-class))))
+        # Assembly-related tools
+        tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
 
-#
-# Default tools for each toolchain.
-#
-# Toolchains can specify a default path to any given tool with a tool class.
-# These values are used in the absence of user-specified values, and are
-# configured by the makefile for each toolchain using variables of the form:
-#
-#   - $(toolchain)-$(tool-class)-default
-#
-# For example, the default C compiler for the AArch32 and AArch64 toolchains
-# could be configured with:
-#
-#   - aarch32-cc-default
-#   - aarch64-cc-default
-#
+        # Linking and object-handling tools
+        tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
+        tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
+        tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
+        tools-ar := arm-ar llvm-ar gnu-ar # Archivers
 
-define check-toolchain-tool-class-default
-        $(eval toolchain := $(1))
-        $(eval tool-class := $(2))
+        # Other tools
+        tools-dtc := generic-dtc # Device tree compilers
 
-        ifndef $(toolchain)-$(tool-class)-default
-                $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`)
-        endif
-endef
+        define check-tool-class-tools
+                $(eval tool-class := $(1))
 
-define check-toolchain-tool-class-defaults
-        $(eval toolchain := $(1))
+                ifndef tools-$(tool-class)
+                        $$(error no tools registered to handle tool class `$(tool-class)`)
+                endif
+        endef
 
         $(foreach tool-class,$(tool-classes), \
-                $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
-endef
+                $(eval $(call check-tool-class-tools,$(tool-class))))
 
-$(foreach toolchain,$(toolchains), \
-        $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
+        #
+        # Default tools for each toolchain.
+        #
+        # Toolchains can specify a default path to any given tool with a tool
+        # class. These values are used in the absence of user-specified values,
+        # and are configured by the makefile for each toolchain using variables
+        # of the form:
+        #
+        #   - $(toolchain)-$(tool-class)-default
+        #
+        # For example, the default C compiler for the AArch32 and AArch64
+        # toolchains could be configured with:
+        #
+        #   - aarch32-cc-default
+        #   - aarch64-cc-default
+        #
 
-#
-# Helper functions to identify toolchain tools.
-#
-# The functions defined in this section return a tool identifier when given a
-# path to a binary. We generally check a help or version string to more reliably
-# identify tools than by looking at the path alone (e.g. `gcc` on macOS is
-# actually Apple Clang).
-#
-# Each tool-guessing function (`guess-tool-$(tool)`) takes a single argument
-# giving the path to the tool to guess, and returns a non-empty value if the
-# tool corresponds to the tool identifier `$(tool)`:
-#
-#     $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
-#     $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
-#
-# The `guess-tool` function tries to find the corresponding tool identifier
-# for a tool given its path. It takes two arguments:
-#
-#   - $(1): a list of candidate tool identifiers to check
-#   - $(2): the path to the tool to identify
-#
-# If any of the guess functions corresponding to candidate tool identifiers
-# return a non-empty value then the tool identifier of the first function to do
-# so is returned:
-#
-#     $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
-#     $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
-#     $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
-#
-# Tools are checked in the order that they appear in `tools-$(tool-class)`, and
-# the first match is returned.
-#
+        define check-toolchain-tool-class-default
+                $(eval toolchain := $(1))
+                $(eval tool-class := $(2))
 
-# Arm Compiler for Embedded
-guess-tool-arm-clang = $(shell $(1) --version 2>&1 | grep -o "Tool: armclang")
-guess-tool-arm-link = $(shell $(1) --help 2>&1 | grep -o "Tool: armlink")
-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 | grep -o "Tool: fromelf")
-guess-tool-arm-ar = $(shell $(1) --version 2>&1 | grep -o "Tool: armar")
+                ifndef $(toolchain)-$(tool-class)-default
+                        $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`)
+                endif
+        endef
 
-# LLVM Project
-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 | grep -o "clang version")
-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 | grep -o "OVERVIEW: lld")
-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 | grep -o "llvm-objcopy tool")
-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 | grep -o "llvm object file dumper")
-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 | grep -o "LLVM Archiver")
+        define check-toolchain-tool-class-defaults
+                $(eval toolchain := $(1))
 
-# GNU Compiler Collection & GNU Binary Utilities
-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 | grep -o "gcc version")
-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 | grep -o "GNU ld")
-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 | grep -o "GNU objcopy")
-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 | grep -o "GNU objdump")
-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 | grep -o "GNU ar")
+                $(foreach tool-class,$(tool-classes), \
+                        $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
+        endef
 
-# Other tools
-guess-tool-dtc = $(shell $(1) --version 2>&1 | grep -o "Version: DTC")
+        $(foreach toolchain,$(toolchains), \
+                $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
 
-guess-tool = $(firstword $(foreach candidate,$(1), \
-        $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
+        #
+        # Helper functions to identify toolchain tools.
+        #
+        # The functions defined in this section return a tool identifier when
+        # given a path to a binary. We generally check a help or version string
+        # to more reliably identify tools than by looking at the path alone
+        # (e.g. `gcc` on macOS is actually Apple Clang).
+        #
+        # Each tool-guessing function (`guess-tool-$(tool)`) takes a single
+        # argument giving the path to the tool to guess, and returns a non-empty
+        # value if the tool corresponds to the tool identifier `$(tool)`:
+        #
+        #     $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
+        #     $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
+        #
+        # The `guess-tool` function tries to find the corresponding tool
+        # identifier for a tool given its path. It takes two arguments:
+        #
+        #   - $(1): a list of candidate tool identifiers to check
+        #   - $(2): the path to the tool to identify
+        #
+        # If any of the guess functions corresponding to candidate tool
+        # identifiers return a non-empty value then the tool identifier of the
+        # first function to do so is returned:
+        #
+        #     $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
+        #     $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
+        #     $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
+        #
+        # Tools are checked in the order that they appear in
+        # `tools-$(tool-class)`, and the first match is returned.
+        #
 
-#
-# Locate and identify tools belonging to each toolchain.
-#
-# Each tool class in each toolchain receives a variable of the form
-# `$(toolchain)-$(tool)` giving the associated path to the program. For example:
-#
-#   - `aarch64-ld` gives the linker for the AArch64 toolchain,
-#   - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
-#   - `host-cc` gives the C compiler for the host toolchain.
-#
-# For each of these variables, if no program path is explicitly provided by the
-# parent Makefile then the C compiler is queried (if supported) for its
-# location. This is done via the `guess-$(tool)-$(tool-class)` set of functions.
-# For example:
-#
-#   - `guess-arm-clang-ld` guesses the linker via Arm Clang,
-#   - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and
-#   - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC.
-#
-# If the C compiler cannot provide the location (or the tool class is the C
-# compiler), then it is assigned the value of the `$(toolchain)-$(tool)-default`
-# variable.
-#
+        # Arm Compiler for Embedded
+        guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
+        guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
+        guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
+        guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar")
 
-guess-arm-clang-cpp = $(1) # Use the C compiler
-guess-arm-clang-as = $(1) # Use the C compiler
-guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
-guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
-guess-arm-clang-od = # Fall back to `$(toolchain)-od-default`
-guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
+        # LLVM Project
+        guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version")
+        guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
+        guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
+        guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
+        guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
 
-guess-llvm-clang-cpp = $(1) # Use the C compiler
-guess-llvm-clang-as = $(1) # Use the C compiler
-guess-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
-guess-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
-guess-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
-guess-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
+        # GNU Compiler Collection & GNU Binary Utilities
+        guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version")
+        guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld")
+        guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
+        guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump")
+        guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar")
 
-guess-gnu-gcc-cpp = $(1) # Use the C compiler
-guess-gnu-gcc-as = $(1) # Use the C compiler
-guess-gnu-gcc-ld = $(if $(filter 1,$(ENABLE_LTO)),$(1),$(shell $(1) --print-prog-name ld.bfd 2>$(nul)))
-guess-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
-guess-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
-guess-gnu-gcc-ar = $(patsubst %$(notdir $(1)),%$(subst gcc,gcc-ar,$(notdir $(1))),$(1))
+        # Other tools
+        guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
 
-define locate-toolchain-tool-cc
-        $(eval toolchain := $(1))
+        guess-tool = $(firstword $(foreach candidate,$(1), \
+                $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
 
-        $(toolchain)-cc := $$(strip \
-                $$(or $$($(toolchain)-cc),$$($(toolchain)-cc-default)))
-        $(toolchain)-cc-id := $$(strip \
-                $$(call guess-tool,$$(tools-cc),$$($(toolchain)-cc)))
-endef
+        #
+        # Locate and identify tools belonging to each toolchain.
+        #
+        # Each tool class in each toolchain receives a variable of the form
+        # `$(toolchain)-$(tool)` giving the associated path to the program. For
+        # example:
+        #
+        #   - `aarch64-ld` gives the linker for the AArch64 toolchain,
+        #   - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
+        #   - `host-cc` gives the C compiler for the host toolchain.
+        #
+        # For each of these variables, if no program path is explicitly provided
+        # by the parent Makefile then the C compiler is queried (if supported)
+        # for its location. This is done via the `guess-$(tool)-$(tool-class)`
+        # set of functions. For example:
+        #
+        #   - `guess-arm-clang-ld` guesses the linker via Arm Clang,
+        #   - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and
+        #   - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC.
+        #
+        # If the C compiler cannot provide the location (or the tool class is
+        # the C compiler), then it is assigned the value of the
+        # `$(toolchain)-$(tool)-default` variable.
+        #
 
-define locate-toolchain-tool
-        $(eval toolchain := $(1))
-        $(eval tool-class := $(2))
+        guess-arm-clang-cpp = $(1)
+        guess-arm-clang-as = $(1)
+        guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
+        guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
+        guess-arm-clang-od = # Fall back to `$(toolchain)-od-default`
+        guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
 
-        ifndef $(toolchain)-$(tool-class)
-                $(toolchain)-$(tool-class) := $$(strip \
-                        $$(call guess-$$($(toolchain)-cc-id)-$(tool-class),$$($(toolchain)-cc)))
+        guess-llvm-clang-cpp = $(1)
+        guess-llvm-clang-as = $(1)
+        guess-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
+        guess-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
+        guess-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
+        guess-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
 
-                ifeq ($$($(toolchain)-$(tool-class)),)
-                        $(toolchain)-$(tool-class) := $$(strip \
-                                $$($(toolchain)-$(tool-class)-default))
-                endif
-        endif
+        guess-gnu-gcc-cpp = $(1)
+        guess-gnu-gcc-as = $(1)
+        guess-gnu-gcc-ld = $(1)
+        guess-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
+        guess-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
+        guess-gnu-gcc-ar = $(call which,$(call decompat-path,$(patsubst %$(call file-name,$(1)),%$(subst gcc,gcc-ar,$(call file-name,$(1))),$(call compat-path,$(1)))))
 
-        $(toolchain)-$(tool-class)-id := $$(strip \
-                $$(call guess-tool,$$(tools-$(tool-class)),$$($$(toolchain)-$(tool-class))))
-endef
+        define toolchain-warn-unrecognized
+                $$(warning )
+                $$(warning The configured $$($(1)-name) $$(tool-class-name-$(2)) could not be identified and may not be supported:)
+                $$(warning )
+                $$(warning $$(space)   $$($(1)-$(2)))
+                $$(warning )
+                $$(warning The default $$($(1)-name) $$(tool-class-name-$(2)) is:)
+                $$(warning )
+                $$(warning $$(space)   $$($(1)-$(2)-default))
+                $$(warning )
+                $$(warning The following tools are supported:)
+                $$(warning )
 
-define canonicalize-toolchain-tool-path
-        $(eval toolchain := $(1))
-        $(eval tool-class := $(2))
+                $$(foreach tool,$$(tools-$(2)), \
+                        $$(warning $$(space) - $$(tool-name-$$(tool))))
 
-        $(toolchain)-$(tool-class) := $$(strip $$(or \
-                $$(call which,$$($(toolchain)-$(tool-class))), \
-                $$($(toolchain)-$(tool-class))))
-endef
+                $$(warning )
+                $$(warning The build system will treat this $$(tool-class-name-$(2)) as $$(tool-name-$$($(1)-$(2)-id-default)).)
+                $$(warning )
+        endef
 
-define locate-toolchain
-        $(eval toolchain := $(1))
+        define toolchain-determine-tool
+                $(1)-$(2)-guess = $$(if $$(filter-out cc,$(2)),$\
+                        $$(call guess-$$($(1)-cc-id)-$(2),$$($(1)-cc)))
 
-        $$(eval $$(call locate-toolchain-tool-cc,$(toolchain)))
-        $$(eval $$(call canonicalize-toolchain-tool-path,$(toolchain),cc))
+                $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-guess))
+                $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-default))
 
-        $$(foreach tool-class,$$(filter-out cc,$$(tool-classes)), \
-                $$(eval $$(call locate-toolchain-tool,$(toolchain),$$(tool-class))) \
-                $$(eval $$(call canonicalize-toolchain-tool-path,$(toolchain),$$(tool-class))))
-endef
+                ifneq ($$(call which,$$($(1)-$(2))),)
+                        # If we can resolve this tool to a program on the `PATH`
+                        # then escape it for use in a shell, which allows us to
+                        # preserve spaces.
 
-$(foreach toolchain,$(toolchains), \
-        $(eval $(call locate-toolchain,$(toolchain))))
+                        $(1)-$(2) := $$(call escape-shell,$$($(1)-$(2)))
+                endif
+
+                $(1)-$(2)-id := $$(call guess-tool,$$(tools-$(2)),$$($(1)-$(2)))
+
+                ifndef $(1)-$(2)-id
+                        $(1)-$(2)-id := $$($(1)-$(2)-id-default)
+
+                        $$(eval $$(call toolchain-warn-unrecognized,$(1),$(2)))
+                endif
+        endef
+
+        define toolchain-determine
+                $$(foreach tool-class,$$(tool-classes), \
+                        $$(eval $$(call toolchain-determine-tool,$(1),$$(tool-class))))
+        endef
+
+        $(foreach toolchain,$(toolchains), \
+                $(eval $(call toolchain-determine,$(toolchain))))
+endif
diff --git a/make_helpers/toolchains/aarch32.mk b/make_helpers/toolchains/aarch32.mk
index 226bc75..ff00a53 100644
--- a/make_helpers/toolchains/aarch32.mk
+++ b/make_helpers/toolchains/aarch32.mk
@@ -4,11 +4,36 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+aarch32-name := AArch32
+
+aarch32-cc := $(if $(filter-out default,$(origin CC)),$(CC))
 aarch32-cc-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+aarch32-cc-id-default := gnu-gcc
+
+aarch32-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
 aarch32-cpp-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+aarch32-cpp-id-default := gnu-gcc
+
+aarch32-as := $(if $(filter-out default,$(origin AS)),$(AS))
 aarch32-as-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
-aarch32-ld-default := $(or $(CROSS_COMPILE),arm-none-eabi-)ld.bfd
+aarch32-as-id-default := gnu-gcc
+
+aarch32-ld := $(if $(filter-out default,$(origin LD)),$(LD))
+aarch32-ld-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+aarch32-ld-id-default := gnu-gcc
+
+aarch32-oc := $(if $(filter-out default,$(origin OC)),$(OC))
 aarch32-oc-default := $(or $(CROSS_COMPILE),arm-none-eabi-)objcopy
+aarch32-oc-id-default := gnu-objcopy
+
+aarch32-od := $(if $(filter-out default,$(origin OD)),$(OD))
 aarch32-od-default := $(or $(CROSS_COMPILE),arm-none-eabi-)objdump
+aarch32-od-id-default := gnu-objdump
+
+aarch32-ar := $(if $(filter-out default,$(origin AR)),$(AR))
 aarch32-ar-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc-ar
+aarch32-ar-id-default := gnu-ar
+
+aarch32-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
 aarch32-dtc-default := dtc
+aarch32-dtc-id-default := generic-dtc
diff --git a/make_helpers/toolchains/aarch64.mk b/make_helpers/toolchains/aarch64.mk
index 15c5757..407f068 100644
--- a/make_helpers/toolchains/aarch64.mk
+++ b/make_helpers/toolchains/aarch64.mk
@@ -4,11 +4,36 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+aarch64-name := AArch64
+
+aarch64-cc := $(if $(filter-out default,$(origin CC)),$(CC))
 aarch64-cc-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-cc-id-default := gnu-gcc
+
+aarch64-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
 aarch64-cpp-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-cpp-id-default := gnu-gcc
+
+aarch64-as := $(if $(filter-out default,$(origin AS)),$(AS))
 aarch64-as-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
-aarch64-ld-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)ld.bfd
+aarch64-as-id-default := gnu-gcc
+
+aarch64-ld := $(if $(filter-out default,$(origin LD)),$(LD))
+aarch64-ld-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-ld-id-default := gnu-gcc
+
+aarch64-oc := $(if $(filter-out default,$(origin OC)),$(OC))
 aarch64-oc-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)objcopy
+aarch64-oc-id-default := gnu-objcopy
+
+aarch64-od := $(if $(filter-out default,$(origin OD)),$(OD))
 aarch64-od-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)objdump
+aarch64-od-id-default := gnu-objdump
+
+aarch64-ar := $(if $(filter-out default,$(origin AR)),$(AR))
 aarch64-ar-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc-ar
+aarch64-ar-id-default := gnu-ar
+
+aarch64-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
 aarch64-dtc-default := dtc
+aarch64-dtc-id-default := generic-dtc
diff --git a/make_helpers/toolchains/host.mk b/make_helpers/toolchains/host.mk
index fe3fc1c..733c289 100644
--- a/make_helpers/toolchains/host.mk
+++ b/make_helpers/toolchains/host.mk
@@ -1,14 +1,39 @@
 #
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+host-name := host
+
+host-cc := $(HOSTCC)
 host-cc-default := gcc
+host-cc-id-default := gnu-gcc
+
+host-cpp := $(HOSTCPP)
 host-cpp-default := gcc
+host-cpp-id-default := gnu-gcc
+
+host-as := $(HOSTAS)
 host-as-default := gcc
+host-as-id-default := gnu-gcc
+
+host-ld := $(HOSTLD)
 host-ld-default := gcc
+host-ld-id-default := gnu-gcc
+
+host-oc := $(HOSTOC)
 host-oc-default := objcopy
+host-oc-id-default := gnu-objcopy
+
+host-od := $(HOSTOD)
 host-od-default := objdump
+host-od-id-default := gnu-objdump
+
+host-ar := $(HOSTAR)
 host-ar-default := gcc-ar
+host-ar-id-default := gnu-ar
+
+host-dtc := $(HOSTDTC)
 host-dtc-default := dtc
+host-dtc-id-default := generic-dtc
diff --git a/make_helpers/toolchains/rk3399-m0.mk b/make_helpers/toolchains/rk3399-m0.mk
index c61b6e8..92309f1 100644
--- a/make_helpers/toolchains/rk3399-m0.mk
+++ b/make_helpers/toolchains/rk3399-m0.mk
@@ -4,11 +4,28 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+rk3399-m0-name := RK3399 M0
+
 rk3399-m0-cc-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+rk3399-m0-cc-id-default := gnu-gcc
+
 rk3399-m0-cpp-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+rk3399-m0-cpp-id-default := gnu-gcc
+
 rk3399-m0-as-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
-rk3399-m0-ld-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)ld.bfd
+rk3399-m0-as-id-default := gnu-gcc
+
+rk3399-m0-ld-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+rk3399-m0-ld-id-default := gnu-gcc
+
 rk3399-m0-oc-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)objcopy
+rk3399-m0-oc-id-default := gnu-objcopy
+
 rk3399-m0-od-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)objdump
+rk3399-m0-od-id-default := gnu-objdump
+
 rk3399-m0-ar-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc-ar
+rk3399-m0-ar-id-default := gnu-ar
+
 rk3399-m0-dtc-default := dtc
+rk3399-m0-dtc-id-default := generic-dtc
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
index d285799..4fd819a 100644
--- a/make_helpers/unix.mk
+++ b/make_helpers/unix.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,9 +9,6 @@
 ifndef UNIX_MK
     UNIX_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := echo
-    ECHO_QUIET := @\#
-
     DIR_DELIM := /
     PATH_SEP := :
 
@@ -21,24 +18,24 @@
     # ${1} is the file to be copied.
     # ${2} is the destination file name.
     define SHELL_COPY
-	${Q}cp -f  "${1}"  "${2}"
+	$(q)cp -f  "${1}"  "${2}"
     endef
 
     # ${1} is the directory to be copied.
     # ${2} is the destination directory path.
     define SHELL_COPY_TREE
-	${Q}cp -rf  "${1}"  "${2}"
+	$(q)cp -rf  "${1}"  "${2}"
     endef
 
     # ${1} is the file to be deleted.
     define SHELL_DELETE
-	-${Q}rm -f  "${1}"
+	-$(q)rm -f  "${1}"
     endef
 
     # ${1} is a space delimited list of files to be deleted.
     # Note that we do not quote ${1}, as multiple parameters may be passed.
     define SHELL_DELETE_ALL
-	-${Q}rm -rf  ${1}
+	-$(q)rm -rf  ${1}
     endef
 
     # ${1} is the directory to be generated.
@@ -48,16 +45,16 @@
         ifneq (${1},${2})
 
 ${1} : ${2}
-	${Q}mkdir -p  "${1}"
+	$(q)mkdir -p  "${1}"
 
         endif
     endef
 
     define SHELL_REMOVE_DIR
-	-${Q}rm -rf  "${1}"
+	-$(q)rm -rf  "${1}"
     endef
 
     nul := /dev/null
 
-    which = $(shell which $(1) 2>$(nul))
+    which = $(shell command -v $(call escape-shell,$(1)) 2>$(nul))
 endif
diff --git a/make_helpers/utilities.mk b/make_helpers/utilities.mk
new file mode 100644
index 0000000..45ef12e
--- /dev/null
+++ b/make_helpers/utilities.mk
@@ -0,0 +1,102 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+space :=
+space := $(space) $(space)
+comma := ,
+
+null := �
+
+compat-path = $(subst $(space),$(null),$(1))
+decompat-path = $(subst $(null), ,$(1))
+
+absolute-path = $(call decompat-path,$(abspath $(call compat-path,$(1))))
+real-path = $(call decompat-path,$(realpath $(call compat-path,$(1))))
+
+file-name = $(call decompat-path,$(notdir $(call compat-path,$(1))))
+directory-name = $(call decompat-path,$(dir $(call compat-path,$(1))))
+
+escape-shell = '$(subst ','\'',$(1))'
+
+#
+# Upper-case a string value.
+#
+# Parameters:
+#
+#   - $(1): The string to upper-case.
+#
+# Example usage:
+#
+#     $(call uppercase,HeLlO wOrLd) # "HELLO WORLD"
+#
+
+uppercase = $(shell echo $(call escape-shell,$(1)) | tr '[:lower:]' '[:upper:]')
+
+#
+# Lower-case a string value.
+#
+# Parameters:
+#
+#   - $(1): The string to lower-case.
+#
+# Example usage:
+#
+#     $(call lowercase,HeLlO wOrLd) # "hello world"
+#
+
+lowercase = $(shell echo $(call escape-shell,$(1)) | tr '[:upper:]' '[:lower:]')
+
+#
+# Determine the "truthiness" of a value.
+#
+# Parameters:
+#
+#   - $(1): The value to determine the truthiness of.
+#
+# A value is considered to be falsy if it is:
+#
+#   - empty, or
+#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
+#
+# If the value is truthy then the value is returned as-is, otherwise no value
+# is returned.
+#
+# Example usage:
+#
+#     truthy := y
+#     truthy-bool := $(call bool,$(truthy)) # "y"
+#
+#     falsy := n
+#     falsy-bool := $(call bool,$(falsy)) # <empty>
+#
+
+bool = $(filter-out 0 n no f false,$(call lowercase,$(1)))
+
+#
+# Determine the "truthiness" of a value, returning 0 or 1.
+#
+# Parameters:
+#
+#   - $(1): The value to determine the truthiness of.
+#
+# A value is considered to be falsy if it is:
+#
+#   - empty, or
+#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
+#
+# If the value is truthy then the value is returned as-is, otherwise no value
+# is returned.
+#
+# Example usage:
+#
+#     truthy := y
+#     truthy-bool := $(call bool,$(truthy)) # "1"
+#
+#     falsy := n
+#     falsy-bool := $(call bool,$(falsy)) # "0"
+#
+
+bool-01 = $(if $(call bool,$(1)),1,0)
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index 7ed8e84..2f5d51b 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -12,8 +12,6 @@
 ifndef WINDOWS_MK
     WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := @cmd /c echo.
-    ECHO_QUIET := @rem
     DIR_DELIM := $(strip \)
     BIN_EXT   := .exe
     PATH_SEP  := ;
@@ -70,7 +68,7 @@
 
     nul := nul
 
-    which = $(shell where $(1) 2>$(nul))
+    which = $(shell where "$(1)" 2>$(nul))
 endif
 
 # Because git is not available from CMD.EXE, we need to avoid
@@ -79,16 +77,4 @@
 # This can be overridden from the command line or environment.
 BUILD_STRING ?= development build
 
-# The DOS echo shell command does not strip ' characters from the command
-# parameters before printing. We therefore use an alternative method invoked
-# by defining the MAKE_BUILD_STRINGS macro.
-BUILT_TIME_DATE_STRING = const char build_message[] = "Built : "${BUILD_MESSAGE_TIMESTAMP};
-VERSION_STRING_MESSAGE = const char version_string[] = "${VERSION_STRING}";
-VERSION_MESSAGE = const char version[] = "${VERSION}";
-define MAKE_BUILD_STRINGS
-	$$(file >$1.in,$$(TF_CFLAGS) $$(CFLAGS))
-	@echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) $$(VERSION_MESSAGE) | \
-		$($(ARCH)-cc) @$1.in -x c -c - -o $1
-endef
-
 MSVC_NMAKE := nmake.exe
diff --git a/package-lock.json b/package-lock.json
index 7753a38..a6bb905 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,13 +1,12 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.10.0",
+  "version": "2.11.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "trusted-firmware-a",
-      "version": "2.10.0",
-      "hasInstallScript": true,
+      "version": "2.11.0",
       "license": "BSD-3-Clause",
       "devDependencies": {
         "@commitlint/cli": "^19.0.0",
diff --git a/package.json b/package.json
index 43c897e..e4c6475 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.10.0",
+  "version": "2.11.0",
   "license": "BSD-3-Clause",
   "type": "module",
   "private": true,
   "scripts": {
-    "postinstall": "husky install",
+    "prepare": "husky",
     "release": "standard-version"
   },
   "engines": {
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index a32124a..263083b 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,6 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
@@ -186,8 +185,6 @@
 {
 	/* Change the DTB if the configuration requires so. */
 	sunxi_prepare_dtb(fdt);
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/amd/versal2/aarch64/common.c b/plat/amd/versal2/aarch64/common.c
new file mode 100644
index 0000000..3ab3dca
--- /dev/null
+++ b/plat/amd/versal2/aarch64/common.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <def.h>
+#include <plat_common.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
+uint32_t platform_id, platform_version;
+
+/*
+ * Table of regions to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+const mmap_region_t plat_mmap[] = {
+	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(IPI_BASE, IPI_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+#if defined(TRANSFER_LIST)
+	MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_BASE + FW_HANDOFF_SIZE,
+			MT_MEMORY | MT_RW | MT_NS),
+#endif
+	{ 0 }
+};
+
+const mmap_region_t *plat_get_mmap(void)
+{
+	return plat_mmap;
+}
+
+/* For saving cpu clock for certain platform */
+uint32_t cpu_clock;
+
+const char *board_name_decode(void)
+{
+	const char *platform;
+
+	switch (platform_id) {
+	case SPP:
+		platform = "IPP";
+		break;
+	case EMU:
+		platform = "EMU";
+		break;
+	case SILICON:
+		platform = "Silicon";
+		break;
+	case QEMU:
+		platform = "QEMU";
+		break;
+	default:
+		platform = "Unknown";
+	}
+
+	return platform;
+}
+
+void board_detection(void)
+{
+	uint32_t version;
+
+	version = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+
+	if (platform_id == QEMU_COSIM) {
+		platform_id = QEMU;
+	}
+
+	/* Make sure that console is setup to see this message */
+	VERBOSE("Platform id: %d version: %d.%d\n", platform_id,
+		platform_version / 10U, platform_version % 10U);
+}
+
+uint32_t get_uart_clk(void)
+{
+	uint32_t uart_clock = 0;
+
+	switch (platform_id) {
+	case SPP:
+	case SPP_MMD:
+		uart_clock = cpu_clock;
+		break;
+	case EMU:
+	case EMU_MMD:
+		uart_clock = 25000000;
+		break;
+	case QEMU:
+		/* Random values now */
+		uart_clock = 25000000;
+		break;
+	case SILICON:
+		uart_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	return uart_clock;
+}
+
+void config_setup(void)
+{
+	uint32_t val;
+	uintptr_t crl_base, iou_scntrs_base, psx_base;
+
+	crl_base = CRL;
+	iou_scntrs_base = IOU_SCNTRS;
+	psx_base = PSX_CRF;
+
+	/* Reset for system timestamp generator in FPX */
+	mmio_write_32(psx_base + PSX_CRF_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Global timer init - Program time stamp reference clk */
+	val = mmio_read_32(crl_base + CRL_TIMESTAMP_REF_CTRL_OFFSET);
+	val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
+	mmio_write_32(crl_base + CRL_TIMESTAMP_REF_CTRL_OFFSET, val);
+
+	/* Clear reset of timestamp reg */
+	mmio_write_32(crl_base + CRL_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Program freq register in System counter and enable system counter. */
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_BASE_FREQ_OFFSET,
+		      cpu_clock);
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET,
+		      IOU_SCNTRS_CONTROL_EN);
+
+	generic_delay_timer_init();
+
+	/* Configure IPI data */
+	soc_ipi_config_table_init();
+}
+
+uint32_t plat_get_syscnt_freq2(void)
+{
+	return cpu_clock;
+}
diff --git a/plat/amd/versal2/aarch64/helpers.S b/plat/amd/versal2/aarch64/helpers.S
new file mode 100644
index 0000000..580bb76
--- /dev/null
+++ b/plat/amd/versal2/aarch64/helpers.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * 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
+	.globl	plat_is_my_cpu_primary
+	.globl	platform_mem_init
+	.globl	plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * TODO: Should we read the PSYS register to make sure
+	 * that the request has gone through.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	mrs	x0, mpidr_el1
+
+	/*
+	 * There is no sane reason to come out of this wfi. This
+	 * cpu will be powered on and reset by the cpu_on pm api
+	 */
+	dsb	sy
+	bl	plat_panic_handler
+endfunc plat_secondary_cold_boot_setup
+
+func plat_is_my_cpu_primary
+	mov	x9, x30
+	bl	plat_my_core_pos
+	cmp	x0, #PRIMARY_CPU
+	cset	x0, eq
+	ret	x9
+endfunc plat_is_my_cpu_primary
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_core_pos_by_mpidr()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_core_pos_by_mpidr
+endfunc plat_my_core_pos
+
+	/* ---------------------------------------------------------------------
+	 * We don't need to carry out any memory initialization on platform
+	 * The Secure RAM is accessible straight away.
+	 * ---------------------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
new file mode 100644
index 0000000..e878863
--- /dev/null
+++ b/plat/amd/versal2/bl31_setup.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bl31/bl31.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/dcc.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+#include <scmi.h>
+
+#include <def.h>
+#include <plat_fdt.h>
+#include <plat_private.h>
+#include <plat_startup.h>
+#include <pm_api_sys.h>
+#include <pm_client.h>
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/*
+ * 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.
+ */
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	assert(sec_state_is_valid(type));
+
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	}
+
+	return &bl32_image_ep_info;
+}
+
+/*
+ * Set the build time defaults,if we can't find any config data.
+ */
+static inline void bl31_set_default_config(void)
+{
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+#if defined(SPD_opteed)
+	/* NS dtb addr passed to optee_os */
+	bl32_image_ep_info.args.arg3 = XILINX_OF_BOARD_DTB_ADDR;
+#endif
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+					  DISABLE_ALL_EXCEPTIONS);
+}
+
+/*
+ * Perform any BL31 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-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.
+ */
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	uint32_t uart_clock;
+	int32_t rc;
+
+	board_detection();
+
+	/* FIXME */
+	switch (platform_id) {
+	case SPP:
+		switch (platform_version) {
+		case SPP_PSXC_MMI_V2_0:
+			cpu_clock = 770000;
+			break;
+		case SPP_PSXC_MMI_V3_0:
+			cpu_clock = 908000;
+			break;
+		default:
+			panic();
+		}
+		break;
+	case SPP_MMD:
+		switch (platform_version) {
+		case SPP_PSXC_ISP_AIE_V2_0:
+		case SPP_PSXC_MMD_AIE_FRZ_EA:
+		case SPP_PSXC_MMD_AIE_V3_0:
+			cpu_clock = 760000;
+			break;
+		default:
+			panic();
+		}
+		break;
+	case EMU:
+	case EMU_MMD:
+		cpu_clock = 112203;
+		break;
+	case QEMU:
+		/* Random values now */
+		cpu_clock = 3333333;
+		break;
+	case SILICON:
+		cpu_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	uart_clock = get_uart_clk();
+
+	if (CONSOLE_IS(pl011_0) || CONSOLE_IS(pl011_1)) {
+		static console_t _runtime_console;
+
+		/* Initialize the console to provide early debug support */
+		rc = console_pl011_register(UART_BASE, uart_clock,
+					    UART_BAUDRATE,
+					    &_runtime_console);
+		if (rc == 0) {
+			panic();
+		}
+
+		console_set_scope(&_runtime_console, CONSOLE_FLAG_BOOT |
+				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	} else if (CONSOLE_IS(dcc)) {
+		/* Initialize the dcc console for debug.
+		 * dcc is over jtag and does not configures uart0 or uart1.
+		 */
+		rc = console_dcc_register();
+		if (rc == 0) {
+			panic();
+		}
+	} else {
+		/* Making MISRA C 2012 15.7 compliant */
+	}
+
+	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
+	       platform_version / 10U, platform_version % 10U);
+
+	/* Initialize the platform config for future decision making */
+	config_setup();
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access. On
+	 * Base only DRAM security is programmable (via TrustZone), but
+	 * other platforms might have more programmable security devices
+	 * present.
+	 */
+
+	/* Populate common information for BL32 and BL33 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	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);
+	bl31_set_default_config();
+
+	long rev_var = cpu_get_rev_var();
+
+	INFO("CPU Revision = 0x%lx\n", rev_var);
+	INFO("cpu_clock = %dHz, uart_clock = %dHz\n", cpu_clock, uart_clock);
+	NOTICE("BL31: Executing from 0x%x\n", BL31_BASE);
+	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);
+
+}
+
+static versal_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
+
+int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
+{
+	static uint32_t index;
+	uint32_t i;
+
+	/* Validate 'handler' and 'id' parameters */
+	if (handler == NULL || index >= MAX_INTR_EL3) {
+		return -EINVAL;
+	}
+
+	/* Check if a handler has already been registered */
+	for (i = 0; i < index; i++) {
+		if (id == type_el3_interrupt_table[i].id) {
+			return -EALREADY;
+		}
+	}
+
+	type_el3_interrupt_table[index].id = id;
+	type_el3_interrupt_table[index].handler = handler;
+
+	index++;
+
+	return 0;
+}
+
+static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
+					  void *handle, void *cookie)
+{
+	uint32_t intr_id;
+	uint32_t i;
+	interrupt_type_handler_t handler = NULL;
+
+	intr_id = plat_ic_get_pending_interrupt_id();
+
+	for (i = 0; i < MAX_INTR_EL3; i++) {
+		if (intr_id == type_el3_interrupt_table[i].id) {
+			handler = type_el3_interrupt_table[i].handler;
+		}
+	}
+
+	if (handler != NULL) {
+		(void)handler(intr_id, flags, handle, cookie);
+	}
+
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	prepare_dtb();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_gic_driver_init();
+	plat_gic_init();
+
+	if (platform_id != EMU) {
+		init_scmi_server();
+	}
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	uint64_t flags = 0;
+	int32_t rc;
+
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+					     rdo_el3_interrupt_handler, flags);
+	if (rc != 0) {
+		panic();
+	}
+}
+
+/*
+ * Perform the very early platform specific architectural setup here.
+ */
+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,
+				MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+				MT_RO_DATA | MT_SECURE),
+		MAP_REGION_FLAT(SMT_BUFFER_BASE, 0x1000,
+			MT_DEVICE | MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER | MT_NS),
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_get_mmap());
+	enable_mmu(0);
+}
diff --git a/plat/amd/versal2/gicv3.c b/plat/amd/versal2/gicv3.c
new file mode 100644
index 0000000..c7b44e1
--- /dev/null
+++ b/plat/amd/versal2/gicv3.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+
+/******************************************************************************
+ * The following functions are defined as weak to allow a platform to override
+ * the way the GICv3 driver is initialised and used.
+ *****************************************************************************/
+#pragma weak plat_gic_driver_init
+#pragma weak plat_gic_init
+#pragma weak plat_gic_cpuif_enable
+#pragma weak plat_gic_cpuif_disable
+#pragma weak plat_gic_pcpu_init
+#pragma weak plat_gic_redistif_on
+#pragma weak plat_gic_redistif_off
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static const interrupt_prop_t _interrupt_props[] = {
+	PLAT_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+/*
+ * We save and restore the GICv3 context on system suspend. Allocate the
+ * data in the designated EL3 Secure carve-out memory.
+ */
+static gicv3_redist_ctx_t rdist_ctx __section("._el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section("._el3_tzc_dram");
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ *   - No CPUs implemented in the system use affinity level 3.
+ */
+static uint32_t _gicv3_mpidr_hash(u_register_t mpidr)
+{
+	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+	return plat_core_pos_by_mpidr(mpidr);
+}
+
+static const gicv3_driver_data_t _gic_data __unused = {
+	.gicd_base = PLAT_GICD_BASE_VALUE,
+	.gicr_base = PLAT_GICR_BASE_VALUE,
+	.interrupt_props = _interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+	.mpidr_to_core_pos = _gicv3_mpidr_hash
+};
+
+void __init plat_gic_driver_init(void)
+{
+	/*
+	 * The GICv3 driver is initialized in EL3 and does not need
+	 * to be initialized again in SEL1. This is because the S-EL1
+	 * can use GIC system registers to manage interrupts and does
+	 * not need GIC interface base addresses to be configured.
+	 */
+#if IMAGE_BL31
+	gicv3_driver_init(&_gic_data);
+#endif
+}
+
+/******************************************************************************
+ * common helper to initialize the GIC. Only invoked by BL31
+ *****************************************************************************/
+void __init plat_gic_init(void)
+{
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to enable the GIC CPU interface
+ *****************************************************************************/
+void plat_gic_cpuif_enable(void)
+{
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to disable the GIC CPU interface
+ *****************************************************************************/
+void plat_gic_cpuif_disable(void)
+{
+	gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to initialize the per-cpu redistributor interface in GICv3
+ *****************************************************************************/
+void plat_gic_pcpu_init(void)
+{
+	gicv3_rdistif_init(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helpers to power GIC redistributor interface
+ *****************************************************************************/
+void plat_gic_redistif_on(void)
+{
+	gicv3_rdistif_on(plat_my_core_pos());
+}
+
+void plat_gic_redistif_off(void)
+{
+	gicv3_rdistif_off(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to save & restore the GICv3 on resume from system suspend
+ *****************************************************************************/
+void plat_gic_save(void)
+{
+	/*
+	 * If an ITS is available, save its context before
+	 * the Redistributor using:
+	 * gicv3_its_save_disable(gits_base, &its_ctx[i])
+	 * Additionnaly, an implementation-defined sequence may
+	 * be required to save the whole ITS state.
+	 */
+
+	/*
+	 * Save the GIC Redistributors and ITS contexts before the
+	 * Distributor context. As we only handle SYSTEM SUSPEND API,
+	 * we only need to save the context of the CPU that is issuing
+	 * the SYSTEM SUSPEND call, i.e. the current CPU.
+	 */
+	gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
+
+	/* Save the GIC Distributor context */
+	gicv3_distif_save(&dist_ctx);
+
+	/*
+	 * From here, all the components of the GIC can be safely powered down
+	 * as long as there is an alternate way to handle wakeup interrupt
+	 * sources.
+	 */
+}
+
+void plat_gic_resume(void)
+{
+	/* Restore the GIC Distributor context */
+	gicv3_distif_init_restore(&dist_ctx);
+
+	/*
+	 * Restore the GIC Redistributor and ITS contexts after the
+	 * Distributor context. As we only handle SYSTEM SUSPEND API,
+	 * we only need to restore the context of the CPU that issued
+	 * the SYSTEM SUSPEND call.
+	 */
+	gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
+
+	/*
+	 * If an ITS is available, restore its context after
+	 * the Redistributor using:
+	 * gicv3_its_restore(gits_base, &its_ctx[i])
+	 * An implementation-defined sequence may be required to
+	 * restore the whole ITS state. The ITS must also be
+	 * re-enabled after this sequence has been executed.
+	 */
+}
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
new file mode 100644
index 0000000..a8cbaaf
--- /dev/null
+++ b/plat/amd/versal2/include/def.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEF_H
+#define DEF_H
+
+#include <plat/arm/common/smccc_def.h>
+#include <plat/common/common_def.h>
+
+#define MAX_INTR_EL3			2
+
+/* List all consoles */
+#define CONSOLE_ID_pl011	U(1)
+#define CONSOLE_ID_pl011_0	U(1)
+#define CONSOLE_ID_pl011_1	U(2)
+#define CONSOLE_ID_dcc	U(3)
+
+#define CONSOLE_IS(con)	(CONSOLE_ID_ ## con == CONSOLE)
+
+/* List all platforms */
+#define SILICON		U(0)
+#define SPP			U(1)
+#define EMU			U(2)
+#define QEMU			U(3)
+#define SPP_MMD			U(5)
+#define EMU_MMD			U(6)
+#define QEMU_COSIM		U(7)
+
+/* For platform detection */
+#define PMC_TAP				U(0xF11A0000)
+#define PMC_TAP_VERSION			(PMC_TAP + 0x4U)
+# define PLATFORM_MASK			GENMASK(27U, 24U)
+# define PLATFORM_VERSION_MASK		GENMASK(31U, 28U)
+
+/* Global timer reset */
+#define PSX_CRF			U(0xEC200000)
+#define ACPU0_CLK_CTRL		U(0x10C)
+#define ACPU_CLK_CTRL_CLKACT	BIT(25)
+
+#define RST_APU0_OFFSET		U(0x300)
+#define RST_APU_COLD_RESET	BIT(0)
+#define RST_APU_WARN_RESET	BIT(4)
+#define RST_APU_CLUSTER_COLD_RESET	BIT(8)
+#define RST_APU_CLUSTER_WARM_RESET	BIT(9)
+
+#define PSX_CRF_RST_TIMESTAMP_OFFSET	U(0x33C)
+
+#define APU_PCLI			(0xECB10000ULL)
+#define APU_PCLI_CPU_STEP		(0x30ULL)
+#define APU_PCLI_CLUSTER_CPU_STEP	(4ULL * APU_PCLI_CPU_STEP)
+#define APU_PCLI_CLUSTER_OFFSET		U(0x8000)
+#define APU_PCLI_CLUSTER_STEP		U(0x1000)
+#define PCLI_PREQ_OFFSET		U(0x4)
+#define PREQ_CHANGE_REQUEST		BIT(0)
+#define PCLI_PSTATE_OFFSET		U(0x8)
+#define PCLI_PSTATE_VAL_SET		U(0x48)
+#define PCLI_PSTATE_VAL_CLEAR		U(0x38)
+
+/* Firmware Image Package */
+#define PRIMARY_CPU		U(0)
+
+#define CORE_0_ISR_WAKE_OFFSET			(0x00000020ULL)
+#define APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_WAKE_MASK		(0x00000001U)
+#define CORE_0_IEN_WAKE_OFFSET			(0x00000028ULL)
+#define APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_WAKE_MASK		(0x00000001U)
+#define CORE_0_IDS_WAKE_OFFSET			(0x0000002CULL)
+#define APU_PCIL_CORE_X_IDS_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_WAKE_MASK		(0x00000001U)
+#define CORE_0_ISR_POWER_OFFSET			(0x00000010ULL)
+#define APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_POWER_MASK		U(0x00000001)
+#define CORE_0_IEN_POWER_OFFSET			(0x00000018ULL)
+#define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_POWER_MASK		(0x00000001U)
+#define CORE_0_IDS_POWER_OFFSET			(0x0000001CULL)
+#define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_POWER_MASK		(0x00000001U)
+#define CORE_PWRDN_EN_BIT_MASK			(0x1U)
+
+/*******************************************************************************
+ * memory map related constants
+ ******************************************************************************/
+/* IPP 1.2/SPP 0.9 mapping */
+#define DEVICE0_BASE		U(0xE8000000) /* psx, crl, iou */
+#define DEVICE0_SIZE		U(0x08000000)
+#define DEVICE1_BASE		U(0xE2000000) /* gic */
+#define DEVICE1_SIZE		U(0x00800000)
+#define DEVICE2_BASE		U(0xF1000000) /* uart, pmc_tap */
+#define DEVICE2_SIZE		U(0x01000000)
+#define CRF_BASE		U(0xFD1A0000)
+#define CRF_SIZE		U(0x00600000)
+#define IPI_BASE		U(0xEB300000)
+#define IPI_SIZE		U(0x00100000)
+
+/* CRL */
+#define CRL					U(0xEB5E0000)
+#define CRL_TIMESTAMP_REF_CTRL_OFFSET	U(0x14C)
+#define CRL_RST_TIMESTAMP_OFFSET		U(0x348)
+
+#define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT	(1U << 25U)
+
+/* IOU SCNTRS */
+#define IOU_SCNTRS					U(0xEC920000)
+#define IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET	U(0)
+#define IOU_SCNTRS_BASE_FREQ_OFFSET			U(0x20)
+
+#define IOU_SCNTRS_CONTROL_EN	U(1)
+
+#define APU_CLUSTER0		U(0xECC00000)
+#define APU_RVBAR_L_0		U(0x40)
+#define APU_RVBAR_H_0		U(0x44)
+#define APU_CLUSTER_STEP	U(0x100000)
+
+#define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL	U(0xF1060504)
+
+/*******************************************************************************
+ * IRQ constants
+ ******************************************************************************/
+#define IRQ_SEC_PHY_TIMER	U(29)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE		U(0xF1920000)
+#define UART1_BASE		U(0xF1930000)
+
+#define UART_BAUDRATE	115200
+
+#if CONSOLE_IS(pl011_1)
+#define UART_BASE		UART1_BASE
+#else
+/* Default console is UART0 */
+#define UART_BASE            UART0_BASE
+#endif
+
+#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/plat_ipi.h b/plat/amd/versal2/include/plat_ipi.h
new file mode 100644
index 0000000..503ec1f
--- /dev/null
+++ b/plat/amd/versal2/include/plat_ipi.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal Gen 2 IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_PMC	1U
+#define IPI_ID_APU	2U
+#define IPI_ID_RPU0	3U
+#define IPI_ID_RPU1	4U
+#define IPI_ID_3	5U
+#define IPI_ID_4	6U
+#define IPI_ID_5	7U
+#define IPI_ID_MAX	8U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR	(0xEB3F0000U)
+
+#define IPI_LOCAL_ID		IPI_ID_APU
+#define IPI_REMOTE_ID		IPI_ID_PMC
+
+#define IPI_BUFFER_LOCAL_BASE	(IPI_BUFFER_BASEADDR + (IPI_LOCAL_ID * 0x200U))
+#define IPI_BUFFER_REMOTE_BASE	(IPI_BUFFER_BASEADDR + (IPI_REMOTE_ID * 0x200U))
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	(IPI_LOCAL_ID * 0x40U)
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	(IPI_REMOTE_ID * 0x40U)
+
+#define IPI_BUFFER_MAX_WORDS	8
+
+#define IPI_BUFFER_REQ_OFFSET	0x0U
+#define IPI_BUFFER_RESP_OFFSET	0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table */
+extern void soc_ipi_config_table_init(void);
+
+/*******************************************************************************
+ * IPI registers and bitfields
+ ******************************************************************************/
+#define IPI0_REG_BASE		(0xEB330000U)
+#define IPI0_TRIG_BIT		(1 << 2)
+#define PMC_IPI_TRIG_BIT	(1 << 1)
+#define IPI1_REG_BASE		(0xEB340000U)
+#define IPI1_TRIG_BIT		(1 << 3)
+#define IPI2_REG_BASE		(0xEB350000U)
+#define IPI2_TRIG_BIT		(1 << 4)
+#define IPI3_REG_BASE		(0xEB360000U)
+#define IPI3_TRIG_BIT		(1 << 5)
+#define IPI4_REG_BASE		(0xEB370000U)
+#define IPI4_TRIG_BIT		(1 << 6)
+#define IPI5_REG_BASE		(0xEB380000U)
+#define IPI5_TRIG_BIT		(1 << 7)
+
+#endif /* PLAT_IPI_H */
diff --git a/plat/amd/versal2/include/plat_macros.S b/plat/amd/versal2/include/plat_macros.S
new file mode 100644
index 0000000..d20f693
--- /dev/null
+++ b/plat/amd/versal2/include/plat_macros.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include "../include/platform_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+	.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+	/* ---------------------------------------------
+	 * The below utility macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL31 on platform.
+	 * Expects: GICD base in x16, GICC base in x17
+	 * Clobbers: x0 - x10, sp
+	 * ---------------------------------------------
+	 */
+	.macro _print_gic_regs
+	/* Check for GICv3 system register access */
+	mrs	x7, id_aa64pfr0_el1
+	ubfx	x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+	cmp	x7, #1
+	b.ne	print_gicv2
+
+	/* Check for SRE enable */
+	mrs	x8, ICC_SRE_EL3
+	tst	x8, #ICC_SRE_SRE_BIT
+	b.eq	print_gicv2
+
+	/* Load the icc reg list to x6 */
+	adr	x6, icc_regs
+	/* Load the icc regs to gp regs used by str_in_crash_buf_print */
+	mrs	x8, ICC_HPPIR0_EL1
+	mrs	x9, ICC_HPPIR1_EL1
+	mrs	x10, ICC_CTLR_EL3
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	b	print_gic_common
+
+print_gicv2:
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+print_gic_common:
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant GIC and CCI registers
+	 * whenever an unhandled exception is taken in
+	 * BL31.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	/*
+	 * Empty for now to handle more platforms variant.
+	 * Uncomment it when versions are stable
+	 */
+	/*
+	mov_imm	x17, PLAT_GICD_BASE_VALUE
+	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	_print_gic_regs
+	*/
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/amd/versal2/include/plat_pm_common.h b/plat/amd/versal2/include/plat_pm_common.h
new file mode 100644
index 0000000..5e68472
--- /dev/null
+++ b/plat/amd/versal2/include/plat_pm_common.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains platform specific definitions of commonly used macros data types
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PLAT_PM_COMMON_H
+#define PLAT_PM_COMMON_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include "pm_defs.h"
+
+#define NON_SECURE_FLAG		1U
+#define SECURE_FLAG		0U
+
+#endif /* PLAT_PM_COMMON_H */
diff --git a/plat/amd/versal2/include/plat_private.h b/plat/amd/versal2/include/plat_private.h
new file mode 100644
index 0000000..5a2e5bd
--- /dev/null
+++ b/plat/amd/versal2/include/plat_private.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define SPP_PSXC_MMI_V2_0	U(6)
+#define SPP_PSXC_MMI_V3_0	U(8)
+
+/* MMD */
+#define SPP_PSXC_ISP_AIE_V2_0	U(3)
+#define SPP_PSXC_MMD_AIE_FRZ_EA	U(4)
+#define SPP_PSXC_MMD_AIE_V3_0	U(5)
+
+typedef struct versal_intr_info_type_el3 {
+	uint32_t id;
+	interrupt_type_handler_t handler;
+} versal_intr_info_type_el3_t;
+
+void config_setup(void);
+uint32_t get_uart_clk(void);
+
+const mmap_region_t *plat_get_mmap(void);
+
+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 plat_gic_save(void);
+void plat_gic_resume(void);
+void plat_gic_redistif_on(void);
+void plat_gic_redistif_off(void);
+
+extern uint32_t cpu_clock, platform_id, platform_version;
+void board_detection(void);
+const char *board_name_decode(void);
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+		       uint64_t x4, void *cookie, void *handle, uint64_t flags);
+int32_t sip_svc_setup_init(void);
+/*
+ * Register handler to specific GIC entrance
+ * for INTR_TYPE_EL3 type of interrupt
+ */
+int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/amd/versal2/include/platform_def.h b/plat/amd/versal2/include/platform_def.h
new file mode 100644
index 0000000..090fe46
--- /dev/null
+++ b/plat/amd/versal2/include/platform_def.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include "def.h"
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE		U(0x440)
+
+#define PLATFORM_CLUSTER_COUNT		U(4)
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	U(2) /* 2 CPUs per cluster */
+
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * PLATFORM_CORE_COUNT_PER_CLUSTER)
+
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL31 debug size plus a
+ * little space for growth.
+ */
+#ifndef MEM_BASE
+# define BL31_BASE			U(0xBBF00000)
+# define BL31_LIMIT			U(0xBC000000)
+#else
+# define BL31_BASE			U(MEM_BASE)
+# define BL31_LIMIT			U(MEM_BASE + MEM_SIZE)
+# ifdef MEM_PROGBITS_SIZE
+#  define BL31_PROGBITS_LIMIT		U(MEM_BASE + \
+					  MEM_PROGBITS_SIZE)
+# endif
+#endif
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#ifndef BL32_MEM_BASE
+# define BL32_BASE			U(0x60000000)
+# define BL32_LIMIT			U(0x80000000)
+#else
+# define BL32_BASE			U(BL32_MEM_BASE)
+# define BL32_LIMIT			U(BL32_MEM_BASE + BL32_MEM_SIZE)
+#endif
+
+/*******************************************************************************
+ * BL33 specific defines.
+ ******************************************************************************/
+#ifndef PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE		U(0x8000000)
+#else
+# define PLAT_ARM_NS_IMAGE_BASE		U(PRELOADED_BL33_BASE)
+#endif
+
+/*******************************************************************************
+ * TSP  specific defines.
+ ******************************************************************************/
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
+
+/* ID of the secure physical generic timer interrupt used by the TSP */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+#define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32U)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32U)
+
+#define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
+
+#define PLAT_OCM_BASE			U(0xBBF00000)
+#define PLAT_OCM_LIMIT			U(0xBC000000)
+
+#if defined(TRANSFER_LIST)
+/*
+ * FIXME: This address should come from firmware before TF-A
+ * Having this to make sure the transfer list functionality works
+ */
+#define FW_HANDOFF_BASE         U(0x70000000)
+#define FW_HANDOFF_SIZE         U(0x10000)
+#endif
+
+#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		11
+#else
+#define MAX_MMAP_REGIONS		10
+#endif
+#endif
+
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES			U(12)
+#endif
+
+#define CACHE_WRITEBACK_SHIFT	U(6)
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+#define PLAT_GICD_BASE_VALUE	U(0xE2000000)
+#define PLAT_GICR_BASE_VALUE	U(0xE2060000)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_IPI_IRQ	89
+#define PLAT_VERSAL_IPI_IRQ	PLAT_IPI_IRQ
+
+#define PLAT_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+#define PLAT_G0_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE), \
+
+#define IRQ_MAX		200U
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/amd/versal2/include/scmi.h b/plat/amd/versal2/include/scmi.h
new file mode 100644
index 0000000..0ab8b34
--- /dev/null
+++ b/plat/amd/versal2/include/scmi.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCMI_H
+#define SCMI_H
+
+#include "versal2-scmi.h"
+
+#define SIP_SCMI	(0xC200ffffU)
+#define SMT_BUFFER_BASE	0x7fffe000
+
+void init_scmi_server(void);
+
+#define SCMI_VENDOR	"AMD"
+#define SCMI_PRODUCT	"Versal Gen 2"
+
+#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
new file mode 100644
index 0000000..4d581e4
--- /dev/null
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+/*
+ * Macros IDs for AMD Versal Gen 2
+ *
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#ifndef _VERSAL2_SCMI_H
+#define _VERSAL2_SCMI_H
+
+#define CLK_GEM0_0	0
+#define CLK_GEM0_1	1
+#define CLK_GEM0_2	2
+#define CLK_GEM0_3	3
+#define CLK_GEM0_4	4
+#define CLK_GEM1_0	5
+#define CLK_GEM1_1	6
+#define CLK_GEM1_2	7
+#define CLK_GEM1_3	8
+#define CLK_GEM1_4	9
+#define CLK_SERIAL0_0	10
+#define CLK_SERIAL0_1	11
+#define CLK_SERIAL1_0	12
+#define CLK_SERIAL1_1	13
+#define CLK_UFS0_0	14
+#define CLK_UFS0_1	15
+#define CLK_UFS0_2	16
+#define CLK_USB0_0	17
+#define CLK_USB0_1	18
+#define CLK_USB0_2	19
+#define CLK_USB1_0	20
+#define CLK_USB1_1	21
+#define CLK_USB1_2	22
+#define CLK_MMC0_0	23
+#define CLK_MMC0_1	24
+#define CLK_MMC0_2	25
+#define CLK_MMC1_0	26
+#define CLK_MMC1_1	27
+#define CLK_MMC1_2	28
+#define CLK_TTC0_0	29
+#define CLK_TTC1_0	30
+#define CLK_TTC2_0	31
+#define CLK_TTC3_0	32
+#define CLK_TTC4_0	33
+#define CLK_TTC5_0	34
+#define CLK_TTC6_0	35
+#define CLK_TTC7_0	36
+#define CLK_I2C0_0	37
+#define CLK_I2C1_0	38
+#define CLK_I2C2_0	39
+#define CLK_I2C3_0	40
+#define CLK_I2C4_0	41
+#define CLK_I2C5_0	42
+#define CLK_I2C6_0	43
+#define CLK_I2C7_0	44
+#define CLK_OSPI0_0	45
+#define CLK_QSPI0_0	46
+#define CLK_QSPI0_1	47
+#define CLK_WWDT0_0	48
+#define CLK_WWDT1_0	49
+#define CLK_WWDT2_0	50
+#define CLK_WWDT3_0	51
+#define CLK_ADMA0_0	52
+#define CLK_ADMA0_1	53
+#define CLK_ADMA1_0	54
+#define CLK_ADMA1_1	55
+#define CLK_ADMA2_0	56
+#define CLK_ADMA2_1	57
+#define CLK_ADMA3_0	58
+#define CLK_ADMA3_1	59
+#define CLK_ADMA4_0	60
+#define CLK_ADMA4_1	61
+#define CLK_ADMA5_0	62
+#define CLK_ADMA5_1	63
+#define CLK_ADMA6_0	64
+#define CLK_ADMA6_1	65
+#define CLK_ADMA7_0	66
+#define CLK_ADMA7_1	67
+#define CLK_CAN0_0	68
+#define CLK_CAN0_1	69
+#define CLK_CAN1_0	70
+#define CLK_CAN1_1	71
+#define CLK_CAN2_0	72
+#define CLK_CAN2_1	73
+#define CLK_CAN3_0	74
+#define CLK_CAN3_1	75
+#define CLK_PS_GPIO_0	76
+#define CLK_PMC_GPIO_0	77
+#define CLK_SPI0_0	78
+#define CLK_SPI0_1	79
+#define CLK_SPI1_0	80
+#define CLK_SPI1_1	81
+#define CLK_I3C0_0	82
+#define CLK_I3C1_0	83
+#define CLK_I3C2_0	84
+#define CLK_I3C3_0	85
+#define CLK_I3C4_0	86
+#define CLK_I3C5_0	87
+#define CLK_I3C6_0	88
+#define CLK_I3C7_0	89
+
+#define RESET_GEM0_0	0
+#define RESET_GEM1_0	1
+#define RESET_SERIAL0_0	2
+#define RESET_SERIAL1_0	3
+#define RESET_UFS0_0	4
+#define RESET_I2C0_0	5
+#define RESET_I2C1_0	6
+#define RESET_I2C2_0	7
+#define RESET_I2C3_0	8
+#define RESET_I2C4_0	9
+#define RESET_I2C5_0	10
+#define RESET_I2C6_0	11
+#define RESET_I2C7_0	12
+#define RESET_I2C8_0	13
+#define RESET_OSPI0_0	14
+#define RESET_USB0_0	15
+#define RESET_USB0_1	16
+#define RESET_USB0_2	17
+#define RESET_USB1_0	18
+#define RESET_USB1_1	19
+#define RESET_USB1_2	20
+#define RESET_MMC0_0	21
+#define RESET_MMC1_0	22
+#define RESET_SPI0_0	23
+#define RESET_SPI1_0	24
+#define RESET_QSPI0_0	25
+#define RESET_I3C0_0	26
+#define RESET_I3C1_0	27
+#define RESET_I3C2_0	28
+#define RESET_I3C3_0	29
+#define RESET_I3C4_0	30
+#define RESET_I3C5_0	31
+#define RESET_I3C6_0	32
+#define RESET_I3C7_0	33
+#define RESET_I3C8_0	34
+
+#endif /* _VERSAL2_SCMI_H */
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
new file mode 100644
index 0000000..4faa434
--- /dev/null
+++ b/plat/amd/versal2/plat_psci.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+
+#include <plat_private.h>
+#include <pm_defs.h>
+
+#define PM_RET_ERROR_NOFEATURE U(19)
+#define ALWAYSTRUE true
+
+static uintptr_t _sec_entry;
+
+static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
+{
+	dsb();
+	wfi();
+}
+
+#define MPIDR_MT_BIT	(24)
+
+static int32_t zynqmp_nopmu_pwr_domain_on(u_register_t mpidr)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr) & ~BIT(MPIDR_MT_BIT);
+	uint32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
+	uint32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
+	uintptr_t apu_cluster_base = 0, apu_pcli_base, apu_pcli_cluster = 0;
+	uintptr_t rst_apu_cluster = PSX_CRF + RST_APU0_OFFSET + ((uint64_t)cluster * 0x4U);
+
+	VERBOSE("%s: mpidr: 0x%lx, cpuid: %x, cpu: %x, cluster: %x\n",
+		__func__, mpidr, cpu_id, cpu, cluster);
+
+	if (cpu_id == -1) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
+	if (cluster > 3) {
+		panic();
+	}
+
+	apu_pcli_cluster = APU_PCLI + APU_PCLI_CLUSTER_OFFSET + ((uint64_t)cluster * APU_PCLI_CLUSTER_STEP);
+	apu_cluster_base = APU_CLUSTER0 + ((uint64_t)cluster * APU_CLUSTER_STEP);
+
+	/* Enable clock */
+	mmio_setbits_32(PSX_CRF + ACPU0_CLK_CTRL + ((uint64_t)cluster * 0x4U), ACPU_CLK_CTRL_CLKACT);
+
+	/* Enable cluster states */
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_SET);
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	/* assert core reset */
+	mmio_setbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* program RVBAR */
+	mmio_write_32(apu_cluster_base + APU_RVBAR_L_0 + (cpu << 3),
+		      (uint32_t)_sec_entry);
+	mmio_write_32(apu_cluster_base + APU_RVBAR_H_0 + (cpu << 3),
+		      _sec_entry >> 32);
+
+	/* de-assert core reset */
+	mmio_clrbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* clear cluster resets */
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_WARM_RESET);
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_COLD_RESET);
+
+	apu_pcli_base = APU_PCLI + (APU_PCLI_CPU_STEP * cpu) +
+			(APU_PCLI_CLUSTER_CPU_STEP * cluster);
+
+	mmio_write_32(apu_pcli_base + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_CLEAR);
+	mmio_write_32(apu_pcli_base + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	return PSCI_E_SUCCESS;
+}
+
+static void zynqmp_nopmu_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	plat_gic_cpuif_disable();
+}
+
+static void __dead2 zynqmp_nopmu_system_reset(void)
+{
+	while (ALWAYSTRUE) {
+		wfi();
+	}
+}
+
+static int32_t zynqmp_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	VERBOSE("Validate ns_entry point %lx\n", ns_entrypoint);
+
+	if ((ns_entrypoint) != 0U) {
+		return PSCI_E_SUCCESS;
+	} else {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+}
+
+static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	plat_gic_pcpu_init();
+	plat_gic_cpuif_enable();
+}
+
+static void __dead2 zynqmp_system_off(void)
+{
+	while (ALWAYSTRUE) {
+		wfi();
+	}
+}
+
+static int32_t zynqmp_validate_power_state(uint32_t power_state, psci_power_state_t *req_state)
+{
+	return PSCI_E_SUCCESS;
+}
+
+static const struct plat_psci_ops _nopmc_psci_ops = {
+	.cpu_standby			= zynqmp_cpu_standby,
+	.pwr_domain_on			= zynqmp_nopmu_pwr_domain_on,
+	.pwr_domain_off			= zynqmp_nopmu_pwr_domain_off,
+	.system_reset			= zynqmp_nopmu_system_reset,
+	.validate_ns_entrypoint		= zynqmp_validate_ns_entrypoint,
+	.pwr_domain_on_finish		= zynqmp_pwr_domain_on_finish,
+	.system_off			= zynqmp_system_off,
+	.validate_power_state		= zynqmp_validate_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			    const struct plat_psci_ops **psci_ops)
+{
+	_sec_entry = sec_entrypoint;
+
+	VERBOSE("Setting up entry point %lx\n", _sec_entry);
+
+	*psci_ops = &_nopmc_psci_ops;
+
+	return 0;
+}
+
+int sip_svc_setup_init(void)
+{
+	return 0;
+}
+
+static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id,
+			   uint32_t arg1, uint32_t arg2)
+{
+	VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1);
+	if (ioctl_id == IOCTL_OSPI_MUX_SELECT) {
+		mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
+		return 0;
+	}
+	return PM_RET_ERROR_NOFEATURE;
+}
+
+static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+			      uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+	int32_t ret;
+	uint32_t arg[4], api_id;
+
+	arg[0] = (uint32_t)x1;
+	arg[1] = (uint32_t)(x1 >> 32);
+	arg[2] = (uint32_t)x2;
+	arg[3] = (uint32_t)(x2 >> 32);
+
+	api_id = smc_fid & FUNCID_NUM_MASK;
+	VERBOSE("%s: smc_fid: %x, api_id=0x%x\n", __func__, smc_fid, api_id);
+
+	switch (api_id) {
+	case PM_IOCTL:
+	{
+		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
+		SMC_RET1(handle, (uint64_t)ret);
+	}
+	case PM_GET_CHIPID:
+	{
+		uint32_t idcode, version;
+
+		idcode  = mmio_read_32(PMC_TAP);
+		version = mmio_read_32(PMC_TAP_VERSION);
+		SMC_RET2(handle, ((uint64_t)idcode << 32), version);
+	}
+	default:
+		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4,
+		     void *cookie, void *handle, uint64_t flags)
+{
+	return no_pm_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+}
diff --git a/plat/amd/versal2/plat_topology.c b/plat/amd/versal2/plat_topology.c
new file mode 100644
index 0000000..0763139
--- /dev/null
+++ b/plat/amd/versal2/plat_topology.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+
+static const uint8_t plat_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	1,
+	/* Number of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the second cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the third cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the fourth cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+};
+
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+	return plat_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	uint32_t cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
+	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -3;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in
+	 * one of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
+		return -1;
+	}
+
+	return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+}
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
new file mode 100644
index 0000000..c07fc36
--- /dev/null
+++ b/plat/amd/versal2/platform.mk
@@ -0,0 +1,127 @@
+# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+PLAT_PATH := plat/amd/versal2
+
+# A78 Erratum for SoC
+ERRATA_A78_AE_1941500 := 1
+ERRATA_A78_AE_1951502 := 1
+ERRATA_A78_AE_2376748 := 1
+ERRATA_A78_AE_2395408 := 1
+ERRATA_ABI_SUPPORT    := 1
+
+# Platform Supports Armv8.2 extensions
+ARM_ARCH_MAJOR := 8
+ARM_ARCH_MINOR := 2
+
+override PROGRAMMABLE_RESET_ADDRESS := 1
+PSCI_EXTENDED_STATE_ID := 1
+SEPARATE_CODE_AND_RODATA := 1
+override RESET_TO_BL31 := 1
+PL011_GENERIC_UART := 1
+IPI_CRC_CHECK := 0
+GIC_ENABLE_V4_EXTN :=  0
+GICV3_SUPPORT_GIC600 := 1
+
+override CTX_INCLUDE_AARCH32_REGS    := 0
+
+ifdef MEM_BASE
+    $(eval $(call add_define,MEM_BASE))
+
+    ifndef MEM_SIZE
+        $(error "ATF_BASE defined without ATF_SIZE")
+    endif
+    $(eval $(call add_define,MEM_SIZE))
+
+    ifdef MEM_PROGBITS_SIZE
+        $(eval $(call add_define,MEM_PROGBITS_SIZE))
+    endif
+endif
+
+ifdef BL32_MEM_BASE
+    $(eval $(call add_define,BL32_MEM_BASE))
+
+    ifndef BL32_MEM_SIZE
+        $(error "BL32_BASE defined without BL32_SIZE")
+    endif
+    $(eval $(call add_define,BL32_MEM_SIZE))
+endif
+
+ifdef IPI_CRC_CHECK
+    $(eval $(call add_define,IPI_CRC_CHECK))
+endif
+
+USE_COHERENT_MEM := 0
+HW_ASSISTED_COHERENCY := 1
+
+CONSOLE	?=	pl011
+ifeq (${CONSOLE}, $(filter ${CONSOLE},pl011 pl011_0 pl011_1 dcc))
+else
+  $(error Please define CONSOLE)
+endif
+
+$(eval $(call add_define_val,CONSOLE,CONSOLE_ID_${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/	\
+				-I${PLAT_PATH}/include/				\
+				-Iplat/xilinx/versal/pm_service/
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/arm/dcc/dcc_console.c			\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				${GICV3_SOURCES}				\
+				drivers/arm/pl011/aarch64/pl011_console.S	\
+				plat/common/aarch64/crash_console_helpers.S	\
+				plat/arm/common/arm_common.c			\
+				plat/common/plat_gicv3.c			\
+				${PLAT_PATH}/aarch64/helpers.S			\
+				${PLAT_PATH}/aarch64/common.c			\
+				${PLAT_PATH}/plat_topology.c                    \
+				${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
+				lib/cpus/aarch64/cortex_a78_ae.S		\
+				lib/cpus/aarch64/cortex_a78.S			\
+				plat/common/plat_psci_common.c			\
+				drivers/scmi-msg/base.c				\
+				drivers/scmi-msg/entry.c			\
+				drivers/scmi-msg/smt.c				\
+				drivers/scmi-msg/clock.c			\
+				drivers/scmi-msg/power_domain.c			\
+				drivers/scmi-msg/reset_domain.c			\
+				${PLAT_PATH}/scmi.c
+
+BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.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_PATH}/soc_ipi.c				\
+				plat/xilinx/common/versal.c			\
+				${PLAT_PATH}/bl31_setup.c			\
+				common/fdt_fixup.c				\
+				${LIBFDT_SRCS}					\
+				${PLAT_PATH}/sip_svc_setup.c			\
+				${PLAT_PATH}/gicv3.c
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+# enable the cpu macros for errata abi interface
+CORTEX_A78_AE_H_INC     := 1
+$(eval $(call add_define, CORTEX_A78_AE_H_INC))
+endif
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
new file mode 100644
index 0000000..c3c517a
--- /dev/null
+++ b/plat/amd/versal2/scmi.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+#include <scmi.h>
+
+#include "plat_private.h"
+
+#define HIGH (1)
+#define LOW (0)
+
+struct scmi_clk {
+	unsigned long clock_id;
+	unsigned long rate;
+	const char *name;
+	bool enabled;
+};
+
+#define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled, _rate) \
+	[_scmi_id] = { \
+		.clock_id = (_id), \
+		.name = (_name), \
+		.enabled = (_init_enabled), \
+		.rate = (_rate), \
+	}
+
+static struct scmi_clk scmi0_clock[] = {
+	CLOCK_CELL(CLK_GEM0_0, CLK_GEM0_0, "gem0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_1, CLK_GEM0_1, "gem0_hclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_2, CLK_GEM0_2, "gem0_tx_clk", true, 125000000),
+	CLOCK_CELL(CLK_GEM0_3, CLK_GEM0_3, "gem0_rx_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_4, CLK_GEM0_4, "gem0_tsu_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_0, CLK_GEM1_0, "gem1_pclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_1, CLK_GEM1_1, "gem1_hclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_2, CLK_GEM1_2, "gem1_tx_clk", true, 125000000),
+	CLOCK_CELL(CLK_GEM1_3, CLK_GEM1_3, "gem1_rx_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_4, CLK_GEM1_4, "gem1_tsu_clk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL0_0, CLK_SERIAL0_0, "uart0_uartclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL0_1, CLK_SERIAL0_1, "uart0_apb_pclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL1_0, CLK_SERIAL1_0, "uart1_uartclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL1_1, CLK_SERIAL1_1, "uart1_apb_pclk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_0, CLK_UFS0_0, "ufs_core_clk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 100000000),
+	CLOCK_CELL(CLK_USB0_0, CLK_USB0_0, "usb0_bus_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB0_1, CLK_USB0_1, "usb0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB0_2, CLK_USB0_2, "usb0_dwc_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_0, CLK_USB1_0, "usb1_bus_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_1, CLK_USB1_1, "usb1_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_2, CLK_USB1_2, "usb1_dwc_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_0, CLK_MMC0_0, "mmc0_xin_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_1, CLK_MMC0_1, "mmc0_ahb_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_2, CLK_MMC0_2, "mmc0_gate_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_0, CLK_MMC1_0, "mmc1_xin_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_1, CLK_MMC1_1, "mmc1_ahb_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_2, CLK_MMC1_2, "mmc1_gate_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC0_0, CLK_TTC0_0, "ttc0_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC1_0, CLK_TTC1_0, "ttc1_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC2_0, CLK_TTC2_0, "ttc2_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC3_0, CLK_TTC3_0, "ttc3_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC4_0, CLK_TTC4_0, "ttc4_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC5_0, CLK_TTC5_0, "ttc5_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC6_0, CLK_TTC6_0, "ttc6_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC7_0, CLK_TTC7_0, "ttc7_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C0_0, CLK_I2C0_0, "i2c0_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C1_0, CLK_I2C1_0, "i2c1_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C2_0, CLK_I2C2_0, "i2c2_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C3_0, CLK_I2C3_0, "i2c3_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C4_0, CLK_I2C4_0, "i2c4_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C5_0, CLK_I2C5_0, "i2c5_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C6_0, CLK_I2C6_0, "i2c6_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C7_0, CLK_I2C7_0, "i2c7_clk", true, 100000000),
+	CLOCK_CELL(CLK_OSPI0_0, CLK_OSPI0_0, "ospi0_clk", true, 100000000),
+	CLOCK_CELL(CLK_QSPI0_0, CLK_QSPI0_0, "qpsi0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_QSPI0_1, CLK_QSPI0_1, "qspi0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT0_0, CLK_WWDT0_0, "wwdt0_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT1_0, CLK_WWDT1_0, "wwdt1_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT2_0, CLK_WWDT2_0, "wwdt2_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT3_0, CLK_WWDT3_0, "wwdt3_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA0_0, CLK_ADMA0_0, "adma0_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA0_1, CLK_ADMA0_1, "adma0_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA1_0, CLK_ADMA1_0, "adma1_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA1_1, CLK_ADMA1_1, "adma1_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA2_0, CLK_ADMA2_0, "adma2_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA2_1, CLK_ADMA2_1, "adma2_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA3_0, CLK_ADMA3_0, "adma3_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA3_1, CLK_ADMA3_1, "adma3_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA4_0, CLK_ADMA4_0, "adma4_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA4_1, CLK_ADMA4_1, "adma4_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA5_0, CLK_ADMA5_0, "adma5_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA5_1, CLK_ADMA5_1, "adma5_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA6_0, CLK_ADMA6_0, "adma6_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA6_1, CLK_ADMA6_1, "adma6_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA7_0, CLK_ADMA7_0, "adma7_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA7_1, CLK_ADMA7_1, "adma7_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN0_0, CLK_CAN0_0, "can0_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN0_1, CLK_CAN0_1, "can0_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN1_0, CLK_CAN1_0, "can1_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN1_1, CLK_CAN1_1, "can1_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN2_0, CLK_CAN2_0, "can2_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN2_1, CLK_CAN2_1, "can2_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN3_0, CLK_CAN3_0, "can3_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN3_1, CLK_CAN3_1, "can3_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_PS_GPIO_0, CLK_PS_GPIO_0, "ps_gpio_clk", true, 100000000),
+	CLOCK_CELL(CLK_PMC_GPIO_0, CLK_PMC_GPIO_0, "pmc_gpio_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI0_0, CLK_SPI0_0, "spi0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI0_1, CLK_SPI0_1, "spi0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_SPI1_0, CLK_SPI1_0, "spi1_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI1_1, CLK_SPI1_1, "spi1_pclk", true, 100000000),
+	CLOCK_CELL(CLK_I3C0_0, CLK_I3C0_0, "i3c0_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C1_0, CLK_I3C1_0, "i3c1_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C2_0, CLK_I3C2_0, "i3c2_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C3_0, CLK_I3C3_0, "i3c3_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C4_0, CLK_I3C4_0, "i3c4_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C5_0, CLK_I3C5_0, "i3c5_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C6_0, CLK_I3C6_0, "i3c6_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C7_0, CLK_I3C7_0, "i3c7_clk", true, 100000000),
+};
+
+/*
+ * struct scmi_reset - Data for the exposed reset controller
+ * @reset_id: Reset identifier in RCC reset driver
+ * @name: Reset string ID exposed to agent
+ */
+struct scmi_reset {
+	unsigned long reset_id;
+	const char *name;
+};
+
+#define RESET_CELL(_scmi_id, _id, _name) \
+	[_scmi_id] = { \
+		.reset_id = (_id), \
+		.name = (_name), \
+	}
+
+static struct scmi_reset scmi0_reset[] = {
+	RESET_CELL(RESET_GEM0_0, RESET_GEM0_0, "gem0"),
+	RESET_CELL(RESET_GEM1_0, RESET_GEM1_0, "gem1"),
+	RESET_CELL(RESET_SERIAL0_0, RESET_SERIAL0_0, "serial0"),
+	RESET_CELL(RESET_SERIAL1_0, RESET_SERIAL1_0, "serial1"),
+	RESET_CELL(RESET_UFS0_0, RESET_UFS0_0, "ufs0"),
+	RESET_CELL(RESET_I2C0_0, RESET_I2C0_0, "i2c0"),
+	RESET_CELL(RESET_I2C1_0, RESET_I2C1_0, "i2c1"),
+	RESET_CELL(RESET_I2C2_0, RESET_I2C2_0, "i2c2"),
+	RESET_CELL(RESET_I2C3_0, RESET_I2C3_0, "i2c3"),
+	RESET_CELL(RESET_I2C4_0, RESET_I2C4_0, "i2c4"),
+	RESET_CELL(RESET_I2C5_0, RESET_I2C5_0, "i2c5"),
+	RESET_CELL(RESET_I2C6_0, RESET_I2C6_0, "i2c6"),
+	RESET_CELL(RESET_I2C7_0, RESET_I2C7_0, "i2c7"),
+	RESET_CELL(RESET_I2C8_0, RESET_I2C8_0, "i2c8"),
+	RESET_CELL(RESET_OSPI0_0, RESET_OSPI0_0, "ospi"),
+	RESET_CELL(RESET_USB0_0, RESET_USB0_0, "usb0_0"),
+	RESET_CELL(RESET_USB0_1, RESET_USB0_1, "usb0_1"),
+	RESET_CELL(RESET_USB0_2, RESET_USB0_2, "usb0_2"),
+	RESET_CELL(RESET_USB1_0, RESET_USB1_0, "usb1_0"),
+	RESET_CELL(RESET_USB1_1, RESET_USB1_1, "usb1_1"),
+	RESET_CELL(RESET_USB1_2, RESET_USB1_2, "usb1_2"),
+	RESET_CELL(RESET_MMC0_0, RESET_MMC0_0, "mmc0"),
+	RESET_CELL(RESET_MMC1_0, RESET_MMC1_0, "mmc1"),
+	RESET_CELL(RESET_SPI0_0, RESET_SPI0_0, "spi0"),
+	RESET_CELL(RESET_SPI1_0, RESET_SPI1_0, "spi1"),
+	RESET_CELL(RESET_QSPI0_0, RESET_QSPI0_0, "qspi"),
+	RESET_CELL(RESET_I3C0_0, RESET_I3C0_0, "i3c0"),
+	RESET_CELL(RESET_I3C1_0, RESET_I3C1_0, "i3c1"),
+	RESET_CELL(RESET_I3C2_0, RESET_I3C2_0, "i3c2"),
+	RESET_CELL(RESET_I3C3_0, RESET_I3C3_0, "i3c3"),
+	RESET_CELL(RESET_I3C4_0, RESET_I3C4_0, "i3c4"),
+	RESET_CELL(RESET_I3C5_0, RESET_I3C5_0, "i3c5"),
+	RESET_CELL(RESET_I3C6_0, RESET_I3C6_0, "i3c6"),
+	RESET_CELL(RESET_I3C7_0, RESET_I3C7_0, "i3c7"),
+	RESET_CELL(RESET_I3C8_0, RESET_I3C8_0, "i3c8"),
+};
+
+struct scmi_resources {
+	struct scmi_clk *clock;
+	size_t clock_count;
+	struct scmi_reset *reset;
+	size_t reset_count;
+
+};
+
+static const struct scmi_resources resources[] = {
+	[0] = {
+		.clock = scmi0_clock,
+		.clock_count = ARRAY_SIZE(scmi0_clock),
+		.reset = scmi0_reset,
+		.reset_count = ARRAY_SIZE(scmi0_reset),
+	},
+};
+
+static const struct scmi_resources *find_resource(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(resources));
+
+	return &resources[agent_id];
+}
+
+static struct scmi_clk *clk_find(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n = 0U;
+	struct scmi_clk *ret = NULL;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->clock_count; n++) {
+			if (n == scmi_id) {
+				ret = &resource->clock[n];
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+size_t plat_scmi_clock_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t ret;
+
+	if (resource == NULL) {
+		ret = 0U;
+	} else {
+		VERBOSE("SCMI: CLK: %d clocks\n", (unsigned int)resource->clock_count);
+
+		ret = resource->clock_count;
+	}
+	return ret;
+}
+
+const char *plat_scmi_clock_get_name(unsigned int agent_id, unsigned int scmi_id)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	const char *ret;
+
+	if (clock == NULL) {
+		ret = NULL;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_name: %s\n", scmi_id, clock->name);
+
+		ret = clock->name;
+	}
+	return ret;
+};
+
+/* Called by Linux */
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
+				    unsigned long *array, size_t *nb_elts,
+				    uint32_t start_idx)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+
+	if (clock == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (start_idx > 0) {
+		return SCMI_OUT_OF_RANGE;
+	}
+
+	if (array == NULL) {
+		*nb_elts = 1U;
+	} else if (*nb_elts == 1U) {
+		*array = clock->rate;
+		VERBOSE("SCMI: CLK: id: %d, clk_name: %s, get_rate %lu\n",
+		     scmi_id, clock->name, *array);
+	} else {
+		return SCMI_GENERIC_ERROR;
+	}
+
+	return SCMI_SUCCESS;
+}
+
+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, unsigned int scmi_id)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	unsigned long ret;
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_rate: %lu\n", scmi_id, clock->rate);
+		ret = clock->rate;
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
+				 unsigned long rate)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	unsigned long ret = UL(SCMI_SUCCESS);
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, set_rate: %lu\n", scmi_id, rate);
+		clock->rate = rate;
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	int32_t ret;
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_state: %d\n", scmi_id, clock->enabled);
+
+		if (clock->enabled) {
+			ret = HIGH;
+		} else {
+			ret = LOW;
+		}
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
+				  bool enable_not_disable)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	int32_t ret;
+
+	if (clock == NULL) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		if (enable_not_disable) {
+			if (!clock->enabled) {
+				VERBOSE("SCMI: clock: %u enable\n", scmi_id);
+				clock->enabled = true;
+			}
+		} else {
+			if (clock->enabled) {
+				VERBOSE("SCMI: clock: %u disable\n", scmi_id);
+				clock->enabled = false;
+			}
+		}
+
+		VERBOSE("SCMI: CLK: id: %d, set_state: %d\n", scmi_id, clock->enabled);
+
+		ret = SCMI_SUCCESS;
+	}
+
+	return ret;
+}
+
+
+/*
+ * Platform SCMI reset domains
+ */
+static struct scmi_reset *find_reset(unsigned int agent_id,
+					 unsigned int scmi_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->reset_count; n++) {
+			if (n == scmi_id) {
+				return &resource->reset[n];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return NULL;
+	}
+
+	return reset->name;
+}
+
+size_t plat_scmi_rstd_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+
+	if (resource == NULL) {
+		return 0U;
+	}
+
+	return resource->reset_count;
+}
+
+int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
+				uint32_t state)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	/* Supports only reset with context loss */
+	if (state != 0U) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI reset on ID %lu/%s\n",
+	       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+	return SCMI_SUCCESS;
+}
+
+int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
+				 bool assert_not_deassert)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (assert_not_deassert) {
+		NOTICE("SCMI reset %lu/%s set\n",
+		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+	} else {
+		NOTICE("SCMI reset %lu/%s release\n",
+		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+	}
+
+	return SCMI_SUCCESS;
+}
+
+/* Currently only one channel is supported. Expectation is that channel 0 is used by NS SW */
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	VERBOSE("%d: SCMI asking for channel\n", agent_id);
+
+	/* Just in case that code is reused */
+	return &scmi_channel[agent_id];
+}
+
+/* Base protocol implementations */
+const char *plat_scmi_vendor_name(void)
+{
+	return SCMI_VENDOR;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return SCMI_PRODUCT;
+}
+
+/* Currently supporting Clocks and Reset Domains */
+static const uint8_t plat_protocol_list[] = {
+	SCMI_PROTOCOL_ID_BASE,
+	SCMI_PROTOCOL_ID_CLOCK,
+	SCMI_PROTOCOL_ID_RESET_DOMAIN,
+	/*
+	 *SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	 *SCMI_PROTOCOL_ID_SENSOR,
+	 */
+	0U /* Null termination */
+};
+
+size_t plat_scmi_protocol_count(void)
+{
+	const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
+
+	VERBOSE("SCMI: Protocol count: %d\n", (int32_t)count);
+
+	return count;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
+{
+	return plat_protocol_list;
+}
+
+void init_scmi_server(void)
+{
+	size_t i;
+	int32_t ret;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+
+	INFO("SCMI: Server initialized\n");
+
+	if (platform_id == QEMU) {
+		/* default setting is for QEMU */
+	} else if (platform_id == SPP) {
+		for (i = 0U; i < ARRAY_SIZE(scmi0_clock); i++) {
+
+			/* Keep i2c on 100MHz to calculate rates properly */
+			if (i >= CLK_I2C0_0 && i <= CLK_I2C7_0)
+				continue;
+			/*
+			 * SPP supports multiple versions.
+			 * The cpu_clock value is set to corresponding SPP
+			 * version in early platform setup, resuse the same
+			 * value here.
+			 */
+			ret = plat_scmi_clock_set_rate(0, i, cpu_clock);
+			if (ret < 0) {
+				NOTICE("Failed to set clock rate for SPP scmi_id=%ld\n", i);
+			}
+		}
+	} else {
+		 /* Making MISRA C 2012 15.7 compliant */
+	}
+}
diff --git a/plat/amd/versal2/sip_svc_setup.c b/plat/amd/versal2/sip_svc_setup.c
new file mode 100644
index 0000000..6850030
--- /dev/null
+++ b/plat/amd/versal2/sip_svc_setup.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
+
+#include <errno.h>
+#include <inttypes.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+#include <scmi.h>
+#include <tools_share/uuid.h>
+
+#include "ipi_mailbox_svc.h"
+#include "plat_private.h"
+#include "pm_svc_main.h"
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_UID		(0x8200ff01U)
+#define SIP_SVC_VERSION	(0x8200ff03U)
+
+/* SiP Service Calls version numbers */
+#define SIP_SVC_VERSION_MAJOR		(0U)
+#define SIP_SVC_VERSION_MINOR		(1U)
+
+/* These macros are used to identify PM calls from the SMC function ID */
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
+#define PM_FID_VALUE	0u
+#define IPI_FID_VALUE	0x1000u
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
+
+/* SiP Service UUID */
+DEFINE_SVC_UUID2(_sip_uuid,
+		0x0499eb70, 0x5ed0, 0x11ee, 0xb3, 0x0a,
+		0x87, 0xd1, 0x1d, 0x4f, 0x8a, 0x9b);
+
+/**
+ * sip_svc_setup() - Setup SiP Service
+ *
+ * Return: 0 on success, negative error code on failure.
+ *
+ */
+static int32_t sip_svc_setup(void)
+{
+	return sip_svc_setup_init();
+}
+
+/*
+ * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ *
+ * Handler for all SiP SMC calls. Handles standard SIP requests
+ * and calls PM SMC handler if the call is for a PM-API function.
+ */
+static uintptr_t sip_svc_smc_handler(uint32_t 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)
+{
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if ((smc_fid & SIP_FID_MASK) != 0) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
+		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let IPI SMC handler deal with IPI-related requests if platform */
+	if (is_ipi_fid(smc_fid)) {
+		return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	switch (smc_fid) {
+	case SIP_SVC_UID:
+		SMC_UUID_RET(handle, _sip_uuid);
+
+	case SIP_SVC_VERSION:
+		SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
+
+	case SIP_SCMI:
+		if (platform_id != EMU) {
+			scmi_smt_fastcall_smc_entry(0);
+			SMC_RET1(handle, 0);
+		}
+		WARN("SCMI is not working on EMU\n");
+		SMC_RET1(handle, SMC_UNK);
+	default:
+		WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+/* Register PM Service Calls as runtime service */
+DECLARE_RT_SVC(
+		sip_svc,
+		OEN_SIP_START,
+		OEN_SIP_END,
+		SMC_TYPE_FAST,
+		sip_svc_setup,
+		sip_svc_smc_handler);
diff --git a/plat/amd/versal2/soc_ipi.c b/plat/amd/versal2/soc_ipi.c
new file mode 100644
index 0000000..85d1bcd
--- /dev/null
+++ b/plat/amd/versal2/soc_ipi.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * SoC IPI agent registers access management
+ */
+
+#include <lib/utils_def.h>
+#include <plat_ipi.h>
+
+/* versal2 ipi configuration table */
+static const struct ipi_config ipi_table[IPI_ID_MAX] = {
+	/* A78 IPI */
+	[IPI_ID_APU] = {
+		.ipi_bit_mask = IPI0_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* PMC IPI */
+	[IPI_ID_PMC] = {
+		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = IPI_SECURE_MASK,
+	},
+
+	/* RPU0 IPI */
+	[IPI_ID_RPU0] = {
+		.ipi_bit_mask = IPI1_TRIG_BIT,
+		.ipi_reg_base = IPI1_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* RPU1 IPI */
+	[IPI_ID_RPU1] = {
+		.ipi_bit_mask = IPI2_TRIG_BIT,
+		.ipi_reg_base = IPI2_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI3 IPI */
+	[IPI_ID_3] = {
+		.ipi_bit_mask = IPI3_TRIG_BIT,
+		.ipi_reg_base = IPI3_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI4 IPI */
+	[IPI_ID_4] = {
+		.ipi_bit_mask = IPI4_TRIG_BIT,
+		.ipi_reg_base = IPI4_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI5 IPI */
+	[IPI_ID_5] = {
+		.ipi_bit_mask = IPI5_TRIG_BIT,
+		.ipi_reg_base = IPI5_REG_BASE,
+		.secure_only = 0,
+	},
+};
+
+/**
+ * soc_ipi_config_table_init() - Initialize versal2 IPI configuration data.
+ */
+void soc_ipi_config_table_init(void)
+{
+	ipi_config_table_init(ipi_table, ARRAY_SIZE(ipi_table));
+}
diff --git a/plat/amd/versal2/tsp/tsp-versal2.mk b/plat/amd/versal2/tsp/tsp-versal2.mk
new file mode 100644
index 0000000..422ed17
--- /dev/null
+++ b/plat/amd/versal2/tsp/tsp-versal2.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal Gen 2 platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk
index 64b35d6..aadecab 100644
--- a/plat/amlogic/axg/platform.mk
+++ b/plat/amlogic/axg/platform.mk
@@ -85,10 +85,10 @@
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
diff --git a/plat/amlogic/g12a/platform.mk b/plat/amlogic/g12a/platform.mk
index 799e106..15658d3 100644
--- a/plat/amlogic/g12a/platform.mk
+++ b/plat/amlogic/g12a/platform.mk
@@ -81,10 +81,10 @@
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
diff --git a/plat/amlogic/gxl/platform.mk b/plat/amlogic/gxl/platform.mk
index 0a88482..31063a9 100644
--- a/plat/amlogic/gxl/platform.mk
+++ b/plat/amlogic/gxl/platform.mk
@@ -81,10 +81,10 @@
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
index b9ff8bf..5bf6a3f 100644
--- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
+++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x83000000>;
-			max-size = <0x01000000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h
index 9f3df1e..b134911 100644
--- a/plat/arm/board/a5ds/include/platform_def.h
+++ b/plat/arm/board/a5ds/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -208,6 +208,9 @@
  */
 #define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x01000000)
+
 /*******************************************************************************
  * BL1 specific defines.
  * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index c9c248f..82401db 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -41,8 +41,12 @@
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_HCX			:= 2
+ENABLE_FEAT_MTE2		:= 2
+ENABLE_FEAT_TCR2		:= 2
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_TRF_FOR_NS		:= 2
+ENABLE_SME_FOR_NS		:= 2
+ENABLE_SME2_FOR_NS		:= 2
 
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
@@ -77,8 +81,8 @@
 				lib/cpus/aarch64/neoverse_n1.S			\
 				lib/cpus/aarch64/neoverse_n2.S			\
 				lib/cpus/aarch64/neoverse_v1.S			\
-				lib/cpus/aarch64/cortex_chaberton.S		\
-				lib/cpus/aarch64/cortex_blackhawk.S
+				lib/cpus/aarch64/cortex_a725.S		\
+				lib/cpus/aarch64/cortex_x925.S
 
 # AArch64/AArch32 cores
 	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S	\
@@ -127,8 +131,16 @@
 $(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31))
 $(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31))
 
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
+        AXF_LDFLAGS	+=	-Wl,--build-id=none -mno-fix-cortex-a53-843419
+else
+        AXF_LDFLAGS	+=	--build-id=none
+endif
+
+AXF_LDFLAGS += -nostdlib -no-pie
+
 bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld
-	$(ECHO) "  LD      $@"
-	$(Q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -s -n -o ${BUILD_PLAT}/bl31.axf
+	$(s)echo "  LD      $@"
+	$(q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} ${AXF_LDFLAGS} -s -n -o ${BUILD_PLAT}/bl31.axf
 
 all: bl31.axf
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 655a4d2..4a2572f 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -219,6 +219,15 @@
 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
 							NON_TRUSTED_NV_CTR_ID);
+#if defined(ARM_COT_cca)
+	} else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) {
+		/*
+		 * Use Trusted NV counter for platforms that don't support
+		 * the CCA NV Counter.
+		 */
+		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+							TRUSTED_NV_CTR_ID);
+#endif
 	} else {
 		return 1;
 	}
diff --git a/plat/arm/board/corstone1000/common/corstone1000_helpers.S b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
index cbe27c3..a4ca9fe 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_helpers.S
+++ b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,8 +21,34 @@
 	 * --------------------------------------------------------------------
 	 */
 func plat_secondary_cold_boot_setup
+#if defined(CORSTONE1000_FVP_MULTICORE)
+
+	/* Calculate the address of our hold entry */
+	bl	plat_my_core_pos
+	lsl	x0, x0, #CORSTONE1000_SECONDARY_CORE_HOLD_SHIFT
+	mov_imm	x2, CORSTONE1000_SECONDARY_CORE_HOLD_BASE
+
+	/* Set the wait state for the secondary core */
+	mov_imm	x3, CORSTONE1000_SECONDARY_CORE_STATE_WAIT
+	str	x3, [x2, x0]
+	dmb	ish
+
+	/* Poll until the primary core signals to go  */
+poll_mailbox:
+	ldr	x1, [x2, x0]
+	cmp	x1, #CORSTONE1000_SECONDARY_CORE_STATE_WAIT
+	beq	1f
+	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
+	ldr	x1, [x0]
+	br	x1
+1:
+	wfe
+	b	poll_mailbox
+#else
 cb_panic:
 	b	cb_panic
+#endif
+
 endfunc plat_secondary_cold_boot_setup
 
 	/* ---------------------------------------------------------------------
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
index 4b0a791..ee07605 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,9 +25,52 @@
 	}
 }
 
+#if defined(CORSTONE1000_FVP_MULTICORE)
+int corstone1000_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 PSCI_E_SUCCESS;
+	}
+	return PSCI_E_INVALID_ADDRESS;
+}
+
+int corstone1000_pwr_domain_on(u_register_t mpidr)
+{
+	int core_index = plat_core_pos_by_mpidr(mpidr);
+	uint64_t *secondary_core_hold_base = (uint64_t *)CORSTONE1000_SECONDARY_CORE_HOLD_BASE;
+
+	/* Validate the core index */
+	if (core_index < 0 || core_index > PLATFORM_CORE_COUNT) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+	secondary_core_hold_base[core_index] = CORSTONE1000_SECONDARY_CORE_STATE_GO;
+	dsbish();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+void corstone1000_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	(void)target_state;
+	plat_arm_gic_init();
+}
+#endif
+
 plat_psci_ops_t plat_arm_psci_pm_ops = {
+#if defined(CORSTONE1000_FVP_MULTICORE)
+	.pwr_domain_on = corstone1000_pwr_domain_on,
+	.pwr_domain_on_finish = corstone1000_pwr_domain_on_finish,
+	.validate_ns_entrypoint = corstone1000_validate_ns_entrypoint,
+	.system_reset = corstone1000_system_reset,
+#else
+	.validate_ns_entrypoint = NULL,
 	.system_reset = corstone1000_system_reset,
-	.validate_ns_entrypoint = NULL
+#endif
 };
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
index 6953b89..e3f3268 100644
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
@@ -262,6 +262,19 @@
 #define ARM_LOCAL_STATE_OFF	U(2)
 
 #define PLAT_ARM_TRUSTED_MAILBOX_BASE	ARM_TRUSTED_SRAM_BASE
+
+#if defined(CORSTONE1000_FVP_MULTICORE)
+/* The secondary core entrypoint address points to bl31_warm_entrypoint
+ * and the address size is 8 bytes */
+#define CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE    UL(0x8)
+
+#define CORSTONE1000_SECONDARY_CORE_HOLD_BASE	(PLAT_ARM_TRUSTED_MAILBOX_BASE + \
+						CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE)
+#define CORSTONE1000_SECONDARY_CORE_STATE_WAIT	ULL(0)
+#define CORSTONE1000_SECONDARY_CORE_STATE_GO	ULL(1)
+#define CORSTONE1000_SECONDARY_CORE_HOLD_SHIFT	ULL(3)
+#endif
+
 #define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
 
 #define PLAT_ARM_NS_IMAGE_BASE		(ARM_NS_SHARED_RAM_BASE)
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index fd08803..9d44a14 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -36,6 +36,13 @@
 $(eval $(call add_define,CORSTONE1000_WITH_BL32))
 endif
 
+ENABLE_MULTICORE       :=      0
+ifneq ($(filter ${TARGET_PLATFORM}, fvp),)
+ifeq (${ENABLE_MULTICORE},1)
+$(eval $(call add_define,CORSTONE1000_FVP_MULTICORE))
+endif
+endif
+
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
 
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 8efc238..46fb44a 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -6,9 +6,10 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/gicv3.h>
-#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
@@ -29,6 +30,21 @@
 	 */
 func plat_secondary_cold_boot_setup
 #ifndef EL3_PAYLOAD_BASE
+
+	/* --------------------------------------------
+	 * Check if core supports powering down, if it
+	 * supports power down then set core power down
+	 * bit before requesting for the cores to be
+	 * powered off from base power controller.
+	 * ---------------------------------------------
+	 */
+	bl	check_cpupwrctrl_el1_is_available
+	cbz	x0, base_power_off
+
+	mrs	x1, CPUPWRCTLR_EL1
+	orr	x1, x1, #CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CPUPWRCTLR_EL1, x1
+
 	/* ---------------------------------------------
 	 * Power down this cpu.
 	 * TODO: Do we need to worry about powering the
@@ -37,6 +53,7 @@
 	 * loader zeroes out the zi section.
 	 * ---------------------------------------------
 	 */
+base_power_off:
 	mrs	x0, mpidr_el1
 	mov_imm	x1, PWRC_BASE
 	str	w0, [x1, #PPOFFR_OFF]
diff --git a/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi b/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
new file mode 100644
index 0000000..9c8328b
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#if COT_DESC_IN_DTB
+	#if defined(ARM_COT_cca)
+		#include "cca_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_dualroot)
+		#include "dualroot_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_tbbr)
+		#include "tbbr_cot_descriptors.dtsi"
+	#endif
+#endif
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 4adf5d5..5d58731 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x07f00000>;
-			max-size = <0x00100000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 			secondary-load-address = <0x0 0x82000000>;
 		};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index ee6c260..9fba4af 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,10 +92,20 @@
 
 	memory@1 {
 		device_type = "ns-memory";
-		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
-		      <0x0 0x88000000 0x0 0x10000000>;
+		reg = <0x0 0x80000000 0x0 0x7c000000>,
+		      <0x8 0x80000000 0x1 0x80000000>,
+		      <0x00008800 0x80000000 0x0 0x7f000000>;
 	};
 
+	memory@2 {
+		device_type = "device-memory";
+		reg = <0x0 0x1c090000 0x0 0x40000>, /* UART */
+		      <0x0 0x2bfe0000 0x0 0x20000>, /* SMMUv3TestEngine */
+		      <0x0 0x2a490000 0x0 0x20000>, /* SP805 Trusted Watchdog */
+		      <0x0 0x1c130000 0x0 0x10000>; /* Virtio block device */
+	};
+
+
 #if MEASURED_BOOT
 #include "event_log.dtsi"
 #endif
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
index 17a2fd1..d90544b 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
@@ -1,8 +1,9 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 /dts-v1/;
 
 #define	AFF	00
@@ -15,7 +16,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -59,6 +60,17 @@
 
 	memory@6000000 {
 		device_type = "memory";
-		reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+		reg = <0x0 0x6000000 0x0 0x2000000>; /* Trusted DRAM */
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x0 0x10000000>;
+	};
+
+	memory@0 {
+		device_type = "device-memory";
+		reg = <0x0 0x1c090000 0x0 0x40000>; /* UART */
 	};
 };
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 9eb2177..b1d3bc1 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -103,13 +103,7 @@
 #endif /* ARM_BL2_SP_LIST_DTS */
 	};
 
-#if COT_DESC_IN_DTB
-	#if defined(ARM_COT_cca)
-		#include "cca_cot_descriptors.dtsi"
-	#elif defined(ARM_COT_tbbr)
-		#include "tbbr_cot_descriptors.dtsi"
-	#endif
-#endif
+#include "fvp_cot_desc.dtsi"
 
 #if MEASURED_BOOT
 	#include "event_log.dtsi"
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index 477ae27..f14dbff 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-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/arm/common/plat_arm.h>
 #include <tools_share/zero_oid.h>
 
@@ -15,9 +16,9 @@
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
-	{ FW_CONFIG_ID, EVLOG_FW_CONFIG_STRING, PCR_0 },
-	{ TB_FW_CONFIG_ID, EVLOG_TB_FW_CONFIG_STRING, PCR_0 },
-	{ BL2_IMAGE_ID, EVLOG_BL2_STRING, PCR_0 },
+	{ FW_CONFIG_ID, MBOOT_FW_CONFIG_STRING, PCR_0 },
+	{ TB_FW_CONFIG_ID, MBOOT_TB_FW_CONFIG_STRING, PCR_0 },
+	{ BL2_IMAGE_ID, MBOOT_BL2_IMAGE_STRING, PCR_0 },
 
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 369bcb4..8bf7dad 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #if defined(ARM_COT_cca)
 #include <tools_share/cca_oid.h>
 #else
@@ -28,27 +29,27 @@
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
-	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
-	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
-	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
-	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
-	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
-	{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
+	{ RMM_IMAGE_ID, MBOOT_RMM_IMAGE_STRING, PCR_0},
 
 #if defined(SPD_spmd)
-	{ SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
-	{ SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
-	{ SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
-	{ SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
-	{ SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
-	{ SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
-	{ SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
-	{ SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
+	{ SP_PKG1_ID, MBOOT_SP1_STRING, PCR_0 },
+	{ SP_PKG2_ID, MBOOT_SP2_STRING, PCR_0 },
+	{ SP_PKG3_ID, MBOOT_SP3_STRING, PCR_0 },
+	{ SP_PKG4_ID, MBOOT_SP4_STRING, PCR_0 },
+	{ SP_PKG5_ID, MBOOT_SP5_STRING, PCR_0 },
+	{ SP_PKG6_ID, MBOOT_SP6_STRING, PCR_0 },
+	{ SP_PKG7_ID, MBOOT_SP7_STRING, PCR_0 },
+	{ SP_PKG8_ID, MBOOT_SP8_STRING, PCR_0 },
 #endif
 
 	{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 97d000e..ebdd80d 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -20,8 +20,6 @@
 
 #include "fvp_private.h"
 
-static struct transfer_list_header *ns_tl __unused;
-
 #if ENABLE_RME
 /*
  * The GPT library might modify the gpt regions structure to optimize
@@ -50,6 +48,11 @@
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
+	struct transfer_list_entry *te __unused;
+
+#if TRANSFER_LIST
+	arg0 = arg3;
+#endif
 	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
 
 	/* Initialize the platform config for future decision making */
@@ -60,10 +63,6 @@
 {
 	arm_bl2_platform_setup();
 
-#if TRANSFER_LIST
-	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE);
-	assert(ns_tl != NULL);
-#endif
 	/* Initialize System level generic or SP804 timer */
 	fvp_timer_init();
 }
@@ -81,16 +80,15 @@
 struct bl_params *plat_get_next_bl_params(void)
 {
 	struct bl_params *arm_bl_params;
-	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
-	struct transfer_list_entry *te __unused;
 	bl_mem_params_node_t *param_node __unused;
+	const struct dyn_cfg_dtb_info_t *fw_config_info __unused;
+	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+	entry_point_info_t *ep __unused;
+	uint32_t next_exe_img_id __unused;
+	uintptr_t fw_config_base __unused;
 
 	arm_bl_params = arm_get_next_bl_params();
 
-#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
-	const struct dyn_cfg_dtb_info_t *fw_config_info;
-	uintptr_t fw_config_base = 0UL;
-
 #if __aarch64__
 	/* Get BL31 image node */
 	param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
@@ -100,6 +98,15 @@
 #endif /* __aarch64__ */
 	assert(param_node != NULL);
 
+#if TRANSFER_LIST
+	arm_bl_params->head = &param_node->params_node_mem;
+	arm_bl_params->head->ep_info = &param_node->ep_info;
+	arm_bl_params->head->image_id = param_node->image_id;
+
+	arm_bl2_setup_next_ep_info(param_node);
+#elif !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
+	fw_config_base = 0UL;
+
 	/* Update the next image's ep info with the FW config address */
 	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
 	assert(fw_config_info != NULL);
@@ -113,49 +120,29 @@
 	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
 	assert(param_node != NULL);
 
-#if TRANSFER_LIST
-	/* Update BL33's ep info with NS HW config address  */
-	te = transfer_list_find(ns_tl, TL_TAG_FDT);
-	assert(te != NULL);
-
-	param_node->ep_info.args.arg1 = TRANSFER_LIST_SIGNATURE |
-					REGISTER_CONVENTION_VERSION_MASK;
-	param_node->ep_info.args.arg2 = 0;
-	param_node->ep_info.args.arg3 = (uintptr_t)ns_tl;
-	param_node->ep_info.args.arg0 =
-		te ? (uintptr_t)transfer_list_entry_data(te) : 0;
-#else
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
 
 	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
 #endif /* TRANSFER_LIST */
-#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
 }
 
 int bl2_plat_handle_post_image_load(unsigned int image_id)
 {
-#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
+#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE && !TRANSFER_LIST
 	if (image_id == HW_CONFIG_ID) {
-		const struct dyn_cfg_dtb_info_t *hw_config_info;
+		const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
 		struct transfer_list_entry *te __unused;
+		bl_mem_params_node_t *param_node __unused;
 
-		const bl_mem_params_node_t *param_node =
-			get_bl_mem_params_node(image_id);
+		param_node = get_bl_mem_params_node(image_id);
 		assert(param_node != NULL);
 
 		hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 		assert(hw_config_info != NULL);
 
-#if TRANSFER_LIST
-		/* Update BL33's ep info with NS HW config address  */
-		te = transfer_list_add(ns_tl, TL_TAG_FDT,
-				       param_node->image_info.image_size,
-				       (void *)hw_config_info->config_addr);
-		assert(te != NULL);
-#else
 		memcpy((void *)hw_config_info->secondary_config_addr,
 		       (void *)hw_config_info->config_addr,
 		       (size_t)param_node->image_info.image_size);
@@ -166,9 +153,8 @@
 		 */
 		flush_dcache_range(hw_config_info->secondary_config_addr,
 				   param_node->image_info.image_size);
-#endif /* TRANSFER_LIST */
 	}
-#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
+#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE && !TRANSFER_LIST*/
 
 	return arm_bl2_plat_handle_post_image_load(image_id);
 }
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index e46dbc9..e087565 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,16 +1,19 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
+
+#include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/smmu_v3.h>
 #include <fconf_hw_config_getter.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/mmio.h>
+
 #include <plat/arm/common/arm_config.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -25,6 +28,9 @@
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
+#if TRANSFER_LIST
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
+#else
 #if !RESET_TO_BL31 && !RESET_TO_BL2
 	const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
 
@@ -48,8 +54,8 @@
 	assert(hw_config_info->secondary_config_addr != 0UL);
 	arg2 = hw_config_info->secondary_config_addr;
 #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */
-
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+#endif /* TRANSFER_LIST */
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
@@ -73,10 +79,22 @@
 	fvp_timer_init();
 
 	/* On FVP RevC, initialize SMMUv3 */
-	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
-		smmuv3_init(PLAT_FVP_SMMUV3_BASE);
+	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) {
+		if (smmuv3_security_init(PLAT_FVP_SMMUV3_BASE) != 0) {
+			/*
+			 * Don't proceed for smmuv3 initialization if the
+			 * security init failed.
+			 */
+			return;
+		}
+		/* SMMUv3 initialization failure is not fatal */
+		if (smmuv3_init(PLAT_FVP_SMMUV3_BASE) != 0) {
+			WARN("Failed initializing SMMU.\n");
+		}
+	}
 }
 
+#if !TRANSFER_LIST
 void __init bl31_plat_arch_setup(void)
 {
 	int rc __unused;
@@ -131,6 +149,7 @@
 	}
 #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1 */
 }
+#endif /* TRANSFER_LIST */
 
 unsigned int plat_get_syscnt_freq2(void)
 {
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index beae242..5557d59 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -5,6 +5,7 @@
  */
 
 #include <assert.h>
+#include <string.h>
 
 #include <common/debug.h>
 #include <drivers/arm/cci.h>
@@ -33,6 +34,14 @@
 #define FVP_GICV2		1
 #define FVP_GICV3		2
 
+/* Defines for RMM Console*/
+#define FVP_RMM_CONSOLE_BASE		UL(0x1c0c0000)
+#define FVP_RMM_CONSOLE_BAUD		UL(115200)
+#define FVP_RMM_CONSOLE_CLK_IN_HZ	UL(14745600)
+#define FVP_RMM_CONSOLE_NAME		"pl011"
+
+#define FVP_RMM_CONSOLE_COUNT		UL(1)
+
 /*******************************************************************************
  * arm_config holds the characteristics of the differences between the three FVP
  * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
@@ -72,10 +81,15 @@
 
 #if TRANSFER_LIST
 #ifdef FW_NS_HANDOFF_BASE
-#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, \
-					  FW_HANDOFF_SIZE,    \
-					  MT_MEMORY | MT_RW | MT_NS)
+#define MAP_FW_NS_HANDOFF                                             \
+	MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \
+			MT_MEMORY | MT_RW | MT_NS)
 #endif
+#ifdef PLAT_ARM_EL3_FW_HANDOFF_BASE
+#define MAP_EL3_FW_HANDOFF                            \
+	MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \
+			PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS)
+#endif
 #endif
 
 /*
@@ -156,7 +170,10 @@
 	ARM_MAP_OPTEE_CORE_MEM,
 	ARM_OPTEE_PAGEABLE_LOAD_MEM,
 #endif
-	{0}
+#ifdef MAP_EL3_FW_HANDOFF
+	MAP_EL3_FW_HANDOFF,
+#endif
+	{ 0 }
 };
 #endif
 #ifdef IMAGE_BL2U
@@ -193,7 +210,10 @@
 #ifdef MAP_FW_NS_HANDOFF
 	MAP_FW_NS_HANDOFF,
 #endif
-	{0}
+#ifdef MAP_EL3_FW_HANDOFF
+	MAP_EL3_FW_HANDOFF,
+#endif
+	{ 0 }
 };
 
 #if defined(IMAGE_BL31) && SPM_MM
@@ -552,8 +572,9 @@
 
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
-	uint64_t checksum, num_banks;
+	uint64_t checksum, num_banks, num_consoles;
 	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
 
 	assert(manifest != NULL);
 
@@ -561,43 +582,74 @@
 	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
 	assert(num_banks <= ARM_DRAM_NUM_BANKS);
 
+	/* Set number of consoles */
+	num_consoles = FVP_RMM_CONSOLE_COUNT;
+
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
 	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
 
 	/*
-	 * Array ns_dram_banks[] follows ns_dram_info structure:
+	 * Boot Manifest structure illustration, with two dram banks and
+	 * a single console.
 	 *
-	 * +-----------------------------------+
-	 * |  offset  |   field   |  comment   |
-	 * +----------+-----------+------------+
-	 * |    0     |  version  | 0x00000002 |
-	 * +----------+-----------+------------+
-	 * |    4     |  padding  | 0x00000000 |
-	 * +----------+-----------+------------+
-	 * |    8     | plat_data |    NULL    |
-	 * +----------+-----------+------------+
-	 * |    16    | num_banks |            |
-	 * +----------+-----------+            |
-	 * |    24    |   banks   | plat_dram  |
-	 * +----------+-----------+            |
-	 * |    32    | checksum  |            |
-	 * +----------+-----------+------------+
-	 * |    40    |  base 0   |            |
-	 * +----------+-----------+   bank[0]  |
-	 * |    48    |  size 0   |            |
-	 * +----------+-----------+------------+
-	 * |    56    |  base 1   |            |
-	 * +----------+-----------+   bank[1]  |
-	 * |    64    |  size 1   |            |
-	 * +----------+-----------+------------+
+	 * +----------------------------------------+
+	 * | offset |     field      |    comment   |
+	 * +--------+----------------+--------------+
+	 * |   0    |    version     |  0x00000003  |
+	 * +--------+----------------+--------------+
+	 * |   4    |    padding     |  0x00000000  |
+	 * +--------+----------------+--------------+
+	 * |   8    |   plat_data    |     NULL     |
+	 * +--------+----------------+--------------+
+	 * |   16   |   num_banks    |              |
+	 * +--------+----------------+              |
+	 * |   24   |     banks      |   plat_dram  |
+	 * +--------+----------------+              |
+	 * |   32   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   40   |  num_consoles  |              |
+	 * +--------+----------------+              |
+	 * |   48   |    consoles    | plat_console |
+	 * +--------+----------------+              |
+	 * |   56   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   64   |     base 0     |              |
+	 * +--------+----------------+    bank[0]   |
+	 * |   72   |     size 0     |              |
+	 * +--------+----------------+--------------+
+	 * |   80   |     base 1     |              |
+	 * +--------+----------------+    bank[1]   |
+	 * |   88   |     size 1     |              |
+	 * +--------+----------------+--------------+
+	 * |   96   |     base       |              |
+	 * +--------+----------------+              |
+	 * |   104  |   map_pages    |              |
+	 * +--------+----------------+              |
+	 * |   112  |     name       |              |
+	 * +--------+----------------+  consoles[0] |
+	 * |   120  |   clk_in_hz    |              |
+	 * +--------+----------------+              |
+	 * |   128  |   baud_rate    |              |
+	 * +--------+----------------+              |
+	 * |   136  |     flags      |              |
+	 * +--------+----------------+--------------+
 	 */
+
 	bank_ptr = (struct ns_dram_bank *)
-			((uintptr_t)&manifest->plat_dram.checksum +
-			sizeof(manifest->plat_dram.checksum));
+			(((uintptr_t)manifest) + sizeof(*manifest));
+	console_ptr = (struct console_info *)
+			((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
 
 	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) * manifest->plat_console.num_consoles) +
+		(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks)) <= ARM_EL3_RMM_SHARED_SIZE);
 
 	/* Calculate checksum of plat_dram structure */
 	checksum = num_banks + (uint64_t)bank_ptr;
@@ -617,6 +669,26 @@
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;
 
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	memset((void *)console_ptr, '\0', sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].map_pages = 1;
+	console_ptr[0].base = FVP_RMM_CONSOLE_BASE;
+	console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ;
+	console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD;
+
+	strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, RMM_CONSOLE_MAX_NAME_LEN-1UL);
+
+	/* Update checksum */
+	checksum += console_ptr[0].base + console_ptr[0].map_pages +
+		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+
+	/* Checksum must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
 	return 0;
 }
 #endif	/* ENABLE_RME */
diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c
index d56f510..605f0ff 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-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,12 +9,10 @@
 
 #include <common/desc_image_load.h>
 #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 <plat/common/platform.h>
 
 extern event_log_metadata_t fvp_event_log_metadata[];
-extern struct rss_mboot_metadata fvp_rss_mboot_metadata[];
 
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
diff --git a/plat/arm/board/fvp/fvp_cpu_errata.mk b/plat/arm/board/fvp/fvp_cpu_errata.mk
index b8fa4ea..b26fa80 100644
--- a/plat/arm/board/fvp/fvp_cpu_errata.mk
+++ b/plat/arm/board/fvp/fvp_cpu_errata.mk
@@ -1,63 +1,32 @@
 #
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-
-#/*
-# * TODO: below lines of code to be removed
-# * after abi and framework are synchronized
-# */
+# Flags to enable the cpu structures in the Errata ABI file
+# file: services/std_svc/errata_abi/errata_abi_main.c. This is specifically
+# for platforms that need to enable errata based on non-arm interconnect IP.
 
 ifeq (${ERRATA_ABI_SUPPORT}, 1)
-# enable the cpu macros for errata abi interface
-ifeq (${ARCH}, aarch64)
-ifeq (${HW_ASSISTED_COHERENCY}, 0)
-CORTEX_A35_H_INC	:= 1
-CORTEX_A53_H_INC	:= 1
-CORTEX_A57_H_INC	:= 1
-CORTEX_A72_H_INC	:= 1
-CORTEX_A73_H_INC	:= 1
-$(eval $(call add_define, CORTEX_A35_H_INC))
-$(eval $(call add_define, CORTEX_A53_H_INC))
-$(eval $(call add_define, CORTEX_A57_H_INC))
-$(eval $(call add_define, CORTEX_A72_H_INC))
-$(eval $(call add_define, CORTEX_A73_H_INC))
-else
+ifeq (${ERRATA_NON_ARM_INTERCONNECT}, 1)
 ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0)
-CORTEX_A76_H_INC	:= 1
-CORTEX_A77_H_INC	:= 1
+CORTEX_A710_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
-CORTEX_A710_H_INC	:= 1
-CORTEX_A715_H_INC 	:= 1
 CORTEX_A78C_H_INC	:= 1
-CORTEX_X2_H_INC		:= 1
-$(eval $(call add_define, CORTEX_A76_H_INC))
-$(eval $(call add_define, CORTEX_A77_H_INC))
+CORTEX_X3_H_INC		:= 1
+CORTEX_X4_H_INC		:= 1
+NEOVERSE_N2_H_INC	:= 1
+NEOVERSE_V1_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A710_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))
-$(eval $(call add_define, CORTEX_A710_H_INC))
-$(eval $(call add_define, CORTEX_A715_H_INC))
 $(eval $(call add_define, CORTEX_A78C_H_INC))
-$(eval $(call add_define, CORTEX_X2_H_INC))
-endif
-CORTEX_A55_H_INC	:= 1
-CORTEX_A75_H_INC	:= 1
-$(eval $(call add_define, CORTEX_A55_H_INC))
-$(eval $(call add_define, CORTEX_A75_H_INC))
+$(eval $(call add_define, CORTEX_X3_H_INC))
+$(eval $(call add_define, CORTEX_X4_H_INC))
+$(eval $(call add_define, NEOVERSE_N2_H_INC))
+$(eval $(call add_define, NEOVERSE_V1_H_INC))
 endif
-else
-CORTEX_A32_H_INC	:= 1
-$(eval $(call add_define, CORTEX_A32_H_INC))
 endif
 endif
diff --git a/plat/arm/board/fvp/fvp_cpu_pwr.c b/plat/arm/board/fvp/fvp_cpu_pwr.c
new file mode 100644
index 0000000..f2771c2
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_pwr.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if __aarch64__
+
+#include <aem_generic.h>
+#include <arch_helpers.h>
+#include <cortex_a35.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a78_ae.h>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <lib/utils_def.h>
+#include <neoverse_e1.h>
+
+bool check_cpupwrctrl_el1_is_available(void)
+{
+	/* Poupulate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
+	const unsigned int midr_no_cpupwrctl[] = {
+		BASE_AEM_MIDR,
+		CORTEX_A35_MIDR,
+		CORTEX_A53_MIDR,
+		CORTEX_A57_MIDR,
+		CORTEX_A72_MIDR,
+		CORTEX_A73_MIDR,
+		CORTEX_A78_AE_MIDR,
+		NEOVERSE_E1_MIDR
+	};
+	unsigned int midr = (unsigned int)read_midr();
+
+	for (unsigned int i = 0U; i < ARRAY_SIZE(midr_no_cpupwrctl); i++) {
+		if (midr_no_cpupwrctl[i] == midr) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+#endif /* __arch64__ */
diff --git a/plat/arm/board/fvp/fvp_el3_spmc.c b/plat/arm/board/fvp/fvp_el3_spmc.c
index 6b44f63..c57a244 100644
--- a/plat/arm/board/fvp/fvp_el3_spmc.c
+++ b/plat/arm/board/fvp/fvp_el3_spmc.c
@@ -7,23 +7,14 @@
 
 #include <platform_def.h>
 
-/*
- * On the FVP platform when using the EL3 SPMC implementation allocate the
- * datastore for tracking shared memory descriptors in the TZC DRAM section
- * to ensure sufficient storage can be allocated.
- * Provide an implementation of the accessor method to allow the datastore
- * details to be retrieved by the SPMC.
- * The SPMC will take care of initializing the memory region.
- */
+IMPORT_SYM(uintptr_t, __PLAT_SPMC_SHMEM_DATASTORE_START__, DATASTORE_BASE);
 
-#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 512 * 1024
-
-__section(".arm_el3_tzc_dram") static uint8_t
+__section(".arm_el3_tzc_dram") __unused static uint8_t
 plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
 
 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
 {
-	*datastore = plat_spmc_shmem_datastore;
+	*datastore = (uint8_t *)DATASTORE_BASE;
 	*size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
 	return 0;
 }
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 5fb3141..83b52fc 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,96 +10,205 @@
 
 #include <plat/common/platform.h>
 
+/*
+ * This is the CBOR serialization of the CCA platform token described at
+ * https://git.trustedfirmware.org/TF-M/tf-m-tools/+/refs/heads/main/iat-verifier/tests/data/cca_example_platform_token.yaml
+ */
 static const uint8_t sample_platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
+	0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0,
+	0x59, 0x05, 0x7a, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+	0x61, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x43, 0x43, 0x41, 0x2d, 0x53, 0x53, 0x44, 0x2f,
+	0x31, 0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20,
+	0xb5, 0x97, 0x3c, 0xb6, 0x8b, 0xaa, 0x9f, 0xc5,
+	0x55, 0x58, 0x78, 0x6b, 0x7e, 0xc6, 0x7f, 0x69,
+	0xe4, 0x0d, 0xf5, 0xba, 0x5a, 0xa9, 0x21, 0xcd,
+	0x0c, 0x27, 0xf4, 0x05, 0x87, 0xa0, 0x11, 0xea,
+	0x19, 0x09, 0x5c, 0x58, 0x20, 0x7f, 0x45, 0x4c,
 	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e,
 	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
 	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
+	0x02, 0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b,
+	0x0a, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
+	0x12, 0x11, 0x10, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b,
+	0x1a, 0x19, 0x18, 0x19, 0x09, 0x61, 0x44, 0xcf,
+	0xcf, 0xcf, 0xcf, 0x19, 0x09, 0x5b, 0x19, 0x30,
+	0x03, 0x19, 0x09, 0x62, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0x19, 0x09, 0x60, 0x78,
+	0x3a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+	0x2f, 0x76, 0x65, 0x72, 0x61, 0x69, 0x73, 0x6f,
+	0x6e, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d,
+	0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x65,
+	0x72, 0x61, 0x69, 0x73, 0x6f, 0x6e, 0x2f, 0x76,
+	0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x19, 0x09, 0x5f, 0x8d, 0xa4,
+	0x01, 0x69, 0x52, 0x53, 0x45, 0x5f, 0x42, 0x4c,
+	0x31, 0x5f, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x9a, 0x27, 0x1f, 0x2a, 0x91, 0x6b, 0x0b,
+	0x6e, 0xe6, 0xce, 0xcb, 0x24, 0x26, 0xf0, 0xb3,
+	0x20, 0x6e, 0xf0, 0x74, 0x57, 0x8b, 0xe5, 0x5d,
+	0x9b, 0xc9, 0x4f, 0x6f, 0x3f, 0xe3, 0xab, 0x86,
+	0xaa, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x52, 0x53, 0x45,
+	0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x53, 0xc2, 0x34, 0xe5, 0xe8, 0x47,
+	0x2b, 0x6a, 0xc5, 0x1c, 0x1a, 0xe1, 0xca, 0xb3,
+	0xfe, 0x06, 0xfa, 0xd0, 0x53, 0xbe, 0xb8, 0xeb,
+	0xfd, 0x89, 0x77, 0xb0, 0x10, 0x65, 0x5b, 0xfd,
+	0xd3, 0xc3, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x65, 0x52, 0x53,
+	0x45, 0x5f, 0x53, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x11, 0x21, 0xcf, 0xcc, 0xd5, 0x91, 0x3f,
+	0x0a, 0x63, 0xfe, 0xc4, 0x0a, 0x6f, 0xfd, 0x44,
+	0xea, 0x64, 0xf9, 0xdc, 0x13, 0x5c, 0x66, 0x63,
+	0x4b, 0xa0, 0x01, 0xd1, 0x0b, 0xcf, 0x43, 0x02,
+	0xa2, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x15, 0x71, 0xb5, 0xec, 0x78, 0xbd, 0x68,
+	0x51, 0x2b, 0xf7, 0x83, 0x0b, 0xb6, 0xa2, 0xa4,
+	0x4b, 0x20, 0x47, 0xc7, 0xdf, 0x57, 0xbc, 0xe7,
+	0x9e, 0xb8, 0xa1, 0xc0, 0xe5, 0xbe, 0xa0, 0xa5,
+	0x01, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x10, 0x15, 0x9b, 0xaf, 0x26, 0x2b, 0x43,
+	0xa9, 0x2d, 0x95, 0xdb, 0x59, 0xda, 0xe1, 0xf7,
+	0x2c, 0x64, 0x51, 0x27, 0x30, 0x16, 0x61, 0xe0,
+	0xa3, 0xce, 0x4e, 0x38, 0xb2, 0x95, 0xa9, 0x7c,
+	0x58, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50,
+	0x5f, 0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x10, 0x12, 0x2e, 0x85, 0x6b, 0x3f,
+	0xcd, 0x49, 0xf0, 0x63, 0x63, 0x63, 0x17, 0x47,
+	0x61, 0x49, 0xcb, 0x73, 0x0a, 0x1a, 0xa1, 0xcf,
+	0xaa, 0xd8, 0x18, 0x55, 0x2b, 0x72, 0xf5, 0x6d,
+	0x6f, 0x68, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43,
+	0x50, 0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20,
+	0xf1, 0x4b, 0x49, 0x87, 0x90, 0x4b, 0xcb, 0x58,
+	0x14, 0xe4, 0x45, 0x9a, 0x05, 0x7e, 0xd4, 0xd2,
+	0x0f, 0x58, 0xa6, 0x33, 0x15, 0x22, 0x88, 0xa7,
+	0x61, 0x21, 0x4d, 0xcd, 0x28, 0x78, 0x0b, 0x56,
+	0x02, 0x58, 0x20, 0xaa, 0x67, 0xa1, 0x69, 0xb0,
+	0xbb, 0xa2, 0x17, 0xaa, 0x0a, 0xa8, 0x8a, 0x65,
+	0x34, 0x69, 0x20, 0xc8, 0x4c, 0x42, 0x44, 0x7c,
+	0x36, 0xba, 0x5f, 0x7e, 0xa6, 0x5f, 0x42, 0x2c,
+	0x1f, 0xe5, 0xd8, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x41,
+	0x50, 0x5f, 0x42, 0x4c, 0x33, 0x31, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x2e, 0x6d, 0x31, 0xa5,
+	0x98, 0x3a, 0x91, 0x25, 0x1b, 0xfa, 0xe5, 0xae,
+	0xfa, 0x1c, 0x0a, 0x19, 0xd8, 0xba, 0x3c, 0xf6,
+	0x01, 0xd0, 0xe8, 0xa7, 0x06, 0xb4, 0xcf, 0xa9,
+	0x66, 0x1a, 0x6b, 0x8a, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x63,
+	0x52, 0x4d, 0x4d, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0xa1, 0xfb, 0x50, 0xe6, 0xc8, 0x6f, 0xae,
+	0x16, 0x79, 0xef, 0x33, 0x51, 0x29, 0x6f, 0xd6,
+	0x71, 0x34, 0x11, 0xa0, 0x8c, 0xf8, 0xdd, 0x17,
+	0x90, 0xa4, 0xfd, 0x05, 0xfa, 0xe8, 0x68, 0x81,
+	0x64, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x69, 0x48, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x1a, 0x25, 0x24, 0x02,
+	0x97, 0x2f, 0x60, 0x57, 0xfa, 0x53, 0xcc, 0x17,
+	0x2b, 0x52, 0xb9, 0xff, 0xca, 0x69, 0x8e, 0x18,
+	0x31, 0x1f, 0xac, 0xd0, 0xf3, 0xb0, 0x6e, 0xca,
+	0xae, 0xf7, 0x9e, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x69,
+	0x46, 0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
+	0x47, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79, 0x63,
+	0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15,
+	0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d,
+	0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa,
+	0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20, 0x9a,
+	0x92, 0xad, 0xbc, 0x0c, 0xee, 0x38, 0xef, 0x65,
+	0x8c, 0x71, 0xce, 0x1b, 0x1b, 0xf8, 0xc6, 0x56,
+	0x68, 0xf1, 0x66, 0xbf, 0xb2, 0x13, 0x64, 0x4c,
+	0x89, 0x5c, 0xcb, 0x1a, 0xd0, 0x7a, 0x25, 0x06,
+	0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35, 0x36,
+	0xa4, 0x01, 0x6c, 0x54, 0x42, 0x5f, 0x46, 0x57,
+	0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05,
+	0x58, 0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53,
+	0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2,
+	0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60,
+	0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f,
+	0x7a, 0xa3, 0x02, 0x58, 0x20, 0x23, 0x89, 0x03,
+	0x18, 0x0c, 0xc1, 0x04, 0xec, 0x2c, 0x5d, 0x8b,
+	0x3f, 0x20, 0xc5, 0xbc, 0x61, 0xb3, 0x89, 0xec,
+	0x0a, 0x96, 0x7d, 0xf8, 0xcc, 0x20, 0x8c, 0xdc,
+	0x7c, 0xd4, 0x54, 0x17, 0x4f, 0x06, 0x67, 0x73,
+	0x68, 0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01,
+	0x6d, 0x53, 0x4f, 0x43, 0x5f, 0x46, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0xe6, 0xc2, 0x1e, 0x8d,
+	0x26, 0x0f, 0xe7, 0x18, 0x82, 0xde, 0xbd, 0xb3,
+	0x39, 0xd2, 0x40, 0x2a, 0x2c, 0xa7, 0x64, 0x85,
+	0x29, 0xbc, 0x23, 0x03, 0xf4, 0x86, 0x49, 0xbc,
+	0xe0, 0x38, 0x00, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0x58, 0x60, 0x21,
+	0x51, 0x20, 0x92, 0xd6, 0xd0, 0x2a, 0xe6, 0xbe,
+	0x2f, 0xe3, 0x93, 0x0e, 0xa5, 0x1f, 0xd6, 0x98,
+	0x96, 0x32, 0x24, 0x56, 0xe9, 0xdf, 0xc7, 0x32,
+	0x5e, 0x0b, 0x78, 0x68, 0xb6, 0x90, 0x73, 0x2a,
+	0x0c, 0x0f, 0x07, 0x77, 0xc1, 0x15, 0x40, 0x4b,
+	0xe1, 0xfc, 0x83, 0x9b, 0x7d, 0x30, 0x4f, 0x4f,
+	0xe6, 0xfa, 0x46, 0xae, 0x12, 0xa3, 0x08, 0x3a,
+	0xcf, 0x24, 0x06, 0x67, 0x91, 0x06, 0xbf, 0xae,
+	0x50, 0x31, 0x79, 0xdd, 0x50, 0x33, 0x49, 0x12,
+	0xbf, 0xc6, 0xda, 0x33, 0x6d, 0xd6, 0x18, 0x25,
+	0x43, 0x54, 0x4d, 0xb5, 0x88, 0xd6, 0xae, 0x67,
+	0x35, 0x7a, 0xfd, 0xb0, 0x5f, 0x95, 0xb7
 };
 
 /*
  * Get the hardcoded platform attestation token as FVP does not support
- * RSS.
+ * RSE.
  */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
 				   uintptr_t hash, size_t hash_size)
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
index fe0cde7..150608d 100644
--- a/plat/arm/board/fvp/fvp_realm_attest_key.c
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -19,7 +19,7 @@
 
 /*
  * Get the hardcoded delegated realm attestation key as FVP
- * does not support RSS.
+ * does not support RSE.
  */
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type)
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 971e35b..1db0502 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,7 @@
 	 * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
 	 * RESET_TO_BL2 systems.
 	 */
-#if RESET_TO_SP_MIN || RESET_TO_BL31 || RESET_TO_BL2
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || RESET_TO_BL2 || IMAGE_BL1
 	cluster_count = FVP_CLUSTER_COUNT;
 	cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
 #else
@@ -106,8 +106,10 @@
 	if (thread_id >= FVP_MAX_PE_PER_CPU)
 		return -1;
 
+#if !IMAGE_BL1
 	if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
 		return -1;
+#endif /* IMAGE_BL1 */
 
 	/*
 	 * Core position calculation for FVP platform depends on the MT bit in
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 4b69d66..56de8b8 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -99,6 +99,20 @@
 					FVP_DTB_DRAM_MAP_SIZE,		\
 					MT_MEMORY | MT_RO | MT_NS)
 
+/*
+ * On the FVP platform when using the EL3 SPMC implementation allocate the
+ * datastore for tracking shared memory descriptors in the TZC DRAM section
+ * to ensure sufficient storage can be allocated.
+ * Provide an implementation of the accessor method to allow the datastore
+ * details to be retrieved by the SPMC.
+ * The SPMC will take care of initializing the memory region.
+ */
+
+#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 512 * 1024
+
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x4000)
+
 #if SPMC_AT_EL3
 /*
  * Number of Secure Partitions supported.
@@ -129,8 +143,14 @@
 #define PLAT_ARM_NS_IMAGE_BASE		(ARM_DRAM1_BASE + UL(0x8000000))
 
 #if TRANSFER_LIST
-#define FW_HANDOFF_SIZE			0x4000
-#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - FW_HANDOFF_SIZE)
+#define PLAT_ARM_FW_HANDOFF_SIZE	U(0x5000)
+
+#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - PLAT_ARM_FW_HANDOFF_SIZE)
+#define PLAT_ARM_EL3_FW_HANDOFF_BASE	ARM_BL_RAM_BASE
+#define PLAT_ARM_EL3_FW_HANDOFF_LIMIT	PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE
+
+#else
+#define PLAT_ARM_FW_HANDOFF_SIZE	U(0)
 #endif
 
 /*
@@ -255,9 +275,15 @@
  * BL2 and BL1-RW.
  * Size of the BL31 PROGBITS increases as the SRAM size increases.
  */
+#if TRANSFER_LIST
+#define PLAT_ARM_MAX_BL31_SIZE                              \
+	(PLAT_ARM_TRUSTED_SRAM_SIZE - ARM_SHARED_RAM_SIZE - \
+	 PLAT_ARM_FW_HANDOFF_SIZE - ARM_L0_GPT_SIZE)
+#else
 #define PLAT_ARM_MAX_BL31_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
 					 ARM_SHARED_RAM_SIZE - \
 					 ARM_FW_CONFIGS_SIZE - ARM_L0_GPT_SIZE)
+#endif /* TRANSFER_LIST */
 #endif /* RESET_TO_BL31 */
 
 #ifndef __aarch64__
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 35086e4..af2b78d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -7,76 +7,58 @@
 include common/fdt_wrappers.mk
 
 # Use the GICv3 driver on the FVP by default
-FVP_USE_GIC_DRIVER	:= FVP_GICV3
+FVP_USE_GIC_DRIVER		:= FVP_GICV3
 
 # Default cluster count for FVP
-FVP_CLUSTER_COUNT	:= 2
+FVP_CLUSTER_COUNT		:= 2
 
 # Default number of CPUs per cluster on FVP
 FVP_MAX_CPUS_PER_CLUSTER	:= 4
 
 # Default number of threads per CPU on FVP
-FVP_MAX_PE_PER_CPU	:= 1
+FVP_MAX_PE_PER_CPU		:= 1
 
 # Disable redistributor frame of inactive/fused CPU cores by marking it as read
 # only; enable redistributor frames of all CPU cores by default.
-FVP_GICR_REGION_PROTECTION		:= 0
+FVP_GICR_REGION_PROTECTION	:= 0
 
-FVP_DT_PREFIX		:= fvp-base-gicv3-psci
+FVP_DT_PREFIX			:= fvp-base-gicv3-psci
 
-# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
+# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
 # the FVP platform. This option defaults to 256.
-FVP_TRUSTED_SRAM_SIZE	:= 256
+FVP_TRUSTED_SRAM_SIZE		:= 256
 
 # Macro to enable helpers for running SPM tests. Disabled by default.
 PLAT_TEST_SPM	:= 0
 
-# This is a very trickly TEMPORARY fix. Enabling ALL features exceeds BL31's
-# progbits limit. We need a way to build all useful configurations while waiting
-# on the fvp to increase its SRAM size. The problem is twofild:
-#  1. the cleanup that introduced these enables cleaned up tf-a a little too
-#     well and things that previously (incorrectly) were enabled, no longer are.
-#     A bunch of CI configs build subtly incorrectly and this combo makes it
-#     necessary to forcefully and unconditionally enable them here.
-#  2. the progbits limit is exceeded only when the tsp is involved. However,
-#     there are tsp CI configs that run on very high architecture revisions so
-#     disabling everything isn't an option.
-# The fix is to enable everything, as before. When the tsp is included, though,
-# we need to slim the size down. In that case, disable all optional features,
-# that will not be present in CI when the tsp is.
-# Similarly, DRTM support is only tested on v8.0 models. Disable everything just
-# for it.
-# TODO: make all of this unconditional (or only base the condition on
-# ARM_ARCH_* when the makefile supports it).
-ifneq (${DRTM_SUPPORT}, 1)
-ifneq (${SPD}, tspd)
-	ENABLE_FEAT_AMU			:= 2
-	ENABLE_FEAT_AMUv1p1		:= 2
-	ENABLE_FEAT_HCX			:= 2
-	ENABLE_FEAT_RNG			:= 2
-	ENABLE_FEAT_TWED		:= 2
-	ENABLE_FEAT_GCS			:= 2
+# By default dont build CPUs with no FVP model.
+BUILD_CPUS_WITH_NO_FVP_MODEL	?= 0
+
+ENABLE_FEAT_AMU			:= 2
+ENABLE_FEAT_AMUv1p1		:= 2
+ENABLE_FEAT_HCX			:= 2
+ENABLE_FEAT_RNG			:= 2
+ENABLE_FEAT_TWED		:= 2
+ENABLE_FEAT_GCS			:= 2
+
 ifeq (${ARCH}, aarch64)
+
 ifeq (${SPM_MM}, 0)
 ifeq (${CTX_INCLUDE_FPREGS}, 0)
-	ENABLE_SME_FOR_NS		:= 2
-	ENABLE_SME2_FOR_NS		:= 2
-endif
-endif
+      ENABLE_SME_FOR_NS		:= 2
+      ENABLE_SME2_FOR_NS	:= 2
 endif
 endif
 
-# enable unconditionally for all builds
-ifeq (${ARCH}, aarch64)
-    ENABLE_BRBE_FOR_NS		:= 2
-    ENABLE_TRBE_FOR_NS		:= 2
+      ENABLE_BRBE_FOR_NS	:= 2
+      ENABLE_TRBE_FOR_NS	:= 2
 endif
+
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_FEAT_CSV2_2		:= 2
 ENABLE_FEAT_CSV2_3		:= 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
@@ -88,7 +70,6 @@
 ENABLE_FEAT_S1PIE		:= 2
 ENABLE_FEAT_S2POE		:= 2
 ENABLE_FEAT_S1POE		:= 2
-endif
 
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
@@ -204,21 +185,29 @@
 					lib/cpus/aarch64/cortex_a78_ae.S	\
 					lib/cpus/aarch64/cortex_a78c.S		\
 					lib/cpus/aarch64/cortex_a710.S		\
+					lib/cpus/aarch64/cortex_a715.S		\
+					lib/cpus/aarch64/cortex_a720.S		\
 					lib/cpus/aarch64/neoverse_n_common.S	\
 					lib/cpus/aarch64/neoverse_n1.S		\
 					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_gelas.S		\
-					lib/cpus/aarch64/nevis.S		\
-					lib/cpus/aarch64/travis.S
+					lib/cpus/aarch64/cortex_x4.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
 				lib/cpus/aarch64/cortex_a75.S
 endif
 
+#Build AArch64-only CPUs with no FVP model yet.
+ifeq (${BUILD_CPUS_WITH_NO_FVP_MODEL},1)
+	FVP_CPU_LIBS    +=	lib/cpus/aarch64/neoverse_n3.S	\
+				lib/cpus/aarch64/cortex_gelas.S		\
+				lib/cpus/aarch64/nevis.S		\
+				lib/cpus/aarch64/travis.S
+endif
+
 else
 FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S			\
 				lib/cpus/aarch32/cortex_a57.S			\
@@ -233,8 +222,10 @@
 				lib/semihosting/${ARCH}/semihosting_call.S	\
 				plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_bl1_setup.c		\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/board/fvp/fvp_err.c			\
 				plat/arm/board/fvp/fvp_io_storage.c		\
+				plat/arm/board/fvp/fvp_topology.c		\
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
 
@@ -262,7 +253,8 @@
 endif
 
 ifeq (${ENABLE_RME},1)
-BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c
 
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
 				plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -274,6 +266,7 @@
 
 ifeq (${RESET_TO_BL2},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/board/fvp/fvp_bl2_el3_setup.c		\
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
@@ -300,6 +293,7 @@
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
 				${FVP_GIC_SOURCES}				\
@@ -327,9 +321,23 @@
 BL31_SOURCES		+=	drivers/delay_timer/generic_delay_timer.c
 endif
 
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+endif
+
 # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
 ifdef UNIX_MK
+FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 FVP_HW_CONFIG_DTS	:=	fdts/${FVP_DT_PREFIX}.dts
+
+FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
+$(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
+
+ifeq (${TRANSFER_LIST}, 1)
+FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
+					${PLAT}_tb_fw_config.dts	\
+				)
+else
 FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
 					${PLAT}_fw_config.dts		\
 					${PLAT}_tb_fw_config.dts	\
@@ -338,7 +346,6 @@
 				)
 
 FVP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
-FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 FVP_SOC_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
 FVP_NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
@@ -350,10 +357,6 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
 endif
 
-ifeq (${TRANSFER_LIST}, 1)
-include lib/transfer_list/transfer_list.mk
-endif
-
 ifeq (${SPD},spmd)
 
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
@@ -369,16 +372,14 @@
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG}))
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
 # Add the SOC_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
-
-FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
-$(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
+endif
 
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 endif
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
index 252fc31..6fe2b5b 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_main.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <arch_helpers.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/console.h>
@@ -92,27 +93,6 @@
 }
 
 /*******************************************************************************
- * 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.
- ******************************************************************************/
-void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			meminfo_t *bl2_mem_layout)
-{
-	assert(bl1_mem_layout != NULL);
-	assert(bl2_mem_layout != NULL);
-
-	/*
-	 * Remove BL1 RW data from the scope of memory visible to BL2.
-	 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
-	 */
-	assert(bl1_mem_layout->total_base < BL1_RW_BASE);
-	bl2_mem_layout->total_base = bl1_mem_layout->total_base;
-	bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
-
-	flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
-}
-
-/*******************************************************************************
  * This function prepares for entry to BL33
  ******************************************************************************/
 void bl1_prepare_next_image(unsigned int image_id)
@@ -182,7 +162,7 @@
 
 	/* Announce our arrival */
 	NOTICE(FIRMWARE_WELCOME_STR);
-	NOTICE("BL1: %s\n", version_string);
+	NOTICE("BL1: %s\n", build_version_string);
 	NOTICE("BL1: %s\n", build_message);
 
 	INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
@@ -265,4 +245,3 @@
 	NOTICE("BL1: Please connect the debugger to continue\n");
 }
 #endif
-
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
index 6a7c0c8..dcf5e04 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -235,7 +235,7 @@
 	 */
 	bl33_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
 
-	bl1_calc_bl2_mem_layout(bl1_secram_layout, bl33_secram_layout);
+	bl1_plat_calc_bl2_layout(bl1_secram_layout, bl33_secram_layout);
 
 	ep_info->args.arg1 = (uintptr_t)bl33_secram_layout;
 
diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h
index ea3a258..1fdec15 100644
--- a/plat/arm/board/fvp_r/include/platform_def.h
+++ b/plat/arm/board/fvp_r/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,13 +75,6 @@
 #define PLAT_BL1_RO_LIMIT               (BL1_RO_BASE \
 					+ PLAT_ARM_TRUSTED_ROM_SIZE)
 
-#define PLAT_ARM_SYS_CNTCTL_BASE	UL(0xaa430000)
-#define PLAT_ARM_SYS_CNTREAD_BASE	UL(0xaa800000)
-#define PLAT_ARM_SYS_TIMCTL_BASE	UL(0xaa810000)
-#define PLAT_ARM_SYS_CNT_BASE_S		UL(0xaa820000)
-#define PLAT_ARM_SYS_CNT_BASE_NS	UL(0xaa830000)
-#define PLAT_ARM_SP805_TWDG_BASE	UL(0xaa490000)
-
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
 
@@ -90,11 +83,11 @@
 
 #define PLAT_ARM_DRAM2_SIZE		UL(0x80000000)
 
-#define PLAT_HW_CONFIG_DTB_SIZE		ULL(0x8000)
+#define PLAT_ARM_HW_CONFIG_SIZE		ULL(0x8000)
 
 #define ARM_DTB_DRAM_NS			MAP_REGION_FLAT(		\
 					PLAT_HW_CONFIG_DTB_BASE,	\
-					PLAT_HW_CONFIG_DTB_SIZE,	\
+					PLAT_ARM_HW_CONFIG_SIZE,	\
 					MT_MEMORY | MT_RO | MT_NS)
 
 #define V2M_FVP_R_SYSREGS_BASE		UL(0x9c010000)
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
index 6e5691b..422ef40 100644
--- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x82000000>;
-			max-size = <0x01000000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h
index bd8ef6a..e09ea02 100644
--- a/plat/arm/board/fvp_ve/include/platform_def.h
+++ b/plat/arm/board/fvp_ve/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -158,6 +158,9 @@
 #define PLAT_PHY_ADDR_SPACE_SIZE			(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE			(1ULL << 32)
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x01000000)
+
 /*
  * This macro defines the deepest retention state possible. A higher state
  * id will represent an invalid or a power down state.
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
index 2d79ac7..11e9574 100644
--- a/plat/arm/board/juno/fdts/juno_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x82000000>;
-			max-size = <0x8000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index b276f7b..777729e 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -36,6 +36,9 @@
  * Other platform porting definitions are provided by included headers
  */
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x8000)
+
 /*
  * Required ARM standard platform porting definitions
  */
diff --git a/plat/arm/board/juno/juno_tbbr_cot_bl2.c b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
index 8930dbb..d001dbe 100644
--- a/plat/arm/board/juno/juno_tbbr_cot_bl2.c
+++ b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -745,6 +745,21 @@
 };
 #endif /* ETHOSN_NPU_TZMP1 */
 
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
 
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index a00bf26..8eca0c5 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-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -134,7 +134,7 @@
 endif
 
 bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin
-	@echo "Building combined BL1 and ROMLIB binary for Juno $@"
+	$(s)echo "Building combined BL1 and ROMLIB binary for Juno $@"
 	./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
 
 # Errata workarounds for Cortex-A53:
diff --git a/plat/arm/board/morello/fdts/morello_fw_config.dts b/plat/arm/board/morello/fdts/morello_fw_config.dts
index a63d7eb..a93d6c4 100644
--- a/plat/arm/board/morello/fdts/morello_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 / {
@@ -25,7 +26,7 @@
 
 		hw-config {
 			load-address = <0x0 0xFEFF8000>;
-			max-size = <0x8000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
index 3cf723e..7ec89db 100644
--- a/plat/arm/board/morello/include/platform_def.h
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -75,6 +75,9 @@
  */
 #define PLAT_ARM_MAX_BL1_RW_SIZE		UL(0xC000)
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x8000)
+
 /*
  * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
  */
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index cfe8bee..b959031 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -5,6 +5,7 @@
  */
 
 #include <arch_helpers.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <drivers/arm/css/sds.h>
@@ -142,7 +143,7 @@
 		return -1;
 	}
 
-	err = fdt_setprop_string(fdt, nodeoffset_fw, "tfa-fw-version", version_string);
+	err = fdt_setprop_string(fdt, nodeoffset_fw, "tfa-fw-version", build_version_string);
 	if (err < 0) {
 		WARN("NT_FW_CONFIG: Unable to set tfa-fw-version\n");
 	}
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 82f1e7f..eb878ed 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -19,9 +19,6 @@
 #define PLAT_ARM_RUN_UART_BASE			0x1C090000
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ		24000000
 
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE		0x2A410000
-#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ	50000000
-
 #define PLAT_ARM_CRASH_UART_BASE		PLAT_ARM_RUN_UART_BASE
 #define PLAT_ARM_CRASH_UART_CLK_IN_HZ		PLAT_ARM_RUN_UART_CLK_IN_HZ
 
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/board/neoverse_rd/common/arch/aarch64/nrd_helper.S
similarity index 84%
rename from plat/arm/css/sgi/aarch64/sgi_helper.S
rename to plat/arm/board/neoverse_rd/common/arch/aarch64/nrd_helper.S
index ced59e8..8d9c0d7 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/board/neoverse_rd/common/arch/aarch64/nrd_helper.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,15 +21,15 @@
 	 *
 	 * Helper function to calculate the core position.
 	 * (ChipId * PLAT_ARM_CLUSTER_COUNT *
-	 *  CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
-	 * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
-	 * (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
+	 *  NRD_MAX_CPUS_PER_CLUSTER * NRD_MAX_PE_PER_CPU) +
+	 * (ClusterId * NRD_MAX_CPUS_PER_CLUSTER * NRD_MAX_PE_PER_CPU) +
+	 * (CPUId * NRD_MAX_PE_PER_CPU) +
 	 * ThreadId
 	 *
 	 * which can be simplified as:
 	 *
 	 * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) *
-	 *   CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU +
+	 *   NRD_MAX_CPUS_PER_CLUSTER) + CPUId) * NRD_MAX_PE_PER_CPU +
 	 * ThreadId
 	 * ------------------------------------------------------
 	 */
@@ -38,7 +38,7 @@
 	mov	x4, x0
 
 	/*
-	 * The MT bit in MPIDR is always set for SGI platforms
+	 * The MT bit in MPIDR is always set for Neoverse RD platforms
 	 * and the affinity level 0 corresponds to thread affinity level.
 	 */
 
@@ -51,9 +51,9 @@
 	/* Compute linear position */
 	mov     x4, #PLAT_ARM_CLUSTER_COUNT
 	madd    x2, x3, x4, x2
-	mov     x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
+	mov     x4, #NRD_MAX_CPUS_PER_CLUSTER
 	madd    x1, x2, x4, x1
-	mov     x4, #CSS_SGI_MAX_PE_PER_CPU
+	mov     x4, #NRD_MAX_PE_PER_CPU
 	madd    x0, x1, x4, x0
 	ret
 endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h
new file mode 100644
index 0000000..74835f6
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the CSS specific memory and interrupt map
+ * definitions for the first generation platforms based on the A75, N1 and V1
+ * CPUs. There are minor differences in the memory map of these platforms and
+ * those differences are not in the scope of this file.
+ */
+
+#ifndef NRD_CSS_DEF1_H
+#define NRD_CSS_DEF1_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* On-Chip ROM */
+#define NRD_CSS_TRUSTED_ROM_BASE	UL(0x00000000)
+#define NRD_CSS_TRUSTED_ROM_SIZE	UL(0x00080000)	/* 512KB */
+
+/* On-Chip RAM */
+#define	NRD_CSS_TRUSTED_SRAM_SIZE	UL(0x00080000)	/* 512KB */
+#define NRD_CSS_NONTRUSTED_SRAM_BASE	UL(0x06000000)
+#define NRD_CSS_NONTRUSTED_SRAM_SIZE	UL(0x00080000)	/* 512KB */
+
+/* PL011 UART */
+#define NRD_CSS_SEC_UART_BASE		UL(0x2A410000)
+#define NRD_CSS_UART_SIZE		UL(0x10000)
+
+/* CSS peripherals */
+#define NRD_CSS_PERIPH_BASE		UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE		UL(0x40000000)
+
+/* Secure Watchdog */
+#define NRD_CSS_WDOG_BASE		UL(0x2A480000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE		ULL(0x8080000000)
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000)
+
+#endif /* NRD_CSS_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h
new file mode 100644
index 0000000..70a7d49
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the CSS firmware specific definitions for
+ * the first generation platforms based on the A75, N1 and V1 CPUs.
+ */
+
+#ifndef NRD1_CSS_FW_DEF1_H
+#define NRD1_CSS_FW_DEF1_H
+
+#include <nrd_css_def1.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#if TRUSTED_BOARD_BOOT
+# define NRD_CSS_BL2_SIZE		UL(0x28000)
+#else
+# define NRD_CSS_BL2_SIZE		UL(0x14000)
+#endif
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_WDOG_TIMEOUT		UL(100)
+
+/*******************************************************************************
+ * Platform ID
+ ******************************************************************************/
+
+/* Platform ID address */
+#define SSC_VERSION		(SSC_REG_BASE + SSC_VERSION_OFFSET)
+#ifndef __ASSEMBLER__
+/* SSC_VERSION related accessors */
+/* Returns the part number of the platform */
+#define GET_NRD_PART_NUM						\
+			GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
+/* Returns the configuration number of the platform */
+#define GET_NRD_CONFIG_NUM						\
+			GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * MMU mappings
+ ******************************************************************************/
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_NON_CACHEABLE | MT_RW | MT_SECURE)
+
+#if SPM_MM
+/*
+ * Stand-alone MM logs would be routed via secure UART. Define page table
+ * entry for secure UART which would be common to all platforms.
+ */
+#define NRD_CSS_SECURE_UART_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_SEC_UART_BASE,				\
+			NRD_CSS_UART_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
+#endif /* NRD_CSS_FW_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h
new file mode 100644
index 0000000..bca095c
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the platform port definitions for the
+ * first generation platforms based on the A75, N1 and V1 CPUs.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF1_H
+#define NRD_PLAT_ARM_DEF1_H
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_ros_fw_def1.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT	(NRD_CHIP_COUNT *			\
+				PLAT_ARM_CLUSTER_COUNT *		\
+				NRD_MAX_CPUS_PER_CLUSTER *		\
+				NRD_MAX_PE_PER_CPU)
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+#if defined(IMAGE_BL31)
+# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
+#  define PLAT_ARM_MMAP_ENTRIES		(10 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(11 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	U(12)
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	U(14)
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		(5 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(6 + ((NRD_CHIP_COUNT - 1) * 3))
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(11 + (NRD_CHIP_COUNT - 1))
+
+/*
+ * MAX_XLAT_TABLES entries need to be doubled because when the address width
+ * exceeds 40 bits an additional level of translation is required. In case of
+ * multichip platforms peripherals also fall into address space with width
+ * > 40 bits.
+ */
+# define MAX_XLAT_TABLES		(11  + ((NRD_CHIP_COUNT - 1) * 2))
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES		U(11)
+# define MAX_XLAT_TABLES		U(7)
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(12)
+# define MAX_XLAT_TABLES		U(6)
+#endif
+
+/*******************************************************************************
+ * Stack size
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		U(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		U(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		U(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		U(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		U(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		U(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		U(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		U(0x440)
+#endif
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
+/*
+ * Secure partition stack follows right after the memory region that is shared
+ * between EL3 and S-EL0.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	U(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	U(0xe000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	U(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	U(0)
+#endif
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * ROM, SRAM and DRAM config
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_TRUSTED_SRAM_SIZE
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_TRUSTED_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_TRUSTED_ROM_SIZE
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NONTRUSTED_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NONTRUSTED_SRAM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * Timer config
+ ******************************************************************************/
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	(0)
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
+					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+/* IO storage framework */
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+#define PLAT_SP_PRI			U(0x10)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0f)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x0)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+		((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)	\
+		>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR		NRD_ROS_PLATFORM_BASE +	\
+						UL(0x00fe00e0)
+
+#endif /* NRD_PLAT_ARM_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h
new file mode 100644
index 0000000..b86ab21
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS specific definitions for the first
+ * generation platforms based on the A75, N1 and V1 CPUs. RoS (Rest Of System)
+ * is used to refer to the part of the reference design platform that excludes
+ * CSS.
+ */
+
+#ifndef NRD_ROS_DEF1_H
+#define NRD_ROS_DEF1_H
+
+/*******************************************************************************
+ * ROS configs
+ ******************************************************************************/
+
+/* RoS Peripherals */
+#define NRD_ROS_PERIPH_BASE		UL(0x60000000)
+#define NRD_ROS_PERIPH_SIZE		UL(0x20000000)
+
+/* System Reg */
+#define NRD_ROS_SYSTEMREG_BASE		UL(0x1C010000)
+#define NRD_ROS_SYSTEMREG_SIZE		UL(0x00010000)
+
+/* NOR Flash 2 */
+#define NRD_ROS_NOR2_FLASH_BASE		UL(0x10000000)
+#define NRD_ROS_NOR2_FLASH_SIZE		UL(0x04000000)
+
+/* RoS Platform */
+#define NRD_ROS_PLATFORM_BASE		UL(0x7F000000)
+#define NRD_ROS_PLATFORM_SIZE		UL(0x20000000)
+
+#endif /* NRD_ROS_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h
new file mode 100644
index 0000000..c521043
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * first generation platforms based on the A75, N1 and V1 CPUs. RoS (Rest Of
+ * System) is used to refer to the part of the reference design platform that
+ * excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF1_H
+#define NRD_ROS_FW_DEF1_H
+
+#include <nrd_ros_def1.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_ROS_PERIPH_BASE,				\
+			NRD_ROS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SECURE_SYSTEMREG_USER_MMAP				\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEMREG_BASE,				\
+			NRD_ROS_SYSTEMREG_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define NRD_ROS_SECURE_NOR2_USER_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_NOR2_FLASH_BASE,			\
+			NRD_ROS_NOR2_FLASH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define NRD_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+/*******************************************************************************
+ * TZ config
+ ******************************************************************************/
+
+/*
+ * Mapping definition of the TrustZone Controller for Arm Neoverse RD platforms
+ * where both the DRAM regions are marked for non-secure access. This applies
+ * to multi-chip platforms.
+ */
+#define NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(n)				\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+#endif  /* NRD_ROS_FW_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h
new file mode 100644
index 0000000..6cf57d4
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS specific definitions for the second generation
+ * platforms based on the N2/V2 CPU.
+ */
+
+#ifndef NRD_CSS_DEF2_H
+#define NRD_CSS_DEF2_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* Boot ROM */
+#define NRD_CSS_SECURE_ROM_BASE			UL(0x00000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE			ULL(0x8080000000)
+
+/* NS SRAM */
+#define NRD_CSS_NS_SRAM_BASE			UL(0x06000000)
+
+/* PL011 UART */
+#define NRD_CSS_SEC_UART_BASE			UL(0x2A410000)
+#define NRD_CSS_NSEC_UART_BASE			UL(0x2A400000)
+#define NRD_CSS_UART_SIZE			UL(0x10000)
+
+/* General Peripherals */
+#define NRD_CSS_PERIPH_BASE			UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE			UL(0x20000000)
+
+/* NS RAM Error record */
+#define NRD_CSS_NS_RAM_ERR_REC_BASE		UL(0x2A4C0000)
+
+/*Secure Watchdog */
+#define NRD_CSS_SECURE_WDOG_BASE		UL(0x2A480000)
+
+/* MHU */
+#define NRD_CSS_AP_SCP_S_MHU_BASE		UL(0x2A920000)
+
+/* GIC */
+#define NRD_CSS_GIC_BASE			UL(0x30000000)
+
+#endif /* NRD_CSS_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h
new file mode 100644
index 0000000..481632b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS-firmware specific definitions for the second
+ * generation platforms based on the N2/V2 CPU.
+ */
+
+#ifndef NRD_CSS_FW_DEF2_H
+#define NRD_CSS_FW_DEF2_H
+
+#include <nrd_css_def2.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#if TRUSTED_BOARD_BOOT
+# define NRD_CSS_BL2_SIZE		UL(0x20000)
+#else
+# define NRD_CSS_BL2_SIZE		UL(0x14000)
+#endif
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW. NRD_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_SECURE_WDOG_TIMEOUT	UL(100)
+
+/*******************************************************************************
+ * RAS config
+ ******************************************************************************/
+
+#define NRD_CSS_NS_RAM_ECC_CE_INT		U(87)
+#define NRD_CSS_NS_RAM_ECC_UE_INT		U(88)
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))			\
+	&& ENABLE_FEAT_RAS && FFH_SUPPORT
+/*
+ * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
+ * memory shared between EL3 and S-EL0.
+ */
+#define NRD_CSS_SP_CPER_BUF_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#define NRD_CSS_SP_CPER_BUF_SIZE	UL(0x10000)
+#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_NON_CACHEABLE | MT_RW | MT_SECURE)
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) &&			\
+ENABLE_FEAT_RAS && FFH_SUPPORT
+/*
+ * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
+ * memory shared between EL3 and S-EL0.
+ */
+#define NRD_CSS_SP_CPER_BUF_MMAP					\
+		MAP_REGION2(						\
+			NRD_CSS_SP_CPER_BUF_BASE,			\
+			NRD_CSS_SP_CPER_BUF_BASE,			\
+			NRD_CSS_SP_CPER_BUF_SIZE,			\
+			MT_RW_DATA | MT_NS | MT_USER,			\
+			PAGE_SIZE)
+#endif
+
+#if SPM_MM
+#define NRD_CSS_SECURE_UART_USER_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_SEC_UART_BASE,				\
+			NRD_CSS_UART_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
+#endif /* NRD_CSS_FW_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h
new file mode 100644
index 0000000..3ee413f
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the trusted firmware required platform port
+ * definitions for the second generation platforms based on the N2/V2 CPUs. The
+ * common platform support for Arm platforms expect platforms to define certain
+ * definitions and those definitions are referred to as the platform port
+ * definitions.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF2_H
+#define NRD_PLAT_ARM_DEF2_H
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <nrd_css_fw_def2.h>
+#include <nrd_ros_fw_def2.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT		(NRD_CHIP_COUNT *		\
+					PLAT_ARM_CLUSTER_COUNT *	\
+					NRD_MAX_CPUS_PER_CLUSTER *	\
+					NRD_MAX_PE_PER_CPU)
+
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_CLUSTER_COUNT		U(8)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define PLAT_ARM_CLUSTER_COUNT		U(4)
+#else
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#endif
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+#if defined(IMAGE_BL31)
+# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
+#  define PLAT_ARM_MMAP_ENTRIES		(10  + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(8  + ((NRD_CHIP_COUNT - 1) * 3))
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	U(12)
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	U(14)
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		(5 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(6 + ((NRD_CHIP_COUNT - 1) * 3))
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(11 + (NRD_CHIP_COUNT - 1))
+
+/*
+ * MAX_XLAT_TABLES entries need to be doubled because when the address width
+ * exceeds 40 bits an additional level of translation is required. In case of
+ * multichip platforms peripherals also fall into address space with width
+ * > 40 bits
+ *
+ */
+# define MAX_XLAT_TABLES		(7  + ((NRD_CHIP_COUNT - 1) * 2))
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES		U(11)
+# define MAX_XLAT_TABLES		U(7)
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(12)
+# define MAX_XLAT_TABLES		U(6)
+#endif
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0xe000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+#endif
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * Stack sizes
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		UL(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		UL(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		UL(0x440)
+#endif
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) &&			\
+ENABLE_FEAT_RAS && FFH_SUPPORT
+/*
+ * Secure partition stack follows right after the memory space reserved for
+ * CPER buffer memory.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +   \
+					 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
+					 NRD_CSS_SP_CPER_BUF_SIZE)
+#elif (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
+/*
+ * Secure partition stack follows right after the memory region that is shared
+ * between EL3 and S-EL0.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * ROM, SRAM and DRAM config
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_SECURE_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_SECURE_ROM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_SECURE_SRAM_SIZE
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	0
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NS_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NS_SRAM_SIZE
+/*
+ * Required platform porting definitions common to all ARM CSS SoCs
+ */
+/* 2MB used for SCP DDR retraining */
+#define PLAT_ARM_SCP_TZC_DRAM1_SIZE	UL(0x00200000)
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		NRD_CSS_GIC_BASE
+
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00100000)
+#elif (NRD_PLATFORM_VARIANT == 3)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00300000)
+#else
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x001C0000)
+#endif
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI			(0x10)
+#endif
+
+/* Interrupt priority level for shutdown/reboot */
+#define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
+#define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
+
+/*******************************************************************************
+ * Secure world config
+ ******************************************************************************/
+
+#define SECURE_PARTITION_COUNT		1
+#define NS_PARTITION_COUNT		1
+#define MAX_EL3_LP_DESCS_COUNT		1
+
+/*******************************************************************************
+ * MHU config
+ ******************************************************************************/
+
+#define PLAT_CSS_MHU_BASE		NRD_CSS_AP_SCP_S_MHU_BASE
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * TZ config
+ ******************************************************************************/
+
+#define PLAT_ARM_TZC_BASE		NRD_ROS_MEMCNTRL_BASE + UL(0x00720000)
+#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define V2M_SYS_LED			U(0x8)
+
+#define V2M_SYS_LED_SS_SHIFT		U(0)
+#define V2M_SYS_LED_EL_SHIFT		U(1)
+#define V2M_SYS_LED_EC_SHIFT		U(3)
+
+#define V2M_SYS_LED_SS_MASK		U(0x01)
+#define V2M_SYS_LED_EL_MASK		U(0x03)
+#define V2M_SYS_LED_EC_MASK		U(0x1f)
+
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
+
+#define V2M_SYSREGS_BASE		NRD_ROS_SYSTEM_PERIPH_BASE +	\
+						UL(0x00010000)
+#define V2M_FLASH0_BASE			NRD_ROS_SMC0_BASE
+#define V2M_FLASH0_SIZE			NRD_ROS_SMC0_SIZE
+#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE +	\
+					V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
+	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR	NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00FE00E0)
+
+/*******************************************************************************
+ * ROS peripheral config
+ ******************************************************************************/
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE		NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00E70000)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE	+ 0x0000)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * MMU config
+ ******************************************************************************/
+
+#define V2M_MAP_FLASH0_RW						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_RO_DATA | MT_SECURE)
+
+#endif /* NRD_PLAT_ARM_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h
new file mode 100644
index 0000000..3558cfc
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the RoS specific definitions for the second generation
+ * platforms based on the N2/V2 CPU.
+ */
+
+#ifndef NRD_ROS_DEF2_H
+#define NRD_ROS_DEF2_H
+
+/*******************************************************************************
+ * SoC memory map related defines
+ ******************************************************************************/
+
+/* System Reg */
+#define NRD_ROS_SYSTEMREG_BASE			UL(0x0C010000)
+#define NRD_ROS_SYSTEMREG_SIZE			UL(0x00010000)
+
+/* NOR flash 2 */
+#define NRD_ROS_NOR2_FLASH_BASE			ULL(0x001054000000)
+#define NRD_ROS_NOR2_FLASH_SIZE			UL(0x000004000000)
+
+/* Memory controller */
+#define NRD_ROS_MEMCNTRL_BASE			UL(0x10000000)
+#define NRD_ROS_MEMCNTRL_SIZE			UL(0x10000000)
+
+/* System peripherals */
+#define NRD_ROS_SYSTEM_PERIPH_BASE		UL(0x0C000000)
+#define NRD_ROS_SYSTEM_PERIPH_SIZE		UL(0x02000000)
+
+/* Platform peripherals */
+#define NRD_ROS_PLATFORM_PERIPH_BASE		UL(0x0E000000)
+#define NRD_ROS_PLATFORM_PERIPH_SIZE		UL(0x02000000)
+
+/* SMC0 */
+#define NRD_ROS_SMC0_BASE			UL(0x08000000)
+#define NRD_ROS_SMC0_SIZE			UL(0x04000000)
+
+#endif /* NRD_ROS_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h
new file mode 100644
index 0000000..6091672
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * second generation platforms based on the N2/V2 CPUs. RoS (Rest Of System) is
+ * used to refer to the part of the reference design platform that excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF2_H
+#define NRD_ROS_FW_DEF2_H
+
+#include <nrd_ros_def2.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PLATFORM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#if SPM_MM
+
+#define NRD_ROS_PLATFORM_PERIPH_USER_MMAP				\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
+#define NRD_ROS_SYSTEM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEM_PERIPH_BASE,			\
+			NRD_ROS_SYSTEM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_MEMCNTRL_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_ROS_MEMCNTRL_BASE,				\
+			NRD_ROS_MEMCNTRL_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SECURE_SYSTEMREG_USER_MMAP				\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEMREG_BASE,				\
+			NRD_ROS_SYSTEMREG_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define NRD_ROS_SECURE_NOR2_USER_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_NOR2_FLASH_BASE,			\
+			NRD_ROS_NOR2_FLASH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+
+#define NRD_ROS_FLASH0_RO_MMAP						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+/*******************************************************************************
+ * TZ config
+ ******************************************************************************/
+
+/*
+ * Mapping definition of the TrustZone Controller for Arm Neoverse RD platforms
+ * where both the DRAM regions are marked for non-secure access. This applies
+ * to multi-chip platforms.
+ */
+#define NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(n)				\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+#endif /* NRD_ROS_FW_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
new file mode 100644
index 0000000..bd2e682
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS specific definitions for the third generation of
+ * platforms.
+ */
+
+#ifndef NRD_CSS_DEF3_H
+#define NRD_CSS_DEF3_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* Shared RAM */
+#define NRD_CSS_SHARED_SRAM_BASE		UL(0x00000000)
+
+/* General Peripherals */
+#define NRD_CSS_PERIPH_BASE			UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE			UL(0x20000000)
+
+/* System NCI */
+#define NRD_CSS_SYSTEM_NCI_BASE			UL(0x20000000)
+#define NRD_CSS_SYSTEM_NCI_SIZE			UL(0x04000000)
+
+/* Debug NIC */
+#define NRD_CSS_DEBUG_NIC_BASE			UL(0x28000000)
+#define NRD_CSS_DEBUG_NIC_SIZE			UL(0x01000000)
+
+/* NS UART */
+#define NRD_CSS_NS_UART_BASE			UL(0x2A400000)
+#define NRD_CSS_NS_UART_SIZE			UL(0x00010000)
+
+/* Secure UART */
+#define NRD_CSS_SECURE_UART_BASE		UL(0x2A410000)
+#define NRD_CSS_SECURE_UART_SIZE		UL(0x00010000)
+
+/* Realm UART */
+#define NRD_CSS_REALM_UART_BASE			UL(0x2A420000)
+#define NRD_CSS_REALM_UART_SIZE			UL(0x00010000)
+
+/* Generic Refclk */
+#define NRD_CSS_GENERIC_REFCLK_BASE		UL(0x2A430000)
+#define NRD_CSS_GENERIC_REFCLK_SIZE		UL(0x00010000)
+
+/* NS Watchdog */
+#define NRD_CSS_AP_NS_WDOG_BASE			UL(0x2A440000)
+#define NRD_CSS_AP_NS_WDOG_SIZE			UL(0x00020000)
+
+/* Root Watchdog */
+#define NRD_CSS_AP_ROOT_WDOG_BASE		UL(0x2A460000)
+#define NRD_CSS_AP_ROOT_WDOG_SIZE		UL(0x00020000)
+
+/* Secure Watchdog */
+#define NRD_CSS_AP_SECURE_WDOG_BASE		UL(0x2A480000)
+#define NRD_CSS_AP_SECURE_WDOG_SIZE		UL(0x00020000)
+
+/* SID */
+#define NRD_CSS_SID_BASE			UL(0x2A4A0000)
+#define NRD_CSS_SID_SIZE			UL(0x00010000)
+
+/* SRAM Secure Error Record Block - AP */
+#define NRD_CSS_SECURE_SRAM_ERB_AP_BASE		UL(0x2A4B0000)
+#define NRD_CSS_SECURE_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM NS Error Record Block - AP */
+#define NRD_CSS_NS_SRAM_ERB_AP_BASE		UL(0x2A4C0000)
+#define NRD_CSS_NS_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - AP */
+#define NRD_CSS_ROOT_SRAM_ERB_AP_BASE		UL(0x2A4D0000)
+#define NRD_CSS_ROOT_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - AP */
+#define NRD_CSS_REALM_SRAM_ERB_AP_BASE		UL(0x2A4E0000)
+#define NRD_CSS_REALM_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - SCP */
+#define NRD_CSS_SECURE_SRAM_ERB_SCP_BASE	UL(0x2A4F0000)
+#define NRD_CSS_SECURE_SRAM_ERB_SCP_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - SCP */
+#define NRD_CSS_NS_SRAM_ERB_SCP_BASE		UL(0x2A500000)
+#define NRD_CSS_NS_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - SCP */
+#define NRD_CSS_ROOT_SRAM_ERB_SCP_BASE		UL(0x2A510000)
+#define NRD_CSS_ROOT_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - SCP */
+#define NRD_CSS_REALM_SRAM_ERB_SCP_BASE		UL(0x2A520000)
+#define NRD_CSS_REALM_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - MCP */
+#define NRD_CSS_SECURE_SRAM_ERB_MCP_BASE	UL(0x2A530000)
+#define NRD_CSS_SECURE_SRAM_ERB_MCP_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - MCP */
+#define NRD_CSS_NS_SRAM_ERB_MCP_BASE		UL(0x2A540000)
+#define NRD_CSS_NS_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - MCP */
+#define NRD_CSS_ROOT_SRAM_ERB_MCP_BASE		UL(0x2A550000)
+#define NRD_CSS_ROOT_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - MCP */
+#define NRD_CSS_REALM_SRAM_ERB_MCP_BASE		UL(0x2A560000)
+#define NRD_CSS_REALM_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - RSE */
+#define NRD_CSS_SECURE_SRAM_ERB_RSE_BASE	UL(0x2A570000)
+#define NRD_CSS_SECURE_SRAM_ERB_RSE_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - RSE */
+#define NRD_CSS_NS_SRAM_ERB_RSE_BASE		UL(0x2A580000)
+#define NRD_CSS_NS_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - RSE */
+#define NRD_CSS_ROOT_SRAM_ERB_RSE_BASE		UL(0x2A590000)
+#define NRD_CSS_ROOT_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - RSE */
+#define NRD_CSS_REALM_SRAM_ERB_RSE_BASE		UL(0x2A5A0000)
+#define NRD_CSS_REALM_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* RSE SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5B0000)
+#define NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* RSE SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_RSE_NS_SRAM_ERB_RSM_BASE	UL(0x2A5C0000)
+#define NRD_CSS_RSE_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* SCP SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5D0000)
+#define NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* SCP SRAM NS Error Record Block - RSM */
+#define NRD_CSS_SCP_NS_SRAM_ERB_RSM_BASE	UL(0x2A5E0000)
+#define NRD_CSS_SCP_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* MCP SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5F0000)
+#define NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* MCP SRAM NS Error Record Block - RSM */
+#define NRD_CSS_MCP_NS_SRAM_ERB_RSM_BASE	UL(0x2A600000)
+#define NRD_CSS_MCP_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* CNTCTL Refclk Readframe */
+#define NRD_CSS_CNTCTL_REFCLK_READFRAME_BASE	UL(0x2A800000)
+#define NRD_CSS_CNTCTL_REFCLK_READFRAME_SIZE	UL(0x00020000)
+
+/* CNTCTL base */
+#define NRD_CSS_SYS_TIMCTL_BASE			UL(0x2A810000)
+
+/* Secure Timer */
+#define NRD_CSS_SECURE_TIMER_CTL_BASE		UL(0x2A820000)
+#define NRD_CSS_SECURE_TIMER_CTL_SIZE		UL(0x00010000)
+
+/* NS Timer */
+#define NRD_CSS_NS_TIMER_CTL_BASE		UL(0x2A830000)
+#define NRD_CSS_NS_TIMER_CTL_SIZE		UL(0x00010000)
+
+/* AP - SCP NS MHU */
+#define NRD_CSS_AP_SCP_NS_MHU_BASE		UL(0x2A900000)
+#define NRD_CSS_AP_SCP_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - SCP Secure MHU */
+#define NRD_CSS_AP_SCP_SECURE_MHU_BASE		UL(0x2A920000)
+#define NRD_CSS_AP_SCP_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - SCP Root MHU */
+#define NRD_CSS_AP_SCP_ROOT_MHU_BASE		UL(0x2A940000)
+#define NRD_CSS_AP_SCP_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP NS MHU */
+#define NRD_CSS_AP_MCP_NS_MHU_BASE		UL(0x2AA00000)
+#define NRD_CSS_AP_MCP_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP Secure MHU */
+#define NRD_CSS_AP_MCP_SECURE_MHU_BASE		UL(0x2AA20000)
+#define NRD_CSS_AP_MCP_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP Root MHU */
+#define NRD_CSS_AP_MCP_ROOT_MHU_BASE		UL(0x2AA40000)
+#define NRD_CSS_AP_MCP_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE NS MHU */
+#define NRD_CSS_AP_RSE_NS_MHU_BASE		UL(0x2AB00000)
+#define NRD_CSS_AP_RSE_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Secure MHU */
+#define NRD_CSS_AP_RSE_SECURE_MHU_BASE		UL(0x2AB20000)
+#define NRD_CSS_AP_RSE_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Root MHU */
+#define NRD_CSS_AP_RSE_ROOT_MHU_BASE		UL(0x2AB40000)
+#define NRD_CSS_AP_RSE_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Realm MHU */
+#define NRD_CSS_AP_RSE_REALM_MHU_BASE		UL(0x2AB60000)
+#define NRD_CSS_AP_RSE_REALM_MHU_SIZE		UL(0x00020000)
+
+/* SCP - MCP - RSE Cross chip MHU */
+#define NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_BASE	UL(0x2AC00000)
+#define NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_SIZE	UL(0x00120000)
+
+/* Synchronization Master Tupdate */
+#define NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_BASE	UL(0x2B100000)
+#define NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_SIZE	UL(0x00030000)
+
+/* AP - RSE NS MHU */
+#define NRD_CSS_STM_SYSTEM_ITS_BASE		UL(0x2CF00000)
+#define NRD_CSS_STM_SYSTEM_ITS_SIZE		UL(0x02100000)
+
+/* SCP - MCP - RSE Shared SRAM */
+#define NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_BASE	UL(0x2F000000)
+#define NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_SIZE	UL(0x00400000)
+
+/* GIC base */
+#define NRD_CSS_GIC_BASE			UL(0x30000000)
+#define NRD_CSS_GIC_SIZE			UL(0x08000000)
+
+/* CMN */
+#define NRD_CSS_CMN_BASE			ULL(0x100000000)
+#define NRD_CSS_CMN_SIZE			UL(0x40000000)
+
+/* LCP Peripherals */
+#define NRD_CSS_LCP_PERIPHERAL_BASE		ULL(0x200000000)
+#define NRD_CSS_LCP_PERIPHERAL_SIZE		UL(0x40000000)
+
+/* DDR IO */
+#define NRD_CSS_DDR_IO_BASE			ULL(0x240000000)
+#define NRD_CSS_DDR_IO_SIZE			UL(0x40000000)
+
+/* SMMU & NCI IO */
+#define NRD_CSS_SMMU_NCI_IO_BASE		ULL(0x280000000)
+#define NRD_CSS_SMMU_NCI_IO_SIZE		UL(0x60000000)
+
+/* GPC SMMU */
+#define NRD_CSS_GPC_SMMUV3_BASE			UL(0x300000000)
+#define NRD_CSS_GPC_SMMUV3_SIZE			UL(0x8000000)
+
+/* DRAM1 */
+#define NRD_CSS_DRAM1_BASE			UL(0x80000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE			ULL(0x8080000000)
+
+/*******************************************************************************
+ * MHUv3 related definitions
+ ******************************************************************************/
+
+#define MHU_V3_MBX_FRAME_OFFSET			UL(0x10000)
+
+/* MHUv3 Postbox and Mailbox register frame base */
+#define AP_RSE_ROOT_MHU_V3_PBX		NRD_CSS_AP_RSE_ROOT_MHU_BASE
+#define AP_RSE_ROOT_MHU_V3_MBX		NRD_CSS_AP_RSE_ROOT_MHU_BASE + \
+						MHU_V3_MBX_FRAME_OFFSET
+
+#define AP_RSE_SECURE_MHU_V3_PBX	NRD_CSS_AP_RSE_SECURE_MHU_BASE
+#define AP_RSE_SECURE_MHU_V3_MBX	NRD_CSS_AP_RSE_SECURE_MHU_BASE + \
+						MHU_V3_MBX_FRAME_OFFSET
+
+#endif /* NRD_CSS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
new file mode 100644
index 0000000..1b92ec2
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS-firmware specific definitions for the third
+ * generation of platforms.
+ */
+
+#ifndef NRD_CSS_FW_DEF3_H
+#define NRD_CSS_FW_DEF3_H
+
+#include <nrd_css_def3.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#define NRD_CSS_BL1_RO_BASE		NRD_CSS_SHARED_SRAM_BASE
+#define NRD_CSS_BL1_RO_SIZE		UL(0x00019000)
+
+# define NRD_CSS_BL2_SIZE		UL(0x30000)
+
+/*
+ * 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. NRD_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+#define NRD_CSS_DRAM1_CARVEOUT_SIZE	UL(0x0C000000)	/* 117MB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_AP_SECURE_WDOG_TIMEOUT	UL(100)
+
+/*******************************************************************************
+ * RMM Console Config
+ ******************************************************************************/
+
+#define NRD_CSS_RMM_CONSOLE_BASE		NRD_CSS_REALM_UART_BASE
+#define NRD_CSS_RMM_CONSOLE_BAUD		ARM_CONSOLE_BAUDRATE
+#define NRD_CSS_RMM_CONSOLE_CLK_IN_HZ		UL(14745600)
+#define NRD_CSS_RMM_CONSOLE_NAME		"pl011"
+#define NRD_CSS_RMM_CONSOLE_COUNT		UL(1)
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_GPC_SMMU_SMMUV3_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_GPC_SMMUV3_BASE,			\
+			NRD_CSS_GPC_SMMUV3_SIZE,			\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_CSS_BL1_RW_MMAP						\
+		MAP_REGION_FLAT(					\
+			BL1_RW_BASE,					\
+			BL1_RW_LIMIT - BL1_RW_BASE,			\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_NS_DRAM1_MMAP						\
+		MAP_REGION_FLAT(					\
+			ARM_NS_DRAM1_BASE,				\
+			ARM_NS_DRAM1_SIZE,				\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#define NRD_CSS_GPT_L1_DRAM_MMAP					\
+		MAP_REGION_FLAT(					\
+			ARM_L1_GPT_BASE,				\
+			ARM_L1_GPT_SIZE,				\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_EL3_RMM_SHARED_MEM_MMAP					\
+		MAP_REGION_FLAT(					\
+			ARM_EL3_RMM_SHARED_BASE,			\
+			ARM_EL3_RMM_SHARED_SIZE,			\
+			MT_MEMORY | MT_RW | MT_REALM)
+
+#define NRD_CSS_RMM_REGION_MMAP						\
+		MAP_REGION_FLAT(					\
+			ARM_REALM_BASE,					\
+			ARM_REALM_SIZE,					\
+			MT_MEMORY | MT_RW | MT_REALM)
+
+#endif /* NRD_CSS_FW_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
new file mode 100644
index 0000000..f9a62ae
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_PAS_DEF3_H
+#define NRD_PAS_DEF3_H
+
+#ifndef __ASSEMBLER__
+#include <stddef.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#endif
+
+#include <nrd_css_def3.h>
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/*
+ * =====================================================================
+ * Base Addr        |Size    |L? GPT |PAS    |Content                  |
+ * =====================================================================
+ * 0x00000000       |256MB   |L0 GPT |ANY    |SHARED RAM               |
+ * 0x0FFFFFFF       |        |       |       |AP EXPANSION             |
+ * ---------------------------------------------------------------------
+ * 0x20000000       |64MB    |L1 GPT |ROOT   |SYSTEM NCI               |
+ * 0x23FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x28000000       |16MB    |L1 GPT |SECURE |DEBUG NIC                |
+ * 0x28FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A400000       |64KB    |L1 GPT |NS     |NS UART                  |
+ * 0x2A40FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A410000       |64KB    |L1 GPT |SECURE |SECURE UART              |
+ * 0x2A41FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A420000       |64KB    |L1 GPT |REALM  |REALM UART               |
+ * 0x2A42FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A430000       |64KB    |L1 GPT |SECURE |GENERIC REFCLK           |
+ * 0x2A43FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A440000       |128KB   |L1 GPT |NS     |AP NS WDOG               |
+ * 0x2A45FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A460000       |128KB   |L1 GPT |ROOT   |AP ROOT WDOG             |
+ * 0x2A47FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A480000       |128KB   |L1 GPT |SECURE |AP SECURE WDOG           |
+ * 0x2A49FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A4A0000       |64KB    |L1 GPT |NS     |SID                      |
+ * 0x2A4AFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A4B0000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A4BFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4C0000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A4CFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4D0000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A4DFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4E0000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A4EFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4F0000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A4FFFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A500000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A50FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A510000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A51FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A520000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A52FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A530000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A53FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A540000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A54FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A550000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A55FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A560000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A56FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A570000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A57FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A580000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A58FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A590000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A59FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A5A0000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A5AFFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A5B0000       |64KB    |L1 GPT |SECURE |RSE SECURE SRAM ERROR    |
+ * 0x2A5BFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5C0000       |64KB    |L1 GPT |NS     |RSE NS SRAM ERROR        |
+ * 0x2A5CFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5D0000       |64KB    |L1 GPT |SECURE |SCP SECURE SRAM ERROR    |
+ * 0x2A5DFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5E0000       |64KB    |L1 GPT |NS     |SCP NS SRAM ERROR        |
+ * 0x2A5EFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5F0000       |64KB    |L1 GPT |SECURE |MCP SECURE SRAM ERROR    |
+ * 0x2A5FFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A600000       |64KB    |L1 GPT |NS     |MCP NS SRAM ERROR        |
+ * 0x2A60FFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A800000       |128KB   |L1 GPT |NS     |CNTCTL REFCLK            |
+ * 0x2A81FFFF       |        |       |       |READ FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A820000       |64KB    |L1 GPT |SECURE |SECURE TIMER CTL         |
+ * 0x2A82FFFF       |        |       |       |BASE FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A830000       |64KB    |L1 GPT |NS     |NS TIMER CTL             |
+ * 0x2A83FFFF       |        |       |       |BASE FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A900000       |128KB   |L1 GPT |NS     |AP-SCP NS                |
+ * 0x2A91FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2A920000       |128KB   |L1 GPT |SECURE |AP-SCP SECURE            |
+ * 0x2A93FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2A940000       |128KB   |L1 GPT |ROOT   |AP-SCP ROOT              |
+ * 0x2A95FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA00000       |128KB   |L1 GPT |NS     |AP-MCP NS                |
+ * 0x2AA1FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA20000       |128KB   |L1 GPT |SECURE |AP-MCP SECURE            |
+ * 0x2AA3FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA40000       |128KB   |L1 GPT |ROOT   |AP-MCP ROOT              |
+ * 0x2AA5FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB00000       |128KB   |L1 GPT |NS     |AP-MCP NS                |
+ * 0x2AB1FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB20000       |128KB   |L1 GPT |SECURE |AP-RSE SECURE            |
+ * 0x2AB3FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB40000       |128KB   |L1 GPT |ROOT   |AP-RSE ROOT              |
+ * 0x2AB5FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB60000       |128KB   |L1 GPT |REALM  |AP-RSE REALM             |
+ * 0x2AB7FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AC00000       |1152KB  |L1 GPT |ROOT   |SCP MCP RSE              |
+ * 0x2ACEFFFF       |        |       |       |CROSS CHIP MHU           |
+ * ---------------------------------------------------------------------
+ * 0x2B100000       |192KB   |L1 GPT |SECURE |SYNCNT                   |
+ * 0x2B12FFFF       |        |       |       |MSTUPDTVAL_ADDR          |
+ * ---------------------------------------------------------------------
+ * 0x2CF00000       |~33MB   |L1 GPT |NS     |STM SYSTEM ITS           |
+ * 0x2EFFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2F000000       |4MB     |L1 GPT |ANY    |SHARED SRAM              |
+ * 0x2F3FFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x30000000       |128MB   |L1 GPT |ANY    |GIC CLAYTON              |
+ * 0x37FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |2GB -   |L1 GPT |NS     |NS DRAM                  |
+ * 0xFFFE2BFF       |117MB   |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |26MB    |L1 GPT |REALM  |RMM                      |
+ * 0x37FFFFFF       |        |       |       |TF-A SHARED              |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |2MB     |L1 GPT |ROOT   |L1GPT                    |
+ * 0x37FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x100080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 3            |
+ * 0x1000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x200080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 2            |
+ * 0x2000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x300080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 1            |
+ * 0x3000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x100000000      |1GB     |L1 GPT |ANY    |CMN                      |
+ * 0x13FFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x200000000      |1GB     |L1 GPT |ANY    |LCP PERIPHERALS          |
+ * 0x23FFFFFFF      |        |       |       |DDR                      |
+ * ---------------------------------------------------------------------
+ * 0x240000000      |1GB     |L1 GPT |ANY    |DDR IO                   |
+ * 0x27FFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x280000000      |1.5GB   |L1 GPT |ANY    |SMMU & NCI IO            |
+ * 0x2DFFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x300000000      |128MB   |L1 GPT |ROOT   |GPC SMMU                 |
+ * 0x308000000      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x8080000000     |6GB     |L1 GPT |ANY    |DRAM 2 CHIP 0            |
+ * 0x81FFFFFFFF     |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x108080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 1            |
+ * 0x1081FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x208080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 2            |
+ * 0x2081FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x308080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 3            |
+ * 0x3081FFFFFFFF   |        |       |       |                         |
+ * =====================================================================
+ */
+
+/*******************************************************************************
+ * Multichip config
+ ******************************************************************************/
+
+#define NRD_MC_BASE(base, n)		(NRD_REMOTE_CHIP_MEM_OFFSET(n) + base)
+
+/*******************************************************************************
+ * PAS mappings
+ ******************************************************************************/
+
+#define NRD_PAS_SHARED_SRAM						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SHARED_SRAM_BASE,			\
+			NRD_CSS_SHARED_SRAM_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_SYSTEM_NCI						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SYSTEM_NCI_BASE,			\
+			NRD_CSS_SYSTEM_NCI_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_DEBUG_NIC						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_DEBUG_NIC_BASE,				\
+			NRD_CSS_DEBUG_NIC_SIZE,				\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_UART							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_UART_BASE,				\
+			NRD_CSS_NS_UART_SIZE,				\
+			GPT_GPI_NS)
+
+#define NRD_PAS_REALM_UART						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_UART_BASE,			\
+			NRD_CSS_REALM_UART_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_AP_NS_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_NS_WDOG_BASE,			\
+			NRD_CSS_AP_NS_WDOG_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_ROOT_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_ROOT_WDOG_BASE,			\
+			NRD_CSS_AP_ROOT_WDOG_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_SECURE_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_SECURE_WDOG_BASE,			\
+			NRD_CSS_AP_SECURE_WDOG_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_SECURE_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_AP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_AP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_AP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_REALM_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_SCP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_SCP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_SCP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_SCP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_SCP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_SCP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_SCP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_SCP_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_SCP_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_MCP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_MCP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_MCP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_MCP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_MCP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_MCP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_MCP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_MCP_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_MCP_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_RSE_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_RSE_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_RSE						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_RSE_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_RSE_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_RSE_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_RSE_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_RSE_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_RSE_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_RSE_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_RSE_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_RSE_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_RSE_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_SCP_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_SCP_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_SCP_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_MCP_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define	NRD_PAS_MCP_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_MCP_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_MCP_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_SCP_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_SCP_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_SCP_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_MCP_NS_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_NS_MHU_BASE,			\
+			NRD_CSS_AP_MCP_NS_MHU_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_MCP_SECURE_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_SECURE_MHU_BASE,			\
+			NRD_CSS_AP_MCP_SECURE_MHU_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_AP_MCP_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_MCP_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_RSE_NS_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_NS_MHU_BASE,			\
+			NRD_CSS_AP_RSE_NS_MHU_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_RSE_SECURE_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_SECURE_MHU_BASE,			\
+			NRD_CSS_AP_RSE_SECURE_MHU_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_AP_RSE_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_RSE_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_RSE_REALM_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_REALM_MHU_BASE,			\
+			NRD_CSS_AP_RSE_REALM_MHU_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU				\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_BASE,	\
+			NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_SIZE,	\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_BASE,		\
+			NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_STM_SYSTEM_ITS						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_STM_SYSTEM_ITS_BASE,			\
+			NRD_CSS_STM_SYSTEM_ITS_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_SCP_MCP_RSE_SHARED_SRAM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_BASE,		\
+			NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_SIZE,		\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_GIC							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_GIC_BASE,				\
+			NRD_CSS_GIC_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_NS_DRAM							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_NS_DRAM1_BASE,				\
+			ARM_NS_DRAM1_SIZE,				\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP1						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 1),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP2						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 2),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 3),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_RMM							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_REALM_BASE,					\
+			ARM_REALM_SIZE +				\
+			ARM_EL3_RMM_SHARED_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_L1GPT							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_L1_GPT_BASE,				\
+			ARM_L1_GPT_SIZE,				\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_CMN							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_CMN_BASE,				\
+			NRD_CSS_CMN_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_LCP_PERIPHERAL						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_LCP_PERIPHERAL_BASE,			\
+			NRD_CSS_LCP_PERIPHERAL_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_DDR_IO							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_DDR_IO_BASE,				\
+			NRD_CSS_DDR_IO_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_SMMU_NCI_IO						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SMMU_NCI_IO_BASE,			\
+			NRD_CSS_SMMU_NCI_IO_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_GPC_SMMUV3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_GPC_SMMUV3_BASE,			\
+			NRD_CSS_GPC_SMMUV3_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_DRAM2_CHIP0						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 0),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP1						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 1),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP2						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 2),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 3),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#endif /* NRD_PAS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
new file mode 100644
index 0000000..0dce512
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
@@ -0,0 +1,756 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the platform port definitions for the
+ * third generation of platforms.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF3_H
+#define NRD_PLAT_ARM_DEF3_H
+
+#include <common/tbbr/tbbr_img_def.h>
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/common/common_def.h>
+#include <nrd_css_fw_def3.h>
+#include <nrd_ros_fw_def3.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT		(NRD_CHIP_COUNT *		\
+					PLAT_ARM_CLUSTER_COUNT *	\
+					NRD_MAX_CPUS_PER_CLUSTER *	\
+					NRD_MAX_PE_PER_CPU)
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage. In addition to that, on
+ * multi-chip platforms, address regions on each of the remote chips are
+ * also mapped. In BL31, for instance, three address regions on the remote
+ * chips are accessed - secure ram, css device and soc device regions.
+ */
+#if defined(IMAGE_BL31)
+#  define PLAT_ARM_MMAP_ENTRIES		(9 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(9 + ((NRD_CHIP_COUNT - 1) * 3))
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(16 + (NRD_CHIP_COUNT - 1))
+# define MAX_XLAT_TABLES		(11  + ((NRD_CHIP_COUNT - 1) * 2))
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(7)
+# define MAX_XLAT_TABLES		U(7)
+#endif
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * BL31 plat param
+ ******************************************************************************/
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
+
+/*******************************************************************************
+ * Stack sizes
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		UL(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		UL(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		UL(0x440)
+#endif
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define ARM_CONSOLE_BAUDRATE		(115200)
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * System counter and timer config
+ ******************************************************************************/
+
+#define ARM_SYS_CNTCTL_BASE		NRD_CSS_GENERIC_REFCLK_BASE
+#define ARM_SYS_CNTREAD_BASE		NRD_CSS_CNTCTL_REFCLK_READFRAME_BASE
+#define ARM_SYS_TIMCTL_BASE		NRD_CSS_SYS_TIMCTL_BASE
+#define ARM_SYS_CNT_BASE_S		NRD_CSS_SECURE_TIMER_CTL_BASE
+#define ARM_SYS_CNT_BASE_NS		NRD_CSS_NS_TIMER_CTL_BASE
+
+/*******************************************************************************
+ * SRAM and DRAM config for FW
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_SECURE_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_SECURE_ROM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_SECURE_SRAM_SIZE
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	(0)
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NS_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NS_SRAM_SIZE
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+/*
+ * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The
+ * power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+#define ARM_PWR_LVL0			MPIDR_AFFLVL0
+#define ARM_PWR_LVL1			MPIDR_AFFLVL1
+#define ARM_PWR_LVL2			MPIDR_AFFLVL2
+#define ARM_PWR_LVL3			MPIDR_AFFLVL3
+
+/* Local power state for power domains in Run state. */
+#define ARM_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define ARM_LOCAL_STATE_RET		U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains
+ */
+#define ARM_LOCAL_STATE_OFF		U(2)
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE		ARM_LOCAL_STATE_RET
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		ARM_LOCAL_STATE_OFF
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * MHU config
+ ******************************************************************************/
+
+#define PLAT_CSS_MHU_BASE		NRD_CSS_AP_SCP_SECURE_MHU_BASE
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+/*******************************************************************************
+ * Cache config
+ ******************************************************************************/
+
+#define ARM_CACHE_WRITEBACK_SHIFT	U(6)
+
+/*
+ * 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.
+ */
+#define CACHE_WRITEBACK_GRANULE		(U(1) << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+/* CPU Fault Handling Interrupt(FHI) PPI interrupt ID */
+#define PLAT_CORE_FAULT_IRQ		U(17)
+
+/* ARM platforms use 3 upper bits of secure interrupt priority */
+#define PLAT_PRI_BITS			U(3)
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_RAS_PRI			U(0x10)
+#endif
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI			U(0x10)
+#endif
+
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_SEC_SGI_0		U(8)
+#define ARM_IRQ_SEC_SGI_1		U(9)
+#define ARM_IRQ_SEC_SGI_2		U(10)
+#define ARM_IRQ_SEC_SGI_3		U(11)
+#define ARM_IRQ_SEC_SGI_4		U(12)
+#define ARM_IRQ_SEC_SGI_5		U(13)
+#define ARM_IRQ_SEC_SGI_6		U(14)
+#define ARM_IRQ_SEC_SGI_7		U(15)
+
+#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 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 PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+#define PLAT_ARM_GICD_BASE		NRD_CSS_GIC_BASE
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00100000)
+#else
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x001C0000)
+#endif
+
+/*******************************************************************************
+ * SDEI config
+ ******************************************************************************/
+
+#define PLAT_SDEI_CRITICAL_PRI		U(0x60)
+#define PLAT_SDEI_NORMAL_PRI		U(0x70)
+
+/* 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	U(3)
+
+/* ARM SDEI dynamic shared event max count */
+#define ARM_SDEI_DS_EVENT_MAX_CNT	U(3)
+#else
+/* ARM SDEI dynamic private event numbers */
+#define ARM_SDEI_DP_EVENT_0		UL(1000)
+#define ARM_SDEI_DP_EVENT_1		UL(1001)
+#define ARM_SDEI_DP_EVENT_2		UL(1002)
+
+/* ARM SDEI dynamic shared event numbers */
+#define ARM_SDEI_DS_EVENT_0		UL(2000)
+#define ARM_SDEI_DS_EVENT_1		UL(2001)
+#define ARM_SDEI_DS_EVENT_2		UL(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 */
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+
+/*******************************************************************************
+ * SMMUv3 Config
+ ******************************************************************************/
+
+/* SMMUv3 root offset register */
+#define PLAT_ARM_SMMUV3_ROOT_REG_OFFSET	UL(0xA0000)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
+	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR	NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00FE00E0)
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define V2M_SYS_LED			U(0x8)
+
+#define V2M_SYS_LED_SS_SHIFT		U(0)
+#define V2M_SYS_LED_EL_SHIFT		U(1)
+#define V2M_SYS_LED_EC_SHIFT		U(3)
+
+#define V2M_SYS_LED_SS_MASK		U(0x01)
+#define V2M_SYS_LED_EL_MASK		U(0x03)
+#define V2M_SYS_LED_EC_MASK		U(0x1f)
+
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
+
+#define V2M_SYSREGS_BASE		NRD_ROS_SYSTEM_PERIPH_BASE +	\
+						UL(0x00010000)
+#define V2M_FLASH0_BASE			NRD_ROS_SMC0_BASE
+#define V2M_FLASH0_SIZE			NRD_ROS_SMC0_SIZE
+#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE +	\
+					V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*******************************************************************************
+ * ROS peripheral config
+ ******************************************************************************/
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE		NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00E70000)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE	+ 0x0000)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * SRAM layout
+ ******************************************************************************/
+
+/*
+ *              Trusted SRAM
+ * 0x00100000 +--------------+
+ *            |    L0 GPT    |
+ * 0x000E0000 +--------------+  loaded by BL2  +----------------+
+ *            |   BL1 (rw)   |  <<<<<<<<<<<<<  |                |
+ *            |--------------|  <<<<<<<<<<<<<  |  BL31 NOBITS   |
+ *            |     BL2      |  <<<<<<<<<<<<<  |                |
+ *            |--------------|  <<<<<<<<<<<<<  |----------------|
+ *            |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
+ *            |              |                 +----------------+
+ *            +--------------+
+ *            |    CONFIG    |
+ * 0x0001A000 +--------------+
+ *            |    Shared    |
+ * 0x00019000 +--------------+
+ *            |   BL1 (ro)   |
+ * 0x00000000 +--------------+
+ */
+
+/*******************************************************************************
+ * BL1 RO specifics
+ ******************************************************************************/
+
+/*
+ * SRAM region to store BL1 code and RO. This has been carved out at the bottom
+ * of SRAM
+ */
+
+#define BL1_RO_BASE			NRD_CSS_BL1_RO_BASE
+#define BL1_RO_LIMIT			(NRD_CSS_BL1_RO_BASE		\
+					 + NRD_CSS_BL1_RO_SIZE)
+
+/*******************************************************************************
+ * L0 GPT specifics
+ ******************************************************************************/
+
+/*
+ * L0 GPT has to be aligned to its size. In order to avoid holes due to
+ * alignment, place L0 GPT at the top of SRAM.
+ */
+#define ARM_L0_GPT_SIZE			UL(0x00020000) /* 128KB */
+#define ARM_L0_GPT_BASE			NRD_CSS_SHARED_SRAM_SIZE -	\
+					ARM_L0_GPT_SIZE
+
+#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
+
+/*******************************************************************************
+ * Arm shared RAM specifics
+ ******************************************************************************/
+
+#define ARM_SHARED_RAM_BASE		(NRD_CSS_BL1_RO_BASE +		\
+					 NRD_CSS_BL1_RO_SIZE)
+#define ARM_SHARED_RAM_SIZE		UL(0x00001000)	/* 4 KB */
+
+/*******************************************************************************
+ * Arm BL RAM specifics
+ ******************************************************************************/
+
+/*Rest of SRAM till L0 GPT base */
+#define ARM_BL_RAM_BASE			(ARM_SHARED_RAM_BASE +		\
+					 ARM_SHARED_RAM_SIZE)
+#define ARM_BL_RAM_SIZE			(ARM_L0_GPT_BASE -		\
+					 ARM_BL_RAM_BASE)
+
+/*******************************************************************************
+ * FW_CONFIG specifics
+ ******************************************************************************/
+
+/*
+ * 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_SIZE		(PAGE_SIZE * 2)
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
+
+/*******************************************************************************
+ * BL1 RW specifics
+ ******************************************************************************/
+
+#define BL1_RW_BASE			(ARM_BL_RAM_BASE +		\
+					 ARM_BL_RAM_SIZE -		\
+					 PLAT_ARM_MAX_BL1_RW_SIZE)
+#define BL1_RW_LIMIT			(ARM_BL_RAM_BASE +		\
+					 ARM_BL_RAM_SIZE)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+
+/* Put BL2 just below BL1. */
+#define BL2_BASE			(BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL1_RW_BASE
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+
+/* Keep 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
+#define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+
+/*
+ * 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			7
+
+#define MAX_MMAP_REGIONS		(PLAT_ARM_MMAP_ENTRIES +	\
+					 ARM_BL_REGIONS)
+
+/*******************************************************************************
+ * DRAM layout
+ ******************************************************************************/
+
+/*
+ * The top 100MB of DRAM1 is configured as follows:
+ *   - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
+ *   - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
+ *   - REALM DRAM: Reserved for Realm world if RME is enabled
+ *
+ *                    DRAM layout
+ *               +------------------+
+ *               |   REALM (RMM)    |
+ *               |   (32MB - 4KB)   |
+ *               +------------------+
+ *               |                  |
+ *               |   TF-A <-> RMM   |
+ *               |   SHARED (4KB)   |
+ *               +------------------+
+ *               |       L1 GPT     |
+ *               |                  |
+ *     DRAM1 End +------------------+
+ */
+
+/* Number of DRAM banks */
+#if (NRD_PLATFORM_VARIANT == 2)
+#define ARM_DRAM_NUM_BANKS		U(8)
+#else
+#define ARM_DRAM_NUM_BANKS		U(2)
+#endif
+
+/*******************************************************************************
+ * DRAM bank1 specific defines.
+ ******************************************************************************/
+
+/* Bank-1 DRAM */
+#define ARM_DRAM1_BASE			UL(0x80000000)
+#define ARM_DRAM1_SIZE			UL(0x80000000)
+#define ARM_DRAM1_END			(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE - 1U)
+
+/*******************************************************************************
+ * DRAM bank2 specific defines.
+ ******************************************************************************/
+
+/* Bank-2 DRAM */
+#define ARM_DRAM2_BASE			PLAT_ARM_DRAM2_BASE
+#define ARM_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
+#define ARM_DRAM2_END			(ARM_DRAM2_BASE +		\
+					 ARM_DRAM2_SIZE - 1U)
+
+/*******************************************************************************
+ * L1GPT specific defines.
+ ******************************************************************************/
+
+/* 2MB per L1 entry, PPS - 48 bits, PGS - 4KB, L0GPTSZ - 16GB */
+#define ARM_L1_GPT_SIZE			(UL(40 * 1024 * 1024) +		\
+					((NRD_CHIP_COUNT - 1) *		\
+					(4 * 1024 * 1024)))
+
+#define ARM_L1_GPT_BASE			(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE -		\
+					 ARM_L1_GPT_SIZE)
+#define ARM_L1_GPT_END			(ARM_L1_GPT_BASE +		\
+					 ARM_L1_GPT_SIZE - 1U)
+
+/*******************************************************************************
+ * "RMM TF-A shared region" specific defines.
+ ******************************************************************************/
+
+/* PLAT_ARM_EL3_RMM_SHARED_SIZE */
+#define ARM_EL3_RMM_SHARED_SIZE		(PAGE_SIZE)    /* 4KB */
+
+#define ARM_EL3_RMM_SHARED_BASE		(ARM_L1_GPT_BASE -		\
+					 ARM_EL3_RMM_SHARED_SIZE)
+
+#define ARM_EL3_RMM_SHARED_END		(ARM_EL3_RMM_SHARED_BASE +	\
+					 ARM_EL3_RMM_SHARED_SIZE - 1U)
+
+/*******************************************************************************
+ * RMM specific defines.
+ ******************************************************************************/
+
+/* ARM_REALM_SIZE */
+#define ARM_REALM_SIZE			(UL(0x02600000) -		\
+					 ARM_EL3_RMM_SHARED_SIZE)
+#define ARM_REALM_BASE			(ARM_EL3_RMM_SHARED_BASE -	\
+					 ARM_REALM_SIZE)
+
+#define ARM_REALM_END			(ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
+
+#define RMM_BASE			(ARM_REALM_BASE)
+#define RMM_LIMIT			(RMM_BASE + ARM_REALM_SIZE)
+#define RMM_SHARED_BASE			(ARM_EL3_RMM_SHARED_BASE)
+#define RMM_SHARED_SIZE			(ARM_EL3_RMM_SHARED_SIZE)
+
+/*******************************************************************************
+ * NRD_CSS_CARVEOUT_RESERVED region specific defines.
+ ******************************************************************************/
+
+#define NRD_CSS_CARVEOUT_RESERVED_BASE	(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE -		\
+					 NRD_CSS_DRAM1_CARVEOUT_SIZE)
+#define NRD_CSS_CARVEOUT_RESERVED_SIZE	(NRD_CSS_DRAM1_CARVEOUT_SIZE -	\
+					(ARM_EL3_RMM_SHARED_SIZE +	\
+					 ARM_REALM_SIZE +		\
+					 ARM_L1_GPT_SIZE))
+
+#define NRD_CSS_CARVEOUT_RESERVED_END	(NRD_CSS_CARVEOUT_RESERVED_BASE +\
+					 NRD_CSS_CARVEOUT_RESERVED_SIZE - 1U)
+
+/*******************************************************************************
+ * NS RAM specific defines specific defines.
+ ******************************************************************************/
+
+#define ARM_NS_DRAM1_BASE		ARM_DRAM1_BASE
+#define ARM_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -		\
+					 NRD_CSS_DRAM1_CARVEOUT_SIZE)
+
+#define ARM_NS_DRAM1_END		(ARM_NS_DRAM1_BASE +		\
+					 ARM_NS_DRAM1_SIZE - 1U)
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define V2M_MAP_FLASH0_RW						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define V2M_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_RO_DATA | EL3_PAS)
+
+#define ARM_MAP_L0_GPT_REGION						\
+		MAP_REGION_FLAT(					\
+			ARM_L0_GPT_BASE,				\
+			ARM_L0_GPT_SIZE,				\
+			MT_MEMORY | MT_RW | MT_ROOT)
+
+#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 | EL3_PAS)
+
+#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
+
+#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
+
+#define ARM_MAP_DRAM2							\
+		MAP_REGION_FLAT(					\
+			ARM_DRAM2_BASE,					\
+			ARM_DRAM2_SIZE,					\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#endif /* NRD_PLAT_ARM_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
new file mode 100644
index 0000000..c987621
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the RoS specific definitions for the third generation of
+ * platforms.
+ */
+
+#ifndef NRD_ROS_DEF3_H
+#define NRD_ROS_DEF3_H
+
+/*******************************************************************************
+ * RoS memory map related defines
+ ******************************************************************************/
+
+/* System peripherals */
+#define NRD_ROS_SYSTEM_PERIPH_BASE		UL(0x0C000000)
+#define NRD_ROS_SYSTEM_PERIPH_SIZE		UL(0x02000000)
+
+/* Platform peripherals */
+#define NRD_ROS_PLATFORM_PERIPH_BASE		UL(0x0E000000)
+#define NRD_ROS_PLATFORM_PERIPH_SIZE		UL(0x02000000)
+
+/* SMC0 */
+#define NRD_ROS_SMC0_BASE			UL(0x08000000)
+#define NRD_ROS_SMC0_SIZE			UL(0x04000000)
+
+#endif /* NRD_ROS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
new file mode 100644
index 0000000..c0fde85
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * third generation of platforms. RoS (Rest Of System) is used to refer to the
+ * part of the reference design platform that excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF3_H
+#define NRD_ROS_FW_DEF3_H
+
+#include <nrd_ros_def3.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PLATFORM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SYSTEM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEM_PERIPH_BASE,			\
+			NRD_ROS_SYSTEM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_V2M_MEM_PROTECT_MMAP					\
+		MAP_REGION_FLAT(					\
+			PLAT_ARM_MEM_PROT_ADDR,				\
+			V2M_FLASH_BLOCK_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_ROS_FLASH0_RO_MMAP						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+#endif /* NRD_ROS_FW_DEF3_H */
diff --git a/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h b/plat/arm/board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h
similarity index 72%
rename from plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h
rename to plat/arm/board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h
index e939163..c63d750 100644
--- a/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h
@@ -1,16 +1,16 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SGI_DMC620_TZC_REGIONS_H
-#define SGI_DMC620_TZC_REGIONS_H
+#ifndef NRD_DMC620_TZC_REGIONS_H
+#define NRD_DMC620_TZC_REGIONS_H
 
 #include <drivers/arm/tzc_dmc620.h>
 
 #if SPM_MM
-#define CSS_SGI_DMC620_TZC_REGIONS_DEF				\
+#define NRD_DMC620_TZC_REGIONS_DEF				\
 	{							\
 		.region_base = ARM_AP_TZC_DRAM1_BASE,		\
 		.region_top = PLAT_SP_IMAGE_NS_BUF_BASE - 1,	\
@@ -25,7 +25,7 @@
 		.sec_attr = TZC_DMC620_REGION_S_RDWR		\
 	}
 #else
-#define CSS_SGI_DMC620_TZC_REGIONS_DEF				\
+#define NRD_DMC620_TZC_REGIONS_DEF				\
 	{							\
 		.region_base = ARM_AP_TZC_DRAM1_BASE,		\
 		.region_top = ARM_AP_TZC_DRAM1_END,		\
@@ -33,4 +33,4 @@
 	}
 #endif /* SPM_MM */
 
-#endif /* SGI_DMC620_TZC_REGIONS_H */
+#endif /* NRD_DMC620_TZC_REGIONS_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd_plat.h b/plat/arm/board/neoverse_rd/common/include/nrd_plat.h
new file mode 100644
index 0000000..775f233
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_plat.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_PLAT_H
+#define NRD_PLAT_H
+
+/* BL31 platform setup common to all Neoverse RD platforms */
+void nrd_bl31_common_platform_setup(void);
+
+#endif /* NRD_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/board/neoverse_rd/common/include/nrd_ras.h
similarity index 66%
rename from plat/arm/css/sgi/include/sgi_ras.h
rename to plat/arm/board/neoverse_rd/common/include/nrd_ras.h
index d311807..768689c 100644
--- a/plat/arm/css/sgi/include/sgi_ras.h
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_ras.h
@@ -1,22 +1,22 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SGI_RAS_H
-#define SGI_RAS_H
+#ifndef NRD_RAS_H
+#define NRD_RAS_H
 
 #include <lib/extensions/ras.h>
 #include <plat/common/platform.h>
 
 /*
  * Interrupt type supported.
- * - SGI_RAS_INTR_TYPE_SPI: Denotes a SPI interrupt
- * - SGI_RAS_INTR_TYPE_PPI: Denotes a PPI interrupt
+ * - NRD_RAS_INTR_TYPE_SPI: Denotes a SPI interrupt
+ * - NRD_RAS_INTR_TYPE_PPI: Denotes a PPI interrupt
  */
-#define SGI_RAS_INTR_TYPE_SPI 0
-#define SGI_RAS_INTR_TYPE_PPI 1
+#define NRD_RAS_INTR_TYPE_SPI 0
+#define NRD_RAS_INTR_TYPE_PPI 1
 
 /*
  * MM Communicate information structure. Required to generate MM Communicate
@@ -29,15 +29,15 @@
 } mm_communicate_header_t;
 
 /* RAS error info data structure. */
-struct sgi_ras_ev_map {
+struct nrd_ras_ev_map {
 	int sdei_ev_num;	/* SDEI Event number */
 	int intr;		/* Physical intr number */
 	int intr_type;          /* Interrupt Type (SPI or PPI)*/
 };
 
 /* RAS config data structure. Must be defined by each platform. */
-struct plat_sgi_ras_config {
-	struct sgi_ras_ev_map *ev_map;
+struct plat_nrd_ras_config {
+	struct nrd_ras_ev_map *ev_map;
 	int ev_map_size;
 };
 
@@ -45,7 +45,7 @@
  * Find event map for a given interrupt number. On success, returns pointer
  * to the event map. On error, returns NULL.
  */
-struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num);
+struct nrd_ras_ev_map *nrd_find_ras_event_map_by_intr(uint32_t intr_num);
 
 /*
  * Initialization function for the framework.
@@ -53,16 +53,16 @@
  * Registers RAS config provided by the platform and then configures and
  * enables interrupt for each registered error. On success, return 0.
  */
-int sgi_ras_platform_setup(struct plat_sgi_ras_config *config);
+int nrd_ras_platform_setup(struct plat_nrd_ras_config *config);
 
 /* Base element RAM RAS interrupt handler function. */
-int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+int nrd_ras_sram_intr_handler(const struct err_record_info *err_rec,
 				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 nrd_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 */
+#endif /* NRD_RAS_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd_sdei.h b/plat/arm/board/neoverse_rd/common/include/nrd_sdei.h
new file mode 100644
index 0000000..f1b6015
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_sdei.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_SDEI_H
+#define NRD_SDEI_H
+
+#if SDEI_SUPPORT
+
+/* ARM SDEI dynamic shared event numbers */
+#define NRD_SDEI_DS_EVENT_0		U(804)
+#define NRD_SDEI_DS_EVENT_1		U(805)
+
+#define PLAT_ARM_PRIVATE_SDEI_EVENTS					      \
+		SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),			      \
+		SDEI_EXPLICIT_EVENT(NRD_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
+		SDEI_EXPLICIT_EVENT(NRD_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
+
+#define PLAT_ARM_SHARED_SDEI_EVENTS
+
+#endif /* SDEI_SUPPORT */
+
+#endif /* NRD_SDEI_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd_variant.h b/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
new file mode 100644
index 0000000..391c68c
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_VARIANT_H
+#define NRD_VARIANT_H
+
+/* SSC_VERSION values for SGI575 */
+#define SGI575_SSC_VER_PART_NUM			0x0783
+
+/* SID Version values for RD-N1E1-Edge */
+#define RD_N1E1_EDGE_SID_VER_PART_NUM		0x0786
+#define RD_E1_EDGE_CONFIG_ID			0x2
+
+/* SID Version values for RD-V1 */
+#define RD_V1_SID_VER_PART_NUM			0x078a
+
+/* SID Version values for RD-N2 */
+#define RD_N2_SID_VER_PART_NUM			0x07B7
+
+/* SID Version values for RD-N2 variants */
+#define RD_N2_CFG1_SID_VER_PART_NUM		0x07B6
+#define RD_N2_CFG3_SID_VER_PART_NUM		0x07F1
+
+/* SID Version values for RD-V2 */
+#define RD_V2_SID_VER_PART_NUM			0x07F2
+#define RD_V2_CONFIG_ID				0x1
+
+/* SID Version values for RD-Fremont */
+#define RD_FREMONT_SID_VER_PART_NUM		0x07EE
+#define RD_FREMONT_CONFIG_ID			0x0
+
+/* SID Version values for RD-Fremont variants */
+#define RD_FREMONT_CFG1_SID_VER_PART_NUM	0x07F9
+#define RD_FREMONT_CFG2_SID_VER_PART_NUM	0x07EE
+
+/* Structure containing Neoverse RD platform variant information */
+typedef struct nrd_platform_info {
+	unsigned int platform_id;	/* Part Number of the platform */
+	unsigned int config_id;		/* Config Id of the platform */
+	unsigned int chip_id;		/* Chip Id or Node number */
+	unsigned int multi_chip_mode;	/* Multi-chip mode availability */
+} nrd_platform_info_t;
+
+extern nrd_platform_info_t nrd_plat_info;
+
+/* returns the part number of the platform*/
+unsigned int plat_arm_nrd_get_platform_id(void);
+
+/* returns the configuration id of the platform */
+unsigned int plat_arm_nrd_get_config_id(void);
+
+/* returns true if operating in multi-chip configuration */
+unsigned int plat_arm_nrd_get_multi_chip_mode(void);
+
+#endif /* NRD_VARIANT_H */
diff --git a/plat/arm/css/sgi/include/plat_macros.S b/plat/arm/board/neoverse_rd/common/include/plat_macros.S
similarity index 85%
rename from plat/arm/css/sgi/include/plat_macros.S
rename to plat/arm/board/neoverse_rd/common/include/plat_macros.S
index 521bcc3..df7cfb6 100644
--- a/plat/arm/css/sgi/include/plat_macros.S
+++ b/plat/arm/board/neoverse_rd/common/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/board/neoverse_rd/common/nrd-common.mk
similarity index 71%
rename from plat/arm/css/sgi/sgi-common.mk
rename to plat/arm/board/neoverse_rd/common/nrd-common.mk
index efa3cc6..95a221f 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/board/neoverse_rd/common/nrd-common.mk
@@ -6,7 +6,7 @@
 
 CSS_USE_SCMI_SDS_DRIVER		:=	1
 
-CSS_ENT_BASE			:=	plat/arm/css/sgi
+NRD_COMMON_BASE			:=	plat/arm/board/neoverse_rd/common
 
 ENABLE_FEAT_RAS			:=	1
 
@@ -16,18 +16,18 @@
 
 HANDLE_EA_EL3_FIRST_NS		:=	0
 
-CSS_SGI_CHIP_COUNT		:=	1
+NRD_CHIP_COUNT		:=	1
 
-CSS_SGI_PLATFORM_VARIANT	:=	0
+NRD_PLATFORM_VARIANT	:=	0
 
 # Do not enable SVE
 ENABLE_SVE_FOR_NS		:=	0
 
 CTX_INCLUDE_FPREGS		:=	1
 
-INTERCONNECT_SOURCES	:=	${CSS_ENT_BASE}/sgi_interconnect.c
+INTERCONNECT_SOURCES	:=	${NRD_COMMON_BASE}/nrd_interconnect.c
 
-PLAT_INCLUDES		+=	-I${CSS_ENT_BASE}/include
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include
 
 # GIC-600 configuration
 GICV3_SUPPORT_GIC600	:=	1
@@ -39,18 +39,19 @@
 				plat/common/plat_gicv3.c	\
 				plat/arm/common/arm_gicv3.c
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/aarch64/sgi_helper.S
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/arch/aarch64/nrd_helper.S
 
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}			\
+				${NRD_COMMON_BASE}/nrd_bl1_setup.c	\
 				drivers/arm/sbsa/sbsa.c
 
-BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_image_load.c	\
+BL2_SOURCES		+=	${NRD_COMMON_BASE}/nrd_image_load.c	\
 				drivers/arm/css/sds/sds.c
 
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}			\
 				${ENT_GIC_SOURCES}			\
-				${CSS_ENT_BASE}/sgi_bl31_setup.c	\
-				${CSS_ENT_BASE}/sgi_topology.c          \
+				${NRD_COMMON_BASE}/nrd_bl31_setup.c	\
+				${NRD_COMMON_BASE}/nrd_topology.c	\
 				drivers/delay_timer/generic_delay_timer.c
 
 ifneq (${RESET_TO_BL31},0)
@@ -58,11 +59,9 @@
   Please set RESET_TO_BL31 to 0.")
 endif
 
-$(eval $(call add_define,SGI_PLAT))
+$(eval $(call add_define,NRD_CHIP_COUNT))
 
-$(eval $(call add_define,CSS_SGI_CHIP_COUNT))
-
-$(eval $(call add_define,CSS_SGI_PLATFORM_VARIANT))
+$(eval $(call add_define,NRD_PLATFORM_VARIANT))
 
 override CSS_LOAD_SCP_IMAGES	:=	0
 override NEED_BL2U		:=	no
@@ -79,5 +78,4 @@
 
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
 include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c
new file mode 100644
index 0000000..a0f656f
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/soc/common/soc_css.h>
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+
+void soc_css_init_nic400(void)
+{
+}
+
+void soc_css_init_pcie(void)
+{
+}
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
new file mode 100644
index 0000000..5a7dfb1
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <plat/common/platform.h>
+
+#include <nrd_ras.h>
+#include <nrd_variant.h>
+
+nrd_platform_info_t nrd_plat_info;
+
+static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+};
+
+static scmi_channel_plat_info_t plat_rd_scmi_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#if (NRD_CHIP_COUNT > 1)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(1),
+		.db_reg_addr = PLAT_CSS_MHU_BASE
+			+ NRD_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 2)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(2),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 3)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(3),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+};
+
+static scmi_channel_plat_info_t plat3_rd_scmi_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#if (NRD_CHIP_COUNT > 1)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(1),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(1) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 2)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(2),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(2) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 3)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(3),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(3) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+{
+	if (nrd_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_N2_CFG3_SID_VER_PART_NUM) {
+		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info)) {
+			panic();
+		}
+		return &plat_rd_scmi_info[channel_id];
+	} else if (nrd_plat_info.platform_id == RD_FREMONT_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_FREMONT_CFG1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_FREMONT_CFG2_SID_VER_PART_NUM) {
+		if (channel_id >= ARRAY_SIZE(plat3_rd_scmi_info)) {
+			panic();
+		}
+		return &plat3_rd_scmi_info[channel_id];
+	} else if (nrd_plat_info.platform_id == SGI575_SSC_VER_PART_NUM) {
+		return &sgi575_scmi_plat_info;
+	} else {
+		panic();
+	}
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	nrd_plat_info.platform_id = plat_arm_nrd_get_platform_id();
+	nrd_plat_info.config_id = plat_arm_nrd_get_config_id();
+	nrd_plat_info.multi_chip_mode = plat_arm_nrd_get_multi_chip_mode();
+
+	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
+
+void nrd_bl31_common_platform_setup(void)
+{
+	generic_delay_timer_init();
+
+	arm_bl31_platform_setup();
+
+	/* Configure the warm reboot SGI for primary core */
+	css_setup_cpu_pwr_down_intr();
+
+#if CSS_SYSTEM_GRACEFUL_RESET
+	/* Register priority level handlers for reboot */
+	ehf_register_priority_handler(PLAT_REBOOT_PRI,
+			css_reboot_interrupt_handler);
+#endif
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+	/*
+	 * For RD-E1-Edge, only CPU power ON/OFF, PSCI platform callbacks are
+	 * supported.
+	 */
+	if (((nrd_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
+	    (nrd_plat_info.config_id == RD_E1_EDGE_CONFIG_ID))) {
+		ops->cpu_standby = NULL;
+		ops->system_off = NULL;
+		ops->system_reset = NULL;
+		ops->get_sys_suspend_power_state = NULL;
+		ops->pwr_domain_suspend = NULL;
+		ops->pwr_domain_suspend_finish = NULL;
+	}
+
+	return css_scmi_override_pm_ops(ops);
+}
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/board/neoverse_rd/common/nrd_image_load.c
similarity index 90%
rename from plat/arm/css/sgi/sgi_image_load.c
rename to plat/arm/board/neoverse_rd/common/nrd_image_load.c
index 0a9bba9..15d90be 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_image_load.c
@@ -12,10 +12,9 @@
 #include <drivers/arm/css/sds.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
 #include <platform_def.h>
-#include <sgi_base_platform_def.h>
-#include <sgi_variant.h>
+
+#include <nrd_variant.h>
 
 /*
  * Information about the isolated CPUs obtained from SDS.
@@ -26,7 +25,7 @@
 };
 
 /* Function to read isolated CPU MPID list from SDS. */
-void plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
+void plat_arm_nrd_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
 {
 	int ret;
 
@@ -75,7 +74,7 @@
  *    isolated-cpu-list = <0>
  * }
  ******************************************************************************/
-static int plat_sgi_append_config_node(void)
+static int plat_nrd_append_config_node(void)
 {
 	bl_mem_params_node_t *mem_params;
 	void *fdt;
@@ -103,28 +102,28 @@
 		return -1;
 	}
 
-	platid = plat_arm_sgi_get_platform_id();
+	platid = plat_arm_nrd_get_platform_id();
 	err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
 	if (err < 0) {
 		ERROR("Failed to set platform-id\n");
 		return -1;
 	}
 
-	platcfg = plat_arm_sgi_get_config_id();
+	platcfg = plat_arm_nrd_get_config_id();
 	err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
 	if (err < 0) {
 		ERROR("Failed to set config-id\n");
 		return -1;
 	}
 
-	platcfg = plat_arm_sgi_get_multi_chip_mode();
+	platcfg = plat_arm_nrd_get_multi_chip_mode();
 	err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
 	if (err < 0) {
 		ERROR("Failed to set multi-chip-mode\n");
 		return -1;
 	}
 
-	plat_arm_sgi_get_isolated_cpu_list(&cpu_mpid_list);
+	plat_arm_nrd_get_isolated_cpu_list(&cpu_mpid_list);
 	if (cpu_mpid_list.num_entries > 0) {
 		err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list",
 				&cpu_mpid_list,
@@ -148,7 +147,7 @@
 {
 	int ret;
 
-	ret = plat_sgi_append_config_node();
+	ret = plat_nrd_append_config_node();
 	if (ret != 0)
 		panic();
 
diff --git a/plat/arm/css/sgi/sgi_interconnect.c b/plat/arm/board/neoverse_rd/common/nrd_interconnect.c
similarity index 94%
rename from plat/arm/css/sgi/sgi_interconnect.c
rename to plat/arm/board/neoverse_rd/common/nrd_interconnect.c
index e9cd812..4f9cc85 100644
--- a/plat/arm/css/sgi/sgi_interconnect.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_interconnect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/board/neoverse_rd/common/nrd_plat1.c
similarity index 79%
rename from plat/arm/css/sgi/sgi_plat.c
rename to plat/arm/board/neoverse_rd/common/nrd_plat1.c
index fe64d34..32444f4 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat1.c
@@ -16,15 +16,11 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <drivers/arm/sbsa.h>
-#include <sgi_base_platform_def.h>
 
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
 
-#define SGI_MAP_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_DEVICE | MT_RO | MT_SECURE)
 /*
  * Table of regions for different BL stages to map using the MMU.
  * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
@@ -35,30 +31,30 @@
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
-	CSS_SGI_MAP_DEVICE,
-	SOC_CSS_MAP_DEVICE,
+	NRD_MAP_FLASH0_RO,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PERIPH_MMAP(0),
 	{0}
 };
 #endif
 #if IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
+	NRD_MAP_FLASH0_RO,
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	CSS_SGI_MAP_DEVICE,
-	SOC_CSS_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PERIPH_MMAP(0),
 	ARM_MAP_NS_DRAM1,
-#if CSS_SGI_CHIP_COUNT > 1
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_PERIPH_MMAP(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_PERIPH_MMAP(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_PERIPH_MMAP(3),
 #endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
@@ -76,11 +72,11 @@
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
 	V2M_MAP_IOFPGA,
-	CSS_SGI_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	SOC_CSS_MAP_DEVICE,
+	NRD_ROS_PERIPH_MMAP(0),
 #if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
@@ -89,15 +85,11 @@
 
 #if SPM_MM && defined(IMAGE_BL31)
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
-	PLAT_ARM_SECURE_MAP_SYSTEMREG,
-	PLAT_ARM_SECURE_MAP_NOR2,
-	SOC_PLATFORM_SECURE_UART,
-	PLAT_ARM_SECURE_MAP_DEVICE,
+	NRD_ROS_SECURE_SYSTEMREG_USER_MMAP,
+	NRD_ROS_SECURE_NOR2_USER_MMAP,
+	NRD_CSS_SECURE_UART_MMAP,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
-#if ENABLE_FEAT_RAS && FFH_SUPPORT
-	CSS_SGI_SP_CPER_BUF_MMAP,
-#endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
 	{0}
@@ -169,21 +161,21 @@
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(NRD_CSS_WDOG_BASE, NRD_CSS_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(NRD_CSS_WDOG_BASE);
 }
 
-static sds_region_desc_t sgi_sds_regions[] = {
+static sds_region_desc_t nrd_sds_regions[] = {
 	{ .base = PLAT_ARM_SDS_MEM_BASE },
 };
 
 sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
 {
-	*region_count = ARRAY_SIZE(sgi_sds_regions);
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
 
-	return sgi_sds_regions;
+	return nrd_sds_regions;
 }
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/board/neoverse_rd/common/nrd_plat2.c
similarity index 78%
rename from plat/arm/css/sgi/sgi_plat_v2.c
rename to plat/arm/board/neoverse_rd/common/nrd_plat2.c
index d241f70..4a7b021 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat2.c
@@ -23,35 +23,35 @@
  */
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
-	CSS_SGI_MAP_DEVICE,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE,
-	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
 	{0}
 };
 #endif
 
 #if IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	CSS_SGI_MAP_DEVICE,
-	SOC_MEMCNTRL_MAP_DEVICE,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE,
-	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_MEMCNTRL_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
 	ARM_MAP_NS_DRAM1,
-#if CSS_SGI_CHIP_COUNT > 1
-	SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(1),
+#if NRD_CHIP_COUNT > 1
+	NRD_ROS_MEMCNTRL_MMAP(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-	SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(2),
+#if NRD_CHIP_COUNT > 2
+	NRD_ROS_MEMCNTRL_MMAP(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-	SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(3),
+#if NRD_CHIP_COUNT > 3
+	NRD_ROS_MEMCNTRL_MMAP(3),
 #endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
@@ -68,13 +68,13 @@
 
 #if IMAGE_BL31
 const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
+	NRD_CSS_SHARED_RAM_MMAP(0),
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	CSS_SGI_MAP_DEVICE,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE,
-	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
 #if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
@@ -83,14 +83,14 @@
 
 #if SPM_MM && defined(IMAGE_BL31)
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
-	PLAT_ARM_SECURE_MAP_SYSTEMREG,
-	PLAT_ARM_SECURE_MAP_NOR2,
-	SOC_PLATFORM_SECURE_UART,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
+	NRD_ROS_SECURE_SYSTEMREG_USER_MMAP,
+	NRD_ROS_SECURE_NOR2_USER_MMAP,
+	NRD_CSS_SECURE_UART_USER_MMAP,
+	NRD_ROS_PLATFORM_PERIPH_USER_MMAP,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
 #if ENABLE_FEAT_RAS && FFH_SUPPORT
-	CSS_SGI_SP_CPER_BUF_MMAP,
+	NRD_CSS_SP_CPER_BUF_MMAP,
 #endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
@@ -171,21 +171,21 @@
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(NRD_CSS_SECURE_WDOG_BASE, NRD_CSS_SECURE_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(NRD_CSS_SECURE_WDOG_BASE);
 }
 
-static sds_region_desc_t sgi_sds_regions[] = {
+static sds_region_desc_t nrd_sds_regions[] = {
 	{ .base = PLAT_ARM_SDS_MEM_BASE },
 };
 
 sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
 {
-	*region_count = ARRAY_SIZE(sgi_sds_regions);
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
 
-	return sgi_sds_regions;
+	return nrd_sds_regions;
 }
diff --git a/plat/arm/board/neoverse_rd/common/nrd_plat3.c b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
new file mode 100644
index 0000000..7b98052
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/utils_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL3 */
+
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	NRD_ROS_V2M_MEM_PROTECT_MMAP,
+#endif
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	NRD_CSS_NS_DRAM1_MMAP,
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
+	NRD_CSS_BL1_RW_MMAP,
+#endif
+	NRD_CSS_GPT_L1_DRAM_MMAP,
+	NRD_CSS_RMM_REGION_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL2 */
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	NRD_ROS_V2M_MEM_PROTECT_MMAP,
+#endif
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	NRD_CSS_GPT_L1_DRAM_MMAP,
+	NRD_CSS_EL3_RMM_SHARED_MEM_MMAP,
+	NRD_CSS_GPC_SMMU_SMMUV3_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL31 */
+
+ARM_CASSERT_MMAP
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+	return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(NRD_CSS_AP_SECURE_WDOG_BASE,
+			NRD_CSS_AP_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(NRD_CSS_AP_SECURE_WDOG_BASE);
+}
+
+static sds_region_desc_t nrd_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
+
+	return nrd_sds_regions;
+}
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/board/neoverse_rd/common/nrd_topology.c
similarity index 78%
rename from plat/arm/css/sgi/sgi_topology.c
rename to plat/arm/board/neoverse_rd/common/nrd_topology.c
index 1c3b5bf..ff04b2b 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <plat/arm/common/plat_arm.h>
 
 /*
- * Common topology related methods for SGI and RD based platforms
+ * Common topology related methods for Neoverse RD platforms
  */
 /*******************************************************************************
  * This function returns the core count within the cluster corresponding to
@@ -15,7 +15,7 @@
  ******************************************************************************/
 unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
 {
-	return CSS_SGI_MAX_CPUS_PER_CLUSTER;
+	return NRD_MAX_CPUS_PER_CLUSTER;
 }
 
 #if ARM_PLAT_MT
@@ -24,6 +24,6 @@
  *****************************************************************************/
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
 {
-	return CSS_SGI_MAX_PE_PER_CPU;
+	return NRD_MAX_PE_PER_CPU;
 }
 #endif
diff --git a/plat/arm/css/sgi/ras/sgi_ras_common.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_common.c
similarity index 65%
rename from plat/arm/css/sgi/ras/sgi_ras_common.c
rename to plat/arm/board/neoverse_rd/common/ras/nrd_ras_common.c
index 9789670..24f4506 100644
--- a/plat/arm/css/sgi/ras/sgi_ras_common.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,27 +11,27 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
-#include <sgi_ras.h>
+#include <nrd_ras.h>
 
-static struct plat_sgi_ras_config *sgi_ras_config;
+static struct plat_nrd_ras_config *nrd_ras_config;
 
 /*
  * Find event map for a given interrupt number. On success, returns pointer to
  * the event map. On error, returns NULL.
  */
-struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
+struct nrd_ras_ev_map *nrd_find_ras_event_map_by_intr(uint32_t intr_num)
 {
-	struct sgi_ras_ev_map *map;
+	struct nrd_ras_ev_map *map;
 	int size;
 	int i;
 
-	if (sgi_ras_config == NULL) {
+	if (nrd_ras_config == NULL) {
 		ERROR("RAS config is NULL\n");
 		return NULL;
 	}
 
-	map = sgi_ras_config->ev_map;
-	size = sgi_ras_config->ev_map_size;
+	map = nrd_ras_config->ev_map;
+	size = nrd_ras_config->ev_map_size;
 
 	for (i = 0; i < size; i++) {
 		if (map->intr == intr_num)
@@ -47,14 +47,14 @@
  * Programs GIC registers and configures interrupt ID's as Group0 EL3
  * interrupts. Current support is to register PPI and SPI interrupts.
  */
-static void sgi_ras_intr_configure(int intr, int intr_type)
+static void nrd_ras_intr_configure(int intr, int intr_type)
 {
 	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
 	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
 	plat_ic_clear_interrupt_pending(intr);
 
 	/* Routing mode option available only for SPI interrupts */
-	if (intr_type == SGI_RAS_INTR_TYPE_SPI) {
+	if (intr_type == NRD_RAS_INTR_TYPE_SPI) {
 		plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
 					(u_register_t)read_mpidr_el1());
 	}
@@ -67,15 +67,15 @@
  * Registers RAS config provided by the platform and then configures and
  * enables interrupt for each registered error. On success, return 0.
  */
-int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
+int nrd_ras_platform_setup(struct plat_nrd_ras_config *config)
 {
-	struct sgi_ras_ev_map *map;
+	struct nrd_ras_ev_map *map;
 	int size;
 	int i;
 
 	/* Check if parameter is valid. */
 	if (config == NULL) {
-		ERROR("SGI: Failed to register RAS config\n");
+		ERROR("NRD: Failed to register RAS config\n");
 		return -1;
 	}
 
@@ -83,17 +83,17 @@
 	 * Maintain a reference to the platform RAS config data for later
 	 * use.
 	 */
-	sgi_ras_config = config;
+	nrd_ras_config = config;
 
-	map = sgi_ras_config->ev_map;
-	size = sgi_ras_config->ev_map_size;
+	map = nrd_ras_config->ev_map;
+	size = nrd_ras_config->ev_map_size;
 
 	for (i = 0; i < size; i++) {
-		sgi_ras_intr_configure(map->intr, map->intr_type);
+		nrd_ras_intr_configure(map->intr, map->intr_type);
 		map++;
 	}
 
-	INFO("SGI: Platform RAS setup successful\n");
+	INFO("NRD: Platform RAS setup successful\n");
 
 	return 0;
 }
diff --git a/plat/arm/css/sgi/ras/sgi_ras_cpu.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
similarity index 74%
rename from plat/arm/css/sgi/ras/sgi_ras_cpu.c
rename to plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
index 5e77dbb..371bde6 100644
--- a/plat/arm/css/sgi/ras/sgi_ras_cpu.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 #include <services/sdei.h>
 #include <services/spm_mm_svc.h>
 
-#include <sgi_ras.h>
+#include <nrd_ras.h>
 
 #define CPU_CONTEXT_REG_GPR_ARR_SIZE 32
 #define CPU_CONTEXT_REG_EL1_ARR_SIZE 17
@@ -95,39 +95,39 @@
 						  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->ErrCtxEl2Reg[0]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						elr_el2);
+	cpu_info->ErrCtxEl2Reg[1]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						esr_el2);
+	cpu_info->ErrCtxEl2Reg[2]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						far_el2);
+	cpu_info->ErrCtxEl2Reg[3]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hacr_el2);
+	cpu_info->ErrCtxEl2Reg[4]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hcr_el2);
+	cpu_info->ErrCtxEl2Reg[5]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hpfar_el2);
+	cpu_info->ErrCtxEl2Reg[6]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						mair_el2);
+	cpu_info->ErrCtxEl2Reg[7]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						sctlr_el2);
+	cpu_info->ErrCtxEl2Reg[8]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						sp_el2);
+	cpu_info->ErrCtxEl2Reg[9]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						spsr_el2);
+	cpu_info->ErrCtxEl2Reg[10]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						tcr_el2);
+	cpu_info->ErrCtxEl2Reg[11]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						tpidr_el2);
+	cpu_info->ErrCtxEl2Reg[12]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						ttbr0_el2);
+	cpu_info->ErrCtxEl2Reg[13]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						vtcr_el2);
+	cpu_info->ErrCtxEl2Reg[14]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						vttbr_el2);
+	cpu_info->ErrCtxEl2Reg[15]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						esr_el2);
+#endif /* CTX_INCLUDE_EL2_REGS */
 
 	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
 						   CTX_ELR_EL3);
@@ -143,11 +143,11 @@
 }
 
 /* CPU RAS interrupt handler */
-int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
+int nrd_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;
+	struct nrd_ras_ev_map *ras_map;
 	mm_communicate_header_t *header;
 	cpu_err_info cpu_info = {0};
 	uint64_t clear_status;
@@ -186,9 +186,9 @@
 	 * 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);
+	ras_map = nrd_find_ras_event_map_by_intr(intr);
 	if (ras_map == NULL) {
-		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+		ERROR("NRD: RAS error info for interrupt id: %d not found\n",
 			intr);
 		return -1;
 	}
diff --git a/plat/arm/css/sgi/ras/sgi_ras_sram.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_sram.c
similarity index 81%
rename from plat/arm/css/sgi/ras/sgi_ras_sram.c
rename to plat/arm/board/neoverse_rd/common/ras/nrd_ras_sram.c
index b100700..96aa864 100644
--- a/plat/arm/css/sgi/ras/sgi_ras_sram.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_sram.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include <services/spm_mm_svc.h>
 
 #include <platform_def.h>
-#include <sgi_ras.h>
+#include <nrd_ras.h>
 
 /* Base Element RAM Error Record offsets. */
 #define ERRSTATUS	U(0)
@@ -22,11 +22,11 @@
  * Base Element RAM error information data structure communicated as part of MM
  * Communication data payload.
  */
-typedef struct sgi_sram_err_info {
+typedef struct nrd_sram_err_info {
 	uint32_t err_status;
 	uint32_t err_code;
 	uint32_t err_addr;
-} sgi_sram_err_info_t;
+} nrd_sram_err_info_t;
 
 /*
  * MM Communicate message header GUID to indicate the payload is intended for
@@ -38,13 +38,13 @@
 };
 
 /* Base element RAM RAS error interrupt handler */
-int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+int nrd_ras_sram_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;
+	struct nrd_ras_ev_map *ras_map;
 	mm_communicate_header_t *header;
-	sgi_sram_err_info_t sram_info;
+	nrd_sram_err_info_t sram_info;
 	uintptr_t base_addr;
 	uint32_t clear_status, intr;
 	int ret;
@@ -52,12 +52,13 @@
 	cm_el1_sysregs_context_save(NON_SECURE);
 	intr = data->interrupt;
 
-	INFO("SGI: Base element RAM interrupt [%d] handler\n", intr);
+	INFO("NRD: Base element RAM interrupt [%d] handler\n", intr);
 
 	/* Determine error record base address to read. */
 	base_addr = 0;
-	if (intr == NS_RAM_ECC_CE_INT || intr == NS_RAM_ECC_UE_INT) {
-		base_addr = SOC_NS_RAM_ERR_REC_BASE;
+	if (intr == NRD_CSS_NS_RAM_ECC_CE_INT ||
+		intr == NRD_CSS_NS_RAM_ECC_UE_INT) {
+		base_addr = NRD_CSS_NS_RAM_ERR_REC_BASE;
 	}
 	sram_info.err_status = mmio_read_32(base_addr + ERRSTATUS);
 	sram_info.err_code = mmio_read_32(base_addr + ERRCODE);
@@ -87,9 +88,9 @@
 	 * 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);
+	ras_map = nrd_find_ras_event_map_by_intr(intr);
 	if (ras_map == NULL) {
-		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+		ERROR("NRD: RAS error info for interrupt id: %d not found\n",
 			intr);
 		return -1;
 	}
diff --git a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_fw_config.dts
similarity index 70%
rename from plat/arm/board/rdv1/fdts/rdv1_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_fw_config.dts
index 9c9cefe..62ba0fa 100644
--- a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,13 +13,13 @@
 		compatible = "fconf,dyn_cfg-dtb_registry";
 
 		tb_fw-config {
-			load-address = <0x0 0x4001300>;
+			load-address = <0x0 0x01f300>;
 			max-size = <0x200>;
 			id = <TB_FW_CONFIG_ID>;
 		};
 
 		nt_fw-config {
-			load-address = <0x0 0xFEF00000>;
+			load-address = <0x0 0xF3000000>;
 			max-size = <0x0100000>;
 			id = <NT_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_nt_fw_config.dts
similarity index 79%
copy from plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
copy to plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_nt_fw_config.dts
index 62ba2c3..62cad39 100644
--- a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 /dts-v1/;
 / {
 	/* compatible string */
-	compatible = "arm,rd-v1";
+	compatible = "arm,rd-fremont";
 
 	/*
 	 * Place holder for system-id node with default values. The
diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_tb_fw_config.dts
similarity index 90%
rename from plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_tb_fw_config.dts
index 49eda27..a4c7c72 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdfremont/include/platform_def.h
new file mode 100644
index 0000000..b55dbe8
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/include/platform_def.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/arm/css/common/css_def.h>
+#include <nrd_css_fw_def3.h>
+#include <nrd_pas_def3.h>
+#include <nrd_plat_arm_def3.h>
+#include <nrd_ros_fw_def3.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+/* PE-Cluster count */
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_CLUSTER_COUNT		U(8)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define PLAT_ARM_CLUSTER_COUNT		U(4)
+#else
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#endif
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+/* Shared RAM*/
+#define NRD_CSS_SHARED_SRAM_SIZE	UL(0x000100000)
+
+/* DRAM1 */
+#define NRD_CSS_DRAM1_SIZE		ULL(0x80000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000)
+
+/* Address bits */
+#define NRD_ADDR_BITS_PER_CHIP		U(36)  /* 64GB */
+
+/*
+ * In the current implementation, the RoT Service request that requires the
+ * biggest message buffer is the RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * maximum required buffer size is calculated based on the platform-specific
+ * needs of this request.
+ */
+#define PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE	UL(0x1000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_mhuv3.h b/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_mhuv3.h
new file mode 100644
index 0000000..400dcc5
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_mhuv3.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDFREMONT_MHUV3_H
+#define RDFREMONT_MHUV3_H
+
+void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender);
+
+#endif /* RDFREMONT_MHUV3_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_rse_comms.h b/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_rse_comms.h
new file mode 100644
index 0000000..ad1bc23
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_rse_comms.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDFREMONT_RSE_COMMS_H
+#define RDFREMONT_RSE_COMMS_H
+
+int plat_rse_comms_init(void);
+
+#endif /* RDFREMONT_RSE_COMMS_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/platform.mk b/plat/arm/board/neoverse_rd/platform/rdfremont/platform.mk
new file mode 100644
index 0000000..bca6172
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/platform.mk
@@ -0,0 +1,139 @@
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RD_FREMONT_VARIANTS := 0 1 2
+ifneq ($(NRD_PLATFORM_VARIANT),						\
+	$(filter $(NRD_PLATFORM_VARIANT),$(RD_FREMONT_VARIANTS)))
+	$(error "NRD_PLATFORM_VARIANT for RD-FREMONT should be 0, 1, or 2,"
+	"currently set to ${NRD_PLATFORM_VARIANT}.")
+endif
+
+$(eval $(call CREATE_SEQ,SEQ,4))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
+	$(error  "Chip count for RD-Fremont-MC should be either $(SEQ) \
+	currently it is set to ${NRD_CHIP_COUNT}.")
+endif
+
+# Build options
+# Major and Minor versions
+override ARM_ARCH_MAJOR			:= 8
+override ARM_ARCH_MINOR			:= 7
+
+# Image flags
+override NEED_BL1			:= yes
+override NEED_BL2			:= yes
+override NEED_BL32			:= no
+override NEED_RMM			:= no
+
+# Misc options
+override CTX_INCLUDE_AARCH32_REGS	:= 0
+
+# RD-Fremont platform uses GIC-700 which is based on GICv4.1
+GIC_ENABLE_V4_EXTN			:= 1
+
+# Enable GIC multichip extension only for multichip platforms
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
+GICV3_IMPL_GIC600_MULTICHIP	:= 1
+endif
+
+# RD-Fremont uses MHUv3
+PLAT_MHU_VERSION := 3
+
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
+include drivers/arm/rse/rse_comms.mk
+include drivers/auth/mbedtls/mbedtls_common.mk
+ifeq (${MEASURED_BOOT},1)
+include drivers/measured_boot/rse/rse_measured_boot.mk
+endif
+
+RDFREMONT_BASE	=	plat/arm/board/neoverse_rd/platform/rdfremont
+
+PLAT_INCLUDES	+=	-I${NRD_COMMON_BASE}/include/nrd3/		\
+			-I${RDFREMONT_BASE}/include/			\
+			-Iinclude/lib/psa
+
+NRD_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
+
+# Source files for RD-Fremont variants
+PLAT_BL_COMMON_SOURCES							\
+		+=	${NRD_COMMON_BASE}/nrd_plat3.c			\
+			${RDFREMONT_BASE}/rdfremont_common.c
+
+PLAT_MEASURED_BOOT_SOURCES						\
+		:=	${MEASURED_BOOT_SOURCES} 			\
+			${RSE_COMMS_SOURCES}				\
+			${RDFREMONT_BASE}/rdfremont_common_measured_boot.c \
+			lib/psa/measured_boot.c
+
+BL1_SOURCES	+=	${NRD_CPU_SOURCES}				\
+			${RDFREMONT_BASE}/rdfremont_err.c		\
+			${RDFREMONT_BASE}/rdfremont_mhuv3.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES	+=	${RDFREMONT_BASE}/rdfremont_trusted_boot.c
+endif
+ifeq (${MEASURED_BOOT},1)
+BL1_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
+			${RDFREMONT_BASE}/rdfremont_bl1_measured_boot.c
+endif
+
+BL2_SOURCES	+=	${RDFREMONT_BASE}/rdfremont_bl2_setup.c		\
+			${RDFREMONT_BASE}/rdfremont_err.c		\
+			${RDFREMONT_BASE}/rdfremont_mhuv3.c		\
+			${RDFREMONT_BASE}/rdfremont_security.c		\
+			lib/utils/mem_region.c				\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL2_SOURCES	+=	${RDFREMONT_BASE}/rdfremont_trusted_boot.c
+endif
+ifeq (${MEASURED_BOOT},1)
+BL2_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
+			${RDFREMONT_BASE}/rdfremont_bl2_measured_boot.c
+endif
+
+BL31_SOURCES	+=	${NRD_CPU_SOURCES}				\
+			${MBEDTLS_SOURCES}				\
+			${RSE_COMMS_SOURCES}				\
+			${RDFREMONT_BASE}/rdfremont_bl31_setup.c	\
+			${RDFREMONT_BASE}/rdfremont_mhuv3.c		\
+			${RDFREMONT_BASE}/rdfremont_topology.c		\
+			${RDFREMONT_BASE}/rdfremont_plat_attest_token.c	\
+			${RDFREMONT_BASE}/rdfremont_realm_attest_key.c	\
+			drivers/arm/smmu/smmu_v3.c			\
+			drivers/cfi/v2m/v2m_flash.c			\
+			lib/psa/cca_attestation.c			\
+			lib/psa/delegated_attestation.c			\
+			lib/utils/mem_region.c				\
+			plat/arm/common/arm_dyn_cfg.c			\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
+BL31_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
+endif
+
+# XLAT options for RD-Fremont variants
+BL31_CFLAGS	+=      -DPLAT_XLAT_TABLES_DYNAMIC
+BL2_CFLAGS	+=      -DPLAT_XLAT_TABLES_DYNAMIC
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES	+=	${RDFREMONT_BASE}/fdts/${PLAT}_fw_config.dts	\
+			${RDFREMONT_BASE}/fdts/${PLAT}_tb_fw_config.dts \
+			${RDFREMONT_BASE}/fdts/${PLAT}_nt_fw_config.dts
+
+FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+# Features for RD-Fremont variants
+override ENABLE_FEAT_MPAM	:= 2
+override ENABLE_FEAT_AMU	:= 2
+override ENABLE_SVE_FOR_SWD	:= 1
+override ENABLE_SVE_FOR_NS	:= 2
+override ENABLE_FEAT_MTE2	:= 2
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl1_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl1_measured_boot.c
new file mode 100644
index 0000000..92e96c2
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl1_measured_boot.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#include <nrd_plat.h>
+#include <rdfremont_rse_comms.h>
+
+/*
+ * Platform specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rse_mboot_metadata rdfremont_rse_mboot_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.slot = U(8),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = TB_FW_CONFIG_ID,
+		.slot = U(9),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = BL2_IMAGE_ID,
+		.slot = U(10),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = RSE_MBOOT_INVALID_ID
+	}
+};
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)plat_rse_comms_init();
+
+	rse_measured_boot_init(rdfremont_rse_mboot_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_measured_boot.c
new file mode 100644
index 0000000..570c33a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_measured_boot.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <plat/common/common_def.h>
+#include <platform_def.h>
+
+#include <nrd_plat.h>
+#include <rdfremont_rse_comms.h>
+
+/*
+ * Platform specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rse_mboot_metadata rdfremont_rse_mboot_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.slot = U(11),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = HW_CONFIG_ID,
+		.slot = U(12),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.slot = U(13),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+#if ENABLE_RME
+	{
+		.id = RMM_IMAGE_ID,
+		.slot = U(14),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_RMM_IMAGE_STRING,
+		.lock_measurement = false
+	},
+#endif /* ENABLE_RME */
+	{
+		.id = RSE_MBOOT_INVALID_ID
+	}
+};
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)plat_rse_comms_init();
+
+	rse_measured_boot_init(rdfremont_rse_mboot_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_setup.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_setup.c
new file mode 100644
index 0000000..8dac8d3
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_setup.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <nrd_plat.h>
+
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	NRD_PAS_SHARED_SRAM,
+	NRD_PAS_SYSTEM_NCI,
+	NRD_PAS_DEBUG_NIC,
+	NRD_PAS_NS_UART,
+	NRD_PAS_REALM_UART,
+	NRD_PAS_AP_NS_WDOG,
+	NRD_PAS_AP_ROOT_WDOG,
+	NRD_PAS_AP_SECURE_WDOG,
+	NRD_PAS_SECURE_SRAM_ERB_AP,
+	NRD_PAS_NS_SRAM_ERB_AP,
+	NRD_PAS_ROOT_SRAM_ERB_AP,
+	NRD_PAS_REALM_SRAM_ERB_AP,
+	NRD_PAS_SECURE_SRAM_ERB_SCP,
+	NRD_PAS_NS_SRAM_ERB_SCP,
+	NRD_PAS_ROOT_SRAM_ERB_SCP,
+	NRD_PAS_REALM_SRAM_ERB_SCP,
+	NRD_PAS_SECURE_SRAM_ERB_MCP,
+	NRD_PAS_NS_SRAM_ERB_MCP,
+	NRD_PAS_ROOT_SRAM_ERB_MCP,
+	NRD_PAS_REALM_SRAM_ERB_MCP,
+	NRD_PAS_SECURE_SRAM_ERB_RSE,
+	NRD_PAS_NS_SRAM_ERB_RSE,
+	NRD_PAS_ROOT_SRAM_ERB_RSE,
+	NRD_PAS_REALM_SRAM_ERB_RSE,
+	NRD_PAS_RSE_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_RSE_NS_SRAM_ERB_RSM,
+	NRD_PAS_SCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_SCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_MCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_MCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_AP_SCP_ROOT_MHU,
+	NRD_PAS_AP_MCP_NS_MHU,
+	NRD_PAS_AP_MCP_SECURE_MHU,
+	NRD_PAS_AP_MCP_ROOT_MHU,
+	NRD_PAS_AP_RSE_NS_MHU,
+	NRD_PAS_AP_RSE_SECURE_MHU,
+	NRD_PAS_AP_RSE_ROOT_MHU,
+	NRD_PAS_AP_RSE_REALM_MHU,
+	NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU,
+	NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR,
+	NRD_PAS_STM_SYSTEM_ITS,
+	NRD_PAS_SCP_MCP_RSE_SHARED_SRAM,
+	NRD_PAS_GIC,
+	NRD_PAS_NS_DRAM,
+	NRD_PAS_RMM,
+	NRD_PAS_L1GPT,
+	NRD_PAS_CMN,
+	NRD_PAS_LCP_PERIPHERAL,
+	NRD_PAS_DDR_IO,
+	NRD_PAS_SMMU_NCI_IO,
+	NRD_PAS_DRAM2_CHIP0,
+#if NRD_CHIP_COUNT > 1
+	NRD_PAS_DRAM1_CHIP1,
+	NRD_PAS_DRAM2_CHIP1,
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_PAS_DRAM1_CHIP2,
+	NRD_PAS_DRAM2_CHIP2,
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_PAS_DRAM1_CHIP3,
+	NRD_PAS_DRAM2_CHIP3
+#endif
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+	.pas_region_base  = pas_regions,
+	.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+	.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+	.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+	.l0_size = (size_t)ARM_L0_GPT_SIZE,
+	.l1_size = (size_t)ARM_L1_GPT_SIZE,
+	.pps = GPCCR_PPS_256TB,
+	.pgs = GPCCR_PGS_4K
+};
+
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+	return &arm_gpt_info;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl31_setup.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl31_setup.c
new file mode 100644
index 0000000..8544930
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl31_setup.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/arm/smmu_v3.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <nrd_plat.h>
+#include <nrd_variant.h>
+#include <rdfremont_rse_comms.h>
+
+#if (NRD_PLATFORM_VARIANT == 2)
+static const mmap_region_t rdfremontmc_dynamic_mmap[] = {
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
+#endif
+};
+
+static struct gic600_multichip_data rdfremontmc_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = NRD_CHIP_COUNT,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+#if NRD_CHIP_COUNT > 1
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#endif
+#if NRD_CHIP_COUNT > 2
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#endif
+#if NRD_CHIP_COUNT > 3
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#endif
+	},
+	.spi_ids = {
+		{PLAT_ARM_GICD_BASE, 32, 511},
+#if NRD_CHIP_COUNT > 1
+		{PLAT_ARM_GICD_BASE, 512, 991},
+#endif
+#if NRD_CHIP_COUNT > 2
+		{PLAT_ARM_GICD_BASE, 4096, 4575},
+#endif
+#if NRD_CHIP_COUNT > 3
+		{PLAT_ARM_GICD_BASE, 4576, 5055},
+#endif
+	}
+};
+
+static uintptr_t rdfremontmc_multichip_gicr_frames[] = {
+	/* Chip 0's GICR Base */
+	PLAT_ARM_GICR_BASE,
+#if NRD_CHIP_COUNT > 1
+	/* Chip 1's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
+#endif
+#if NRD_CHIP_COUNT > 2
+	/* Chip 2's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
+#endif
+#if NRD_CHIP_COUNT > 3
+	/* Chip 3's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
+#endif
+	UL(0)	/* Zero Termination */
+};
+#endif /* NRD_PLATFORM_VARIANT == 2 */
+
+void bl31_platform_setup(void)
+{
+	/*
+	 * Perform SMMUv3 GPT configuration for the GPC SMMU present in system
+	 * control block on RD-Fremont platforms. This SMMUv3 initialization is
+	 * not fatal.
+	 *
+	 * Don't perform smmuv3_security_init() for this instance of SMMUv3 as
+	 * the global aborts need not be configured to allow the components in
+	 * system control block send transations downstream to SMMUv3.
+	 */
+	if (smmuv3_init(NRD_CSS_GPC_SMMUV3_BASE) != 0) {
+		WARN("Failed initializing System SMMU.\n");
+	}
+
+#if (NRD_PLATFORM_VARIANT == 2)
+	int ret;
+	unsigned int i;
+
+	if (plat_arm_nrd_get_multi_chip_mode() == 0) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+		       NRD_CHIP_COUNT);
+		panic();
+	} else {
+		INFO("Enabling multi-chip support for RD-Fremont variant\n");
+
+		for (i = 0; i < ARRAY_SIZE(rdfremontmc_dynamic_mmap); i++) {
+			ret = mmap_add_dynamic_region(
+					rdfremontmc_dynamic_mmap[i].base_pa,
+					rdfremontmc_dynamic_mmap[i].base_va,
+					rdfremontmc_dynamic_mmap[i].size,
+					rdfremontmc_dynamic_mmap[i].attr);
+			if (ret != 0) {
+				ERROR("Failed to add entry i: %d (ret=%d)\n",
+				       i, ret);
+				panic();
+			}
+		}
+
+		plat_arm_override_gicr_frames(
+			rdfremontmc_multichip_gicr_frames);
+		gic600_multichip_init(&rdfremontmc_multichip_data);
+	}
+#endif /* NRD_PLATFORM_VARIANT == 2 */
+	nrd_bl31_common_platform_setup();
+
+	if (plat_rse_comms_init() != 0) {
+		WARN("Failed initializing AP-RSE comms.\n");
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common.c
new file mode 100644
index 0000000..31cc2a0
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/rse_comms.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <nrd_plat.h>
+#include <rdfremont_mhuv3.h>
+#include <rdfremont_rse_comms.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) &
+	       SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_nrd_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+		SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * Get a pointer to the RMM-EL3 shared buffer and return it
+ * through the pointer passed as parameter.
+ *
+ * This function returns the size of the shared buffer.
+ */
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
+{
+	*shared = (uintptr_t)RMM_SHARED_BASE;
+
+	return (size_t)RMM_SHARED_SIZE;
+}
+
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
+{
+	uint64_t checksum, num_banks, num_consoles;
+	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
+
+	assert(manifest != NULL);
+
+	/* DRAM Bank-1 and Bank-2 */
+	num_banks = 2;
+	assert(num_banks <= ARM_DRAM_NUM_BANKS);
+
+	/* Set number of consoles */
+	num_consoles = NRD_CSS_RMM_CONSOLE_COUNT;
+
+	manifest->version = RMMD_MANIFEST_VERSION;
+	manifest->padding = 0U; /* RES0 */
+	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
+
+	/*
+	 * Boot Manifest structure illustration, with two dram banks and
+	 * a single console.
+	 *
+	 * +----------------------------------------+
+	 * | offset |     field      |    comment   |
+	 * +--------+----------------+--------------+
+	 * |   0    |    version     |  0x00000003  |
+	 * +--------+----------------+--------------+
+	 * |   4    |    padding     |  0x00000000  |
+	 * +--------+----------------+--------------+
+	 * |   8    |   plat_data    |     NULL     |
+	 * +--------+----------------+--------------+
+	 * |   16   |   num_banks    |              |
+	 * +--------+----------------+              |
+	 * |   24   |     banks      |   plat_dram  |
+	 * +--------+----------------+              |
+	 * |   32   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   40   |  num_consoles  |              |
+	 * +--------+----------------+              |
+	 * |   48   |    consoles    | plat_console |
+	 * +--------+----------------+              |
+	 * |   56   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   64   |     base 0     |              |
+	 * +--------+----------------+    bank[0]   |
+	 * |   72   |     size 0     |              |
+	 * +--------+----------------+--------------+
+	 * |   80   |     base 1     |              |
+	 * +--------+----------------+    bank[1]   |
+	 * |   88   |     size 1     |              |
+	 * +--------+----------------+--------------+
+	 * |   96   |     base       |              |
+	 * +--------+----------------+              |
+	 * |   104  |   map_pages    |              |
+	 * +--------+----------------+              |
+	 * |   112  |     name       |              |
+	 * +--------+----------------+  consoles[0] |
+	 * |   120  |   clk_in_hz    |              |
+	 * +--------+----------------+              |
+	 * |   128  |   baud_rate    |              |
+	 * +--------+----------------+              |
+	 * |   136  |     flags      |              |
+	 * +--------+----------------+--------------+
+	 */
+
+	bank_ptr = (struct ns_dram_bank *)
+			(((uintptr_t)manifest) + sizeof(*manifest));
+	console_ptr = (struct console_info *)
+			((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
+
+	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) *
+		manifest->plat_console.num_consoles) +
+		(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks))
+		<= ARM_EL3_RMM_SHARED_SIZE);
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	/* Store FVP DRAM banks data in Boot Manifest */
+	bank_ptr[0].base = ARM_NS_DRAM1_BASE;
+	bank_ptr[0].size = ARM_NS_DRAM1_SIZE;
+
+	bank_ptr[1].base = ARM_DRAM2_BASE;
+	bank_ptr[1].size = ARM_DRAM2_SIZE;
+
+	/* Update checksum */
+	checksum += bank_ptr[0].base + bank_ptr[0].size + bank_ptr[1].base +
+		bank_ptr[1].size;
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
+
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	memset((void *)console_ptr, '\0',
+		sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].map_pages = 1;
+	console_ptr[0].base = NRD_CSS_RMM_CONSOLE_BASE;
+	console_ptr[0].clk_in_hz = NRD_CSS_RMM_CONSOLE_CLK_IN_HZ;
+	console_ptr[0].baud_rate = NRD_CSS_RMM_CONSOLE_BAUD;
+
+	strlcpy(console_ptr[0].name, NRD_CSS_RMM_CONSOLE_NAME,
+		sizeof(console_ptr[0].name));
+
+	/* Update checksum */
+	checksum += console_ptr[0].base + console_ptr[0].map_pages +
+		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+
+	/* Checksum must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
+	return 0;
+}
+
+int plat_rse_comms_init(void)
+{
+	uintptr_t snd_base, rcv_base;
+
+	/* Get sender and receiver frames for AP-RSE communication */
+	mhu_v3_get_secure_device_base(&snd_base, true);
+	mhu_v3_get_secure_device_base(&rcv_base, false);
+
+	VERBOSE("Initializing the rse_comms now\n");
+	/* Initialize the communication channel between AP and RSE */
+	return rse_comms_init(snd_base, rcv_base);
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common_measured_boot.c
new file mode 100644
index 0000000..e95c544
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common_measured_boot.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+
+extern struct rse_mboot_metadata rdfremont_rse_mboot_metadata[];
+
+struct rse_mboot_metadata *plat_rse_mboot_get_metadata(void)
+{
+	return rdfremont_rse_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 RSE */
+	err = rse_mboot_measure_and_record(rdfremont_rse_mboot_metadata,
+					   image_data->image_base,
+					   image_data->image_size,
+					   image_id);
+	if (err != 0) {
+		ERROR("Measure and record failed for image id %u, err (%i)\n",
+		      image_id, err);
+	}
+
+	return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return rse_mboot_set_signer_id(rdfremont_rse_mboot_metadata, pk_oid,
+				       pk_ptr, pk_len);
+}
diff --git a/plat/arm/board/rdv1/rdv1_err.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_err.c
similarity index 66%
copy from plat/arm/board/rdv1/rdv1_err.c
copy to plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_err.c
index 68f9a3e..de6cc68 100644
--- a/plat/arm/board/rdv1/rdv1_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <plat/arm/common/plat_arm.h>
 
 /*
- * rdv1 error handler
+ * rdfremont error handler
  */
 void __dead2 plat_arm_error_handler(int err)
 {
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_mhuv3.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_mhuv3.c
new file mode 100644
index 0000000..41332cc
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_mhuv3.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <nrd_css_def3.h>
+#include <nrd_plat.h>
+#include <rdfremont_mhuv3.h>
+
+void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender)
+{
+	if (sender) {
+		*base = AP_RSE_ROOT_MHU_V3_PBX;
+	} else {
+		*base = AP_RSE_ROOT_MHU_V3_MBX;
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_plat_attest_token.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_plat_attest_token.c
new file mode 100644
index 0000000..188a09f
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_plat_attest_token.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+
+#include <cca_attestation.h>
+#include <common/debug.h>
+#include <psa/error.h>
+
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+				   uintptr_t hash, size_t hash_size)
+{
+	psa_status_t ret;
+
+	ret = cca_attestation_get_plat_token(buf, len, hash, hash_size);
+	if (ret != PSA_SUCCESS) {
+		ERROR("Unable to fetch CCA attestation token\n");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_realm_attest_key.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_realm_attest_key.c
new file mode 100644
index 0000000..224c20b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_realm_attest_key.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+
+#include <cca_attestation.h>
+#include <common/debug.h>
+#include <psa/error.h>
+
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+				       unsigned int type)
+{
+	psa_status_t ret;
+
+	ret = cca_attestation_get_realm_key(buf, len, type);
+	if (ret != PSA_SUCCESS) {
+		ERROR("Unable to fetch CCA attestation key\n");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_security.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_security.c
new file mode 100644
index 0000000..a12d3e2
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_security.c
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Placeholder function to resolve build dependency */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_topology.c
similarity index 72%
copy from plat/arm/board/rdn2/rdn2_topology.c
copy to plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_topology.c
index 24acc4d..e7931d4 100644
--- a/plat/arm/board/rdn2/rdn2_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,32 +10,32 @@
 /******************************************************************************
  * The power domain tree descriptor.
  ******************************************************************************/
-const unsigned char rd_n2_pd_tree_desc[] = {
-	(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+const unsigned char rd_fremont_pd_tree_desc[] = {
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #if (PLAT_ARM_CLUSTER_COUNT > 4 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 #if (PLAT_ARM_CLUSTER_COUNT > 8 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 2))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (PLAT_ARM_CLUSTER_COUNT > 12 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 3))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 };
 
@@ -44,32 +44,32 @@
  ******************************************************************************/
 const unsigned char *plat_get_power_domain_tree_desc(void)
 {
-	return rd_n2_pd_tree_desc;
+	return rd_fremont_pd_tree_desc;
 }
 
 /*******************************************************************************
  * The array mapping platform core position (implemented by plat_my_core_pos())
  * to the SCMI power domain ID implemented by SCP.
  ******************************************************************************/
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
+#if (NRD_CHIP_COUNT > 2)
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
@@ -86,7 +86,7 @@
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
-#if (PLAT_ARM_CLUSTER_COUNT > 8)
+#if (NRD_PLATFORM_VARIANT == 0)
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_trusted_boot.c
similarity index 88%
rename from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_trusted_boot.c
index 4592b8f..6aec208 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_fw_config.dts
similarity index 86%
copy from plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
copy to plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_fw_config.dts
index d3b7fba..085a42a 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
similarity index 86%
rename from plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
index 68366c5..3cef0d1 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
index 257ef4a..78cd5a8 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h
new file mode 100644
index 0000000..5357c31
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
+#include <nrd_sdei.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(4)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+
+/* Base address of DMC-620 instances */
+#define RDN1EDGE_DMC620_BASE0		UL(0x4e000000)
+#define RDN1EDGE_DMC620_BASE1		UL(0x4e100000)
+
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
+
+/* Maximum number of address bits used per chip */
+#define NRD_ADDR_BITS_PER_CHIP	U(42)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
+/* GIC SPI range for multichip */
+#define NRD_CHIP0_SPI_MIN		U(32)
+#define NRD_CHIP0_SPI_MAX		U(991)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
similarity index 72%
rename from plat/arm/board/rdn1edge/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
index d8d1293..15fc9bb 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
@@ -1,25 +1,24 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
-
 # GIC-600 configuration
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDN1EDGE_BASE		=	plat/arm/board/rdn1edge
+RDN1EDGE_BASE		=	plat/arm/board/neoverse_rd/platform/rdn1edge
 
-PLAT_INCLUDES		+=	-I${RDN1EDGE_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${RDN1EDGE_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n1.S
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n1.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN1EDGE_BASE}/rdn1edge_err.c
 
 BL2_SOURCES		+=	${RDN1EDGE_BASE}/rdn1edge_plat.c	\
@@ -29,7 +28,7 @@
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN1EDGE_BASE}/rdn1edge_plat.c	\
 				${RDN1EDGE_BASE}/rdn1edge_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -62,17 +61,18 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 $(eval $(call CREATE_SEQ,SEQ,2))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
  $(error  "Chip count for RDN1Edge platform should be one of $(SEQ), currently \
-   set to ${CSS_SGI_CHIP_COUNT}.")
+   set to ${NRD_CHIP_COUNT}.")
 endif
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-N1-Edge should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for RD-N1-Edge should always be 0, \
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
+override SPMD_SPM_AT_SEL2		:= 0
 
 # Enable the flag since RD-N1-EDGE has a system level cache
 NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/rdn1edge/rdn1edge_err.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_err.c
similarity index 71%
rename from plat/arm/board/rdn1edge/rdn1edge_err.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_err.c
index 46d318c..273e1f4 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c
similarity index 70%
rename from plat/arm/board/rdn1edge/rdn1edge_plat.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c
index 6da8bcd..ccabe22 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,26 +8,28 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <sgi_soc_platform_def.h>
-#include <sgi_plat.h>
+
+#include <nrd_plat.h>
 
 #if defined(IMAGE_BL31)
 static const mmap_region_t rdn1edge_dynamic_mmap[] = {
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1)
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+	NRD_ROS_PERIPH_MMAP(1)
 };
 
 static struct gic600_multichip_data rdn1e1_multichip_data __init = {
 	.rt_owner_base = PLAT_ARM_GICD_BASE,
 	.rt_owner = 0,
-	.chip_count = CSS_SGI_CHIP_COUNT,
+	.chip_count = NRD_CHIP_COUNT,
 	.chip_addrs = {
 		PLAT_ARM_GICD_BASE >> 16,
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
 	},
 	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 255},
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP0_SPI_MIN,
+		NRD_CHIP0_SPI_MAX},
 		{0, 0, 0}
 	}
 };
@@ -35,23 +37,23 @@
 static uintptr_t rdn1e1_multichip_gicr_frames[] = {
 	PLAT_ARM_GICR_BASE,				/* Chip 0's GICR Base */
 	PLAT_ARM_GICR_BASE +
-		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),	/* Chip 1's GICR BASE */
+		NRD_REMOTE_CHIP_MEM_OFFSET(1),		/* Chip 1's GICR BASE */
 	UL(0)						/* Zero Termination */
 };
 #endif /* IMAGE_BL31 */
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
 				& SID_SYSTEM_ID_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
 			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
@@ -68,12 +70,12 @@
 	unsigned int i;
 	int ret;
 
-	if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
+	if (plat_arm_nrd_get_multi_chip_mode() == 0 && NRD_CHIP_COUNT > 1) {
 		ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
-				CSS_SGI_CHIP_COUNT);
+				NRD_CHIP_COUNT);
 		panic();
-	} else if (plat_arm_sgi_get_multi_chip_mode() == 1 &&
-			CSS_SGI_CHIP_COUNT > 1) {
+	} else if (plat_arm_nrd_get_multi_chip_mode() == 1 &&
+			NRD_CHIP_COUNT > 1) {
 		INFO("Enabling support for multi-chip in RD-N1-Edge\n");
 
 		for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) {
@@ -93,6 +95,6 @@
 		gic600_multichip_init(&rdn1e1_multichip_data);
 	}
 
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_security.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_security.c
similarity index 85%
rename from plat/arm/board/rdn1edge/rdn1edge_security.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_security.c
index 4943532..f3f6238 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <sgi_dmc620_tzc_regions.h>
+#include <nrd_dmc620_tzc_regions.h>
 
 uintptr_t rdn1edge_dmc_base[] = {
 	RDN1EDGE_DMC620_BASE0,
@@ -20,7 +20,7 @@
 };
 
 static const tzc_dmc620_acc_addr_data_t rdn1edge_acc_addr_data[] = {
-	CSS_SGI_DMC620_TZC_REGIONS_DEF
+	NRD_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t rdn1edge_plat_config_data = {
diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_topology.c
similarity index 86%
rename from plat/arm/board/rdn1edge/rdn1edge_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_topology.c
index 5bbea69..133eb16 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,12 +11,12 @@
  * The power domain tree descriptor.
  ******************************************************************************/
 static const unsigned char rdn1edge_pd_tree_desc[] = {
-	(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-#if (CSS_SGI_CHIP_COUNT > 1)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#if (NRD_CHIP_COUNT > 1)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 #endif
 };
 
@@ -41,7 +41,7 @@
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_trusted_boot.c
similarity index 88%
copy from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
copy to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_trusted_boot.c
index 4592b8f..84622d0 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts
similarity index 85%
rename from plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts
index d992eac..f857f72 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,12 +18,14 @@
 			id = <TB_FW_CONFIG_ID>;
 		};
 
+#if SPMC_AT_EL3
 		tos_fw-config {
 			load-address = <0x0 0x04001500>;
 			max-size = <0x1000>;
 			id = <TOS_FW_CONFIG_ID>;
 		};
 
+#endif
 		nt_fw-config {
 			load-address = <0x0 0xFEF00000>;
 			max-size = <0x0100000>;
diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_nt_fw_config.dts
similarity index 90%
rename from plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_nt_fw_config.dts
index dd70141..8e58565 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 - 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/fdts/rdn2_stmm_sel0_manifest.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
similarity index 97%
rename from plat/arm/board/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
rename to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
index 6119706..dbdc7e5 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_tb_fw_config.dts
similarity index 89%
copy from plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
copy to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_tb_fw_config.dts
index 49eda27..c370623 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h
new file mode 100644
index 0000000..f6f2b86
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#include <nrd_css_fw_def2.h>
+#include <nrd_plat_arm_def2.h>
+#include <nrd_ros_fw_def2.h>
+#include <nrd_sdei.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)					\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+/* Boot ROM */
+#define NRD_CSS_SECURE_ROM_SIZE		UL(0x00080000) /* 512KB */
+
+/* Secure SRAM */
+#define NRD_CSS_SECURE_SRAM_SIZE	UL(0x00080000) /* 512KB */
+
+/* NS SRAM */
+#define NRD_CSS_NS_SRAM_SIZE		UL(0x00080000) /* 512KB */
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000) /* 6GB */
+
+#define TZC400_OFFSET			UL(0x1000000)
+
+#if (NRD_PLATFORM_VARIANT == 1)
+#define TZC400_COUNT			U(2)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define TZC400_COUNT			U(4)
+#else
+#define TZC400_COUNT			U(8)
+#endif
+
+#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
+						(n * TZC400_OFFSET))
+
+#define TZC_NSAID_ALL_AP		U(0)
+#define TZC_NSAID_PCI			U(1)
+#define TZC_NSAID_HDLCD0		U(2)
+#define TZC_NSAID_DMA			U(5)
+#define TZC_NSAID_DMA2			U(8)
+#define TZC_NSAID_CLCD			U(7)
+#define TZC_NSAID_AP			U(9)
+#define TZC_NSAID_VIRTIO		U(15)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA2))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#if (NRD_PLATFORM_VARIANT == 2)
+#define NRD_ADDR_BITS_PER_CHIP	U(46)	/* 64TB */
+#else
+#define NRD_ADDR_BITS_PER_CHIP	U(42)	/* 4TB */
+#endif
+
+/* GIC SPI range for multichip */
+#define NRD_CHIP0_SPI_MIN		U(32)
+#define NRD_CHIP0_SPI_MAX		U(511)
+#if NRD_CHIP_COUNT > 1
+#define NRD_CHIP1_SPI_MIN		U(512)
+#define NRD_CHIP1_SPI_MAX		U(991)
+#endif
+#if NRD_CHIP_COUNT > 2
+#define NRD_CHIP2_SPI_MIN		U(4096)
+#define NRD_CHIP2_SPI_MAX		U(4575)
+#endif
+#if NRD_CHIP_COUNT > 3
+#define NRD_CHIP3_SPI_MIN		U(4576)
+#define NRD_CHIP3_SPI_MAX		U(5055)
+#endif
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h b/plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h
new file mode 100644
index 0000000..c8a6f2d
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDN2_RAS_H
+#define RDN2_RAS_H
+
+#include <nrd_ras.h>
+
+extern struct plat_nrd_ras_config ras_config;
+
+#endif /* RDN2_RAS_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
similarity index 74%
rename from plat/arm/board/rdn2/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
index 28ec5dc..c8f0899 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
@@ -1,19 +1,19 @@
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 RD_N2_VARIANTS	:= 0 1 2 3
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),\
-	$(filter $(CSS_SGI_PLATFORM_VARIANT),$(RD_N2_VARIANTS)))
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-N2 should be 0, 1, 2 or 3, currently \
-	set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),\
+	$(filter $(NRD_PLATFORM_VARIANT),$(RD_N2_VARIANTS)))
+ $(error "NRD_PLATFORM_VARIANT for RD-N2 should be 0, 1, 2 or 3, currently \
+	set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
 $(eval $(call CREATE_SEQ,SEQ,4))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
  $(error  "Chip count for RD-N2-MC should be either $(SEQ) \
- currently it is set to ${CSS_SGI_CHIP_COUNT}.")
+ currently it is set to ${NRD_CHIP_COUNT}.")
 endif
 
 # RD-N2 platform uses GIC-700 which is based on GICv4.1
@@ -21,25 +21,26 @@
 GIC_EXT_INTID		:=	1
 
 #Enable GIC Multichip Extension only for Multichip Platforms
-ifeq (${CSS_SGI_PLATFORM_VARIANT}, 2)
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 endif
 
 override CSS_SYSTEM_GRACEFUL_RESET	:= 1
 override EL3_EXCEPTION_HANDLING		:= 1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDN2_BASE		=	plat/arm/board/rdn2
+RDN2_BASE		=	plat/arm/board/neoverse_rd/platform/rdn2
 
-PLAT_INCLUDES		+=	-I${RDN2_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd2/	\
+				-I${RDN2_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S \
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S \
 				lib/cpus/aarch64/neoverse_v2.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat_v2.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat2.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN2_BASE}/rdn2_err.c
 
 BL2_SOURCES		+=	${RDN2_BASE}/rdn2_plat.c		\
@@ -50,7 +51,7 @@
 				plat/arm/common/arm_tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN2_BASE}/rdn2_plat.c		\
 				${RDN2_BASE}/rdn2_topology.c		\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -62,7 +63,7 @@
 BL2_SOURCES		+=	${RDN2_BASE}/rdn2_trusted_boot.c
 endif
 
-ifeq (${CSS_SGI_PLATFORM_VARIANT}, 2)
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
 BL31_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
 
 # Enable dynamic addition of MMAP regions in BL31
@@ -71,9 +72,9 @@
 
 ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
 BL31_SOURCES		+=	${RDN2_BASE}/rdn2_ras.c			\
-				${CSS_ENT_BASE}/ras/sgi_ras_common.c	\
-				${CSS_ENT_BASE}/ras/sgi_ras_sram.c	\
-				${CSS_ENT_BASE}/ras/sgi_ras_cpu.c
+				${NRD_COMMON_BASE}/ras/nrd_ras_common.c	\
+				${NRD_COMMON_BASE}/ras/nrd_ras_sram.c	\
+				${NRD_COMMON_BASE}/ras/nrd_ras_cpu.c
 endif
 
 # Add the FDT_SOURCES and options for Dynamic Config
@@ -93,15 +94,19 @@
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
 
+ifeq (${SPMC_AT_EL3}, 1)
 STMM_CONFIG_DTS		:=	${RDN2_BASE}/fdts/${PLAT}_stmm_sel0_manifest.dts
 FDT_SOURCES		+=	${STMM_CONFIG_DTS}
 TOS_FW_CONFIG		:=	${BUILD_PLAT}/fdts/$(notdir $(basename ${STMM_CONFIG_DTS})).dtb
 
 # Add the TOS_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TOS_FW_CONFIG},--tos-fw-config,${TOS_FW_CONFIG}))
+endif
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_FEAT_AMU		:= 1
+override ENABLE_FEAT_AMU		:= 2
+override ENABLE_FEAT_MTE2       	:= 2
+override SPMD_SPM_AT_SEL2		:= 0
 
 # Enable the flag since RD-N2 has a system level cache
 NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/rdn2/rdn2_err.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_err.c
similarity index 70%
rename from plat/arm/board/rdn2/rdn2_err.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_err.c
index 802ac21..d712645 100644
--- a/plat/arm/board/rdn2/rdn2_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c
similarity index 60%
rename from plat/arm/board/rdn2/rdn2_plat.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c
index 2a6c658..b1046d6 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,93 +9,101 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <services/el3_spmc_ffa_memory.h>
+
+#include <nrd_plat.h>
 #include <rdn2_ras.h>
-#include <sgi_soc_platform_def_v2.h>
-#include <sgi_plat.h>
 
 #if defined(IMAGE_BL31)
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 static const mmap_region_t rdn2mc_dynamic_mmap[] = {
-#if CSS_SGI_CHIP_COUNT > 1
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(2),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(3),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
 #endif
 };
 #endif
 
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 static struct gic600_multichip_data rdn2mc_multichip_data __init = {
 	.rt_owner_base = PLAT_ARM_GICD_BASE,
 	.rt_owner = 0,
-	.chip_count = CSS_SGI_CHIP_COUNT,
+	.chip_count = NRD_CHIP_COUNT,
 	.chip_addrs = {
 		PLAT_ARM_GICD_BASE >> 16,
-#if CSS_SGI_CHIP_COUNT > 1
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#if NRD_CHIP_COUNT > 1
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#if NRD_CHIP_COUNT > 2
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#if NRD_CHIP_COUNT > 3
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
 #endif
 	},
 	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 511},
-	#if CSS_SGI_CHIP_COUNT > 1
-		{PLAT_ARM_GICD_BASE, 512, 991},
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP0_SPI_MIN,
+		NRD_CHIP0_SPI_MAX},
+	#if NRD_CHIP_COUNT > 1
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP1_SPI_MIN,
+		NRD_CHIP1_SPI_MAX},
 	#endif
-	#if CSS_SGI_CHIP_COUNT > 2
-		{PLAT_ARM_GICD_BASE, 4096, 4575},
+	#if NRD_CHIP_COUNT > 2
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP2_SPI_MIN,
+		NRD_CHIP2_SPI_MAX},
 	#endif
-	#if CSS_SGI_CHIP_COUNT > 3
-		{PLAT_ARM_GICD_BASE, 4576, 5055},
+	#if NRD_CHIP_COUNT > 3
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP3_SPI_MIN,
+		NRD_CHIP3_SPI_MAX},
 	#endif
 	}
 };
 #endif
 
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 static uintptr_t rdn2mc_multichip_gicr_frames[] = {
 	/* Chip 0's GICR Base */
 	PLAT_ARM_GICR_BASE,
-#if CSS_SGI_CHIP_COUNT > 1
+#if NRD_CHIP_COUNT > 1
 	/* Chip 1's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
+#if NRD_CHIP_COUNT > 2
 	/* Chip 2's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
+#if NRD_CHIP_COUNT > 3
 	/* Chip 3's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
 #endif
 	UL(0)	/* Zero Termination */
 };
 #endif
 #endif /* IMAGE_BL31 */
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
 			    & SID_SYSTEM_ID_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
 			     SID_MULTI_CHIP_MODE_MASK) >>
@@ -105,13 +113,13 @@
 #if defined(IMAGE_BL31)
 void bl31_platform_setup(void)
 {
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 	int ret;
 	unsigned int i;
 
-	if (plat_arm_sgi_get_multi_chip_mode() == 0) {
-		ERROR("Chip Count is set to %u but multi-chip mode is not "
-			"enabled\n", CSS_SGI_CHIP_COUNT);
+	if (plat_arm_nrd_get_multi_chip_mode() == 0) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+			NRD_CHIP_COUNT);
 		panic();
 	} else {
 		INFO("Enabling multi-chip support for RD-N2 variant\n");
@@ -135,10 +143,10 @@
 	}
 #endif
 
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 
 #if ENABLE_FEAT_RAS && FFH_SUPPORT
-	sgi_ras_platform_setup(&ras_config);
+	nrd_ras_platform_setup(&ras_config);
 #endif
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn2/rdn2_ras.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_ras.c
similarity index 60%
rename from plat/arm/board/rdn2/rdn2_ras.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_ras.c
index 3aed58e..e328764 100644
--- a/plat/arm/board/rdn2/rdn2_ras.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_ras.c
@@ -1,30 +1,31 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <platform_def.h>
-#include <sgi_ras.h>
-#include <sgi_sdei.h>
 
-struct sgi_ras_ev_map plat_ras_map[] = {
+#include <nrd_ras.h>
+#include <nrd_sdei.h>
+
+struct nrd_ras_ev_map plat_ras_map[] = {
 	/* Non Secure base RAM ECC CE interrupt */
-	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_CE_INT, SGI_RAS_INTR_TYPE_SPI},
+	{NRD_SDEI_DS_EVENT_0, NRD_CSS_NS_RAM_ECC_CE_INT, NRD_RAS_INTR_TYPE_SPI},
 
 	/* Non Secure base RAM ECC UE interrupt */
-	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_UE_INT, SGI_RAS_INTR_TYPE_SPI},
+	{NRD_SDEI_DS_EVENT_0, NRD_CSS_NS_RAM_ECC_UE_INT, NRD_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}
+	{NRD_SDEI_DS_EVENT_1, PLAT_CORE_FAULT_IRQ, NRD_RAS_INTR_TYPE_PPI}
 };
 
 /* RAS error record list definition, used by the common RAS framework. */
 struct err_record_info plat_err_records[] = {
 	/* 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),
+	ERR_RECORD_MEMMAP_V1(NRD_CSS_NS_RAM_ERR_REC_BASE, 4, NULL,
+				&nrd_ras_sram_intr_handler, 0),
+	ERR_RECORD_SYSREG_V1(0, 1, NULL, &nrd_ras_cpu_intr_handler, 0),
 };
 
 /* RAS error interrupt list definition, used by the common RAS framework. */
@@ -33,10 +34,10 @@
 		.intr_number = PLAT_CORE_FAULT_IRQ,
 		.err_record = &plat_err_records[1],
 	}, {
-		.intr_number = NS_RAM_ECC_CE_INT,
+		.intr_number = NRD_CSS_NS_RAM_ECC_CE_INT,
 		.err_record = &plat_err_records[0],
 	}, {
-		.intr_number = NS_RAM_ECC_UE_INT,
+		.intr_number = NRD_CSS_NS_RAM_ECC_UE_INT,
 		.err_record = &plat_err_records[0],
 	},
 };
@@ -47,7 +48,7 @@
 REGISTER_RAS_INTERRUPTS(plat_ras_interrupts);
 
 /* Platform RAS handling config data definition */
-struct plat_sgi_ras_config ras_config = {
+struct plat_nrd_ras_config ras_config = {
 	plat_ras_map,
 	ARRAY_SIZE(plat_ras_map)
 };
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_security.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_security.c
new file mode 100644
index 0000000..7319d1a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_security.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#define RDN2_TZC_CPER_REGION				\
+	{NRD_CSS_SP_CPER_BUF_BASE, (NRD_CSS_SP_CPER_BUF_BASE +	\
+	NRD_CSS_SP_CPER_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+	PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+static const arm_tzc_regions_info_t tzc_regions[] = {
+	ARM_TZC_REGIONS_DEF,
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+	RDN2_TZC_CPER_REGION,
+#endif
+	{}
+};
+
+#if (NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1)
+static const arm_tzc_regions_info_t tzc_regions_mc[][NRD_CHIP_COUNT - 1] = {
+	{
+		/* TZC memory regions for second chip */
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(1),
+		{}
+	},
+#if NRD_CHIP_COUNT > 2
+	{
+		/* TZC memory regions for third chip */
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(2),
+		{}
+	},
+#endif
+#if NRD_CHIP_COUNT > 3
+	{
+		/* TZC memory regions for fourth chip */
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(3),
+		{}
+	},
+#endif
+};
+#endif /* NRD_PLATFORM_VARIANT && NRD_CHIP_COUNT */
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+	unsigned int i;
+
+	INFO("Configuring TrustZone Controller for Chip 0\n");
+
+	for (i = 0; i < TZC400_COUNT; i++) {
+		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+	}
+
+#if (NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1)
+	unsigned int j;
+
+	for (i = 1; i < NRD_CHIP_COUNT; i++) {
+		INFO("Configuring TrustZone Controller for Chip %u\n", i);
+
+		for (j = 0; j < TZC400_COUNT; j++) {
+			arm_tzc400_setup(NRD_REMOTE_CHIP_MEM_OFFSET(i)
+				+ TZC400_BASE(j), tzc_regions_mc[i-1]);
+		}
+	}
+#endif
+}
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_topology.c
similarity index 76%
rename from plat/arm/board/rdn2/rdn2_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_topology.c
index 24acc4d..b8b6b7a 100644
--- a/plat/arm/board/rdn2/rdn2_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,31 +11,31 @@
  * The power domain tree descriptor.
  ******************************************************************************/
 const unsigned char rd_n2_pd_tree_desc[] = {
-	(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #if (PLAT_ARM_CLUSTER_COUNT > 4 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 #if (PLAT_ARM_CLUSTER_COUNT > 8 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 2))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 #if (PLAT_ARM_CLUSTER_COUNT > 8 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 3))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 };
 
@@ -51,25 +51,25 @@
  * The array mapping platform core position (implemented by plat_my_core_pos())
  * to the SCMI power domain ID implemented by SCP.
  ******************************************************************************/
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
+#if (NRD_CHIP_COUNT > 2)
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_trusted_boot.c
similarity index 88%
copy from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
copy to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_trusted_boot.c
index 4592b8f..84622d0 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_fw_config.dts
similarity index 86%
copy from plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
copy to plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_fw_config.dts
index d3b7fba..d443443 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
+
 / {
 	dtb-registry {
 		compatible = "fconf,dyn_cfg-dtb_registry";
@@ -24,4 +25,3 @@
 		};
 	};
 };
-
diff --git a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_nt_fw_config.dts
similarity index 82%
rename from plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_nt_fw_config.dts
index 62ba2c3..fb08885 100644
--- a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_tb_fw_config.dts
similarity index 89%
copy from plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
copy to plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_tb_fw_config.dts
index 49eda27..c370623 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv1/include/platform_def.h
similarity index 64%
rename from plat/arm/board/rdv1/include/platform_def.h
rename to plat/arm/board/neoverse_rd/platform/rdv1/include/platform_def.h
index 620fa3e..cd40117 100644
--- a/plat/arm/board/rdv1/include/platform_def.h
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,19 +8,21 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
 
-#include <sgi_soc_platform_def.h>
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
 
 #define PLAT_ARM_CLUSTER_COUNT		U(16)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
 /* TZC Related Constants */
 #define PLAT_ARM_TZC_BASE		UL(0x21830000)
 #define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
@@ -47,22 +49,10 @@
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
 
 /* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
+#define NRD_ADDR_BITS_PER_CHIP	U(42)
 
 /* GIC related constants */
 #define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
 #define PLAT_ARM_GICR_BASE		UL(0x30140000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
similarity index 72%
rename from plat/arm/board/rdv1/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
index 0b059b5..fe87779 100644
--- a/plat/arm/board/rdv1/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -6,17 +6,18 @@
 # RD-V1 platform uses GIC-700 which is based on GICv4.1
 GIC_ENABLE_V4_EXTN	:=	1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDV1_BASE		=	plat/arm/board/rdv1
+RDV1_BASE		=	plat/arm/board/neoverse_rd/platform/rdv1
 
-PLAT_INCLUDES		+=	-I${RDV1_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${RDV1_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1_BASE}/rdv1_err.c
 
 BL2_SOURCES		+=	${RDV1_BASE}/rdv1_plat.c	\
@@ -27,7 +28,7 @@
 				plat/arm/common/arm_tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1_BASE}/rdv1_plat.c	\
 				${RDV1_BASE}/rdv1_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -57,11 +58,12 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_FEAT_AMU		:= 1
+override ENABLE_FEAT_AMU		:= 2
+override SPMD_SPM_AT_SEL2		:= 0
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-V1 should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for RD-V1 should always be 0, \
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
 # Enable the flag since RD-V1 has a system level cache
diff --git a/plat/arm/board/rdv1/rdv1_err.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_err.c
similarity index 70%
rename from plat/arm/board/rdv1/rdv1_err.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_err.c
index 68f9a3e..d75f525 100644
--- a/plat/arm/board/rdv1/rdv1_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_plat.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_plat.c
new file mode 100644
index 0000000..7cdc19a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_plat.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+#include <nrd_plat.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+				& SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_nrd_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+void bl31_platform_setup(void)
+{
+	nrd_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rdv1/rdv1_security.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_security.c
similarity index 82%
rename from plat/arm/board/rdv1/rdv1_security.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_security.c
index 1247db8..a936a71 100644
--- a/plat/arm/board/rdv1/rdv1_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/rdv1_topology.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_topology.c
similarity index 77%
rename from plat/arm/board/rdv1/rdv1_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_topology.c
index ab64fd8..20e4266 100644
--- a/plat/arm/board/rdv1/rdv1_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,22 +12,22 @@
  ******************************************************************************/
 const unsigned char rd_v1_pd_tree_desc[] = {
 	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 };
 
 /*******************************************************************************
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_trusted_boot.c
similarity index 88%
copy from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
copy to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_trusted_boot.c
index 4592b8f..84622d0 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_fw_config.dts
similarity index 86%
copy from plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
copy to plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_fw_config.dts
index d3b7fba..d443443 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
+
 / {
 	dtb-registry {
 		compatible = "fconf,dyn_cfg-dtb_registry";
@@ -24,4 +25,3 @@
 		};
 	};
 };
-
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
similarity index 82%
rename from plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
index 71c7db3..78fa31e 100644
--- a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
index 49eda27..c370623 100644
--- a/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv1mc/include/platform_def.h
similarity index 69%
rename from plat/arm/board/rdv1mc/include/platform_def.h
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/include/platform_def.h
index 3670904..b4c5c0a 100644
--- a/plat/arm/board/rdv1mc/include/platform_def.h
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,18 +8,21 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
-#include <sgi_soc_platform_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
 
 #define PLAT_ARM_CLUSTER_COUNT		U(4)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
 /* TZC Related Constants */
 #define PLAT_ARM_TZC_BASE		UL(0x21830000)
 #define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
@@ -47,17 +50,14 @@
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
 
 /* Remote chip address offset (4TB per chip) */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)
-
-/* Physical and virtual address space limits for MMU in AARCH64 mode */
-#define PLAT_PHY_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
+#define NRD_ADDR_BITS_PER_CHIP	U(42)
 
 /* GIC related constants */
 #define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
 #define PLAT_ARM_GICR_BASE		UL(0x30140000)
 
+/* GIC SPI range for multichip */
+#define NRD_CHIP0_SPI_MIN		U(32)
+#define NRD_CHIP0_SPI_MAX		U(991)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdv1mc/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
similarity index 72%
rename from plat/arm/board/rdv1mc/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
index 176e0ef..a0a1204 100644
--- a/plat/arm/board/rdv1mc/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,17 +7,18 @@
 GIC_ENABLE_V4_EXTN		:=	1
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDV1MC_BASE	=	plat/arm/board/rdv1mc
+RDV1MC_BASE	=	plat/arm/board/neoverse_rd/platform/rdv1mc
 
-PLAT_INCLUDES		+=	-I${RDV1MC_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${RDV1MC_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1MC_BASE}/rdv1mc_err.c
 
 BL2_SOURCES		+=	${RDV1MC_BASE}/rdv1mc_plat.c	\
@@ -28,7 +29,7 @@
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1MC_BASE}/rdv1mc_plat.c	\
 				${RDV1MC_BASE}/rdv1mc_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -56,9 +57,9 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 $(eval $(call CREATE_SEQ,SEQ,4))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
  $(error  "Chip count for RD-V1-MC should be either $(SEQ) \
- currently it is set to ${CSS_SGI_CHIP_COUNT}.")
+ currently it is set to ${NRD_CHIP_COUNT}.")
 endif
 
 FDT_SOURCES		+=	${RDV1MC_BASE}/fdts/${PLAT}_nt_fw_config.dts
@@ -68,11 +69,12 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_FEAT_AMU		:= 1
+override ENABLE_FEAT_AMU		:= 2
+override SPMD_SPM_AT_SEL2		:= 0
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-V1-MC should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for RD-V1-MC should always be 0, \
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
 # Enable the flag since RD-V1-MC has a system level cache
diff --git a/plat/arm/board/rdv1mc/rdv1mc_err.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_err.c
similarity index 71%
rename from plat/arm/board/rdv1mc/rdv1mc_err.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_err.c
index 755a503..b855edd 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c
new file mode 100644
index 0000000..5713cb9
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <nrd_plat.h>
+
+#if defined(IMAGE_BL31)
+static const mmap_region_t rdv1mc_dynamic_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+	NRD_ROS_PERIPH_MMAP(1),
+#if (NRD_CHIP_COUNT > 2)
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
+	NRD_ROS_PERIPH_MMAP(2),
+#endif
+#if (NRD_CHIP_COUNT > 3)
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
+	NRD_ROS_PERIPH_MMAP(3)
+#endif
+};
+
+static struct gic600_multichip_data rdv1mc_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = NRD_CHIP_COUNT,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#if (NRD_CHIP_COUNT > 2)
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#endif
+#if (NRD_CHIP_COUNT > 3)
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#endif
+	},
+	.spi_ids = {
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP0_SPI_MIN,
+		NRD_CHIP0_SPI_MAX},
+		{0, 0, 0},
+#if (NRD_CHIP_COUNT > 2)
+		{0, 0, 0},
+#endif
+#if (NRD_CHIP_COUNT > 3)
+		{0, 0, 0},
+#endif
+	}
+};
+
+static uintptr_t rdv1mc_multichip_gicr_frames[] = {
+	/* Chip 0's GICR Base */
+	PLAT_ARM_GICR_BASE,
+	/* Chip 1's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
+#if (NRD_CHIP_COUNT > 2)
+	/* Chip 2's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
+#endif
+#if (NRD_CHIP_COUNT > 3)
+	/* Chip 3's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
+#endif
+	UL(0)	/* Zero Termination */
+};
+#endif /* IMAGE_BL31 */
+
+unsigned int plat_arm_nrd_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+				& SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_nrd_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because
+ * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
+ * for other stages.
+ */
+#if defined(IMAGE_BL31)
+void bl31_platform_setup(void)
+{
+	int ret;
+	unsigned int i;
+
+	if ((plat_arm_nrd_get_multi_chip_mode() == 0) &&
+			(NRD_CHIP_COUNT > 1)) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+			NRD_CHIP_COUNT);
+		panic();
+	} else if ((plat_arm_nrd_get_multi_chip_mode() == 1) &&
+			(NRD_CHIP_COUNT > 1)) {
+		INFO("Enabling support for multi-chip in RD-V1-MC\n");
+
+		for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) {
+			ret = mmap_add_dynamic_region(
+					rdv1mc_dynamic_mmap[i].base_pa,
+					rdv1mc_dynamic_mmap[i].base_va,
+					rdv1mc_dynamic_mmap[i].size,
+					rdv1mc_dynamic_mmap[i].attr);
+			if (ret != 0) {
+				ERROR("Failed to add dynamic mmap entry "
+						"(ret=%d)\n", ret);
+				panic();
+			}
+		}
+
+		plat_arm_override_gicr_frames(
+			rdv1mc_multichip_gicr_frames);
+		gic600_multichip_init(&rdv1mc_multichip_data);
+	}
+
+	nrd_bl31_common_platform_setup();
+}
+#endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdv1mc/rdv1mc_security.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_security.c
similarity index 63%
rename from plat/arm/board/rdv1mc/rdv1mc_security.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_security.c
index adc0bf8..1e59831 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,29 +14,29 @@
 	{}
 };
 
-#if CSS_SGI_CHIP_COUNT > 1
-static const arm_tzc_regions_info_t tzc_regions_mc[][CSS_SGI_CHIP_COUNT - 1] = {
+#if NRD_CHIP_COUNT > 1
+static const arm_tzc_regions_info_t tzc_regions_mc[][NRD_CHIP_COUNT - 1] = {
 	{
 		/* TZC memory regions for second chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(1),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(1),
 		{}
 	},
-#if CSS_SGI_CHIP_COUNT > 2
+#if NRD_CHIP_COUNT > 2
 	{
 		/* TZC memory regions for third chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(2),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(2),
 		{}
 	},
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
+#if NRD_CHIP_COUNT > 3
 	{
 		/* TZC memory regions for fourth chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(3),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(3),
 		{}
 	},
 #endif
 };
-#endif /* CSS_SGI_CHIP_COUNT */
+#endif /* NRD_CHIP_COUNT */
 
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
@@ -49,14 +49,14 @@
 		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
 	}
 
-#if CSS_SGI_CHIP_COUNT > 1
+#if NRD_CHIP_COUNT > 1
 	unsigned int j;
 
-	for (i = 1; i < CSS_SGI_CHIP_COUNT; i++) {
+	for (i = 1; i < NRD_CHIP_COUNT; i++) {
 		INFO("Configuring TrustZone Controller for Chip %u\n", i);
 
 		for (j = 0; j < TZC400_COUNT; j++) {
-			arm_tzc400_setup(CSS_SGI_REMOTE_CHIP_MEM_OFFSET(i)
+			arm_tzc400_setup(NRD_REMOTE_CHIP_MEM_OFFSET(i)
 				+ TZC400_BASE(j), tzc_regions_mc[i-1]);
 		}
 	}
diff --git a/plat/arm/board/rdv1mc/rdv1mc_topology.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_topology.c
similarity index 69%
rename from plat/arm/board/rdv1mc/rdv1mc_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_topology.c
index 4486e5c..52514ca 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,34 +7,35 @@
 #include <common/debug.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/css/common/css_pm.h>
-#include <sgi_variant.h>
+
+#include <nrd_variant.h>
 
 /******************************************************************************
  * The power domain tree descriptor.
  ******************************************************************************/
 const unsigned char rd_v1_mc_pd_tree_desc_multi_chip[] = {
-	((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT)),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-#if (CSS_SGI_CHIP_COUNT > 1)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	((PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT)),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#if (NRD_CHIP_COUNT > 1)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (NRD_CHIP_COUNT > 2)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+#if (NRD_CHIP_COUNT > 3)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 #endif
 };
 
@@ -43,7 +44,7 @@
  ******************************************************************************/
 const unsigned char *plat_get_power_domain_tree_desc(void)
 {
-	if (plat_arm_sgi_get_multi_chip_mode() == 1)
+	if (plat_arm_nrd_get_multi_chip_mode() == 1)
 		return rd_v1_mc_pd_tree_desc_multi_chip;
 	panic();
 }
@@ -57,19 +58,19 @@
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
+#if (NRD_CHIP_COUNT > 2)
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_trusted_boot.c
similarity index 88%
copy from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
copy to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_trusted_boot.c
index 4592b8f..84622d0 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_fw_config.dts
similarity index 86%
rename from plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_fw_config.dts
index d3b7fba..fe62b6d 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
+
 / {
 	dtb-registry {
 		compatible = "fconf,dyn_cfg-dtb_registry";
@@ -24,4 +25,3 @@
 		};
 	};
 };
-
diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_nt_fw_config.dts
similarity index 86%
rename from plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_nt_fw_config.dts
index 260247a..0573488 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_tb_fw_config.dts
index 49eda27..c370623 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h
new file mode 100644
index 0000000..0797017
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
+#include <nrd_sdei.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(4)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x45000000)
+
+/* Base address of DMC-620 instances */
+#define SGI575_DMC620_BASE0		UL(0x4e000000)
+#define SGI575_DMC620_BASE1		UL(0x4e100000)
+
+/* Maximum number of address bits used per chip */
+#define NRD_ADDR_BITS_PER_CHIP	U(36)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
similarity index 69%
rename from plat/arm/board/sgi575/platform.mk
rename to plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
index 2f2bf73..37306be 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
@@ -1,22 +1,21 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-include plat/arm/css/sgi/sgi-common.mk
+SGI575_BASE		=	plat/arm/board/neoverse_rd/platform/sgi575
 
-SGI575_BASE		=	plat/arm/board/sgi575
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${SGI575_BASE}/include/
 
-PLAT_INCLUDES		+=	-I${SGI575_BASE}/include/
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a75.S
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a75.S
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
-
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${SGI575_BASE}/sgi575_err.c
 
 BL2_SOURCES		+=	${SGI575_BASE}/sgi575_plat.c		\
@@ -26,7 +25,7 @@
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${SGI575_BASE}/sgi575_plat.c		\
 				${SGI575_BASE}/sgi575_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -56,12 +55,14 @@
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
-ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ifneq ($(NRD_CHIP_COUNT),1)
  $(error  "Chip count for SGI575 should be 1, currently set to \
-   ${CSS_SGI_CHIP_COUNT}.")
+   ${NRD_CHIP_COUNT}.")
 endif
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for SGI575 should always be 0,\
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for SGI575 should always be 0,\
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
+
+override SPMD_SPM_AT_SEL2		:= 0
diff --git a/plat/arm/board/sgi575/sgi575_err.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_err.c
similarity index 71%
rename from plat/arm/board/sgi575/sgi575_err.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_err.c
index 21bfcb7..7e656ab 100644
--- a/plat/arm/board/sgi575/sgi575_err.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_plat.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_plat.c
new file mode 100644
index 0000000..8b74616
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_plat.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+#include <nrd_plat.h>
+#include <nrd_variant.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
+{
+	return mmio_read_32(SSC_VERSION) & SSC_VERSION_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_nrd_get_config_id(void)
+{
+	return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
+			& SSC_VERSION_CONFIG_MASK;
+}
+
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
+{
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	nrd_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/sgi575/sgi575_security.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_security.c
similarity index 84%
rename from plat/arm/board/sgi575/sgi575_security.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_security.c
index 17d07d1..8b8a382 100644
--- a/plat/arm/board/sgi575/sgi575_security.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <sgi_dmc620_tzc_regions.h>
+#include <nrd_dmc620_tzc_regions.h>
 
 uintptr_t sgi575_dmc_base[] = {
 	SGI575_DMC620_BASE0,
@@ -20,7 +20,7 @@
 };
 
 static const tzc_dmc620_acc_addr_data_t sgi575_acc_addr_data[] = {
-	CSS_SGI_DMC620_TZC_REGIONS_DEF
+	NRD_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t sgi575_plat_config_data = {
diff --git a/plat/arm/board/sgi575/sgi575_topology.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_topology.c
similarity index 89%
rename from plat/arm/board/sgi575/sgi575_topology.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_topology.c
index f7c3856..15ffc65 100644
--- a/plat/arm/board/sgi575/sgi575_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,8 +11,8 @@
  ******************************************************************************/
 static const unsigned char sgi575_pd_tree_desc[] = {
 	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 };
 
 /*******************************************************************************
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_trusted_boot.c
similarity index 88%
copy from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
copy to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_trusted_boot.c
index 4592b8f..84622d0 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
deleted file mode 100644
index 69fb0d4..0000000
--- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/tbbr/tbbr_img_def.h>
-
-/dts-v1/;
-
-/ {
-	dtb-registry {
-		compatible = "fconf,dyn_cfg-dtb_registry";
-
-		tb_fw-config {
-			load-address = <0x0 0x4001300>;
-			max-size = <0x200>;
-			id = <TB_FW_CONFIG_ID>;
-		};
-
-		nt_fw-config {
-			load-address = <0x0 0xFEF00000>;
-			max-size = <0x0100000>;
-			id = <NT_FW_CONFIG_ID>;
-		};
-	};
-};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
deleted file mode 100644
index 0af821e..0000000
--- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-/ {
-	/* compatible string */
-	compatible = "arm,rd-e1edge";
-
-	/*
-	 * Place holder for system-id node with default values. The
-	 * value of platform-id and config-id will be set to the
-	 * correct values during the BL2 stage of boot.
-	 */
-	system-id {
-		platform-id = <0x0>;
-		config-id = <0x0>;
-		multi-chip-mode = <0x0>;
-	};
-
-};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
deleted file mode 100644
index dba91e5..0000000
--- a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
-	tb_fw-config {
-		compatible = "arm,tb_fw";
-
-		/* Disable authentication for development */
-		disable_auth = <0x0>;
-
-		/*
-		 * The following two entries are placeholders for Mbed TLS
-		 * heap information. The default values don't matter since
-		 * they will be overwritten by BL1.
-		 * In case of having shared Mbed TLS heap between BL1 and BL2,
-		 * BL1 will populate these two properties with the respective
-		 * info about the shared heap. This info will be available for
-		 * BL2 in order to locate and re-use the heap.
-		 */
-		mbedtls_heap_addr = <0x0 0x0>;
-		mbedtls_heap_size = <0x0>;
-	};
-};
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
deleted file mode 100644
index 69bfd7b..0000000
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def.h>
-
-#define PLAT_ARM_CLUSTER_COUNT		U(2)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(8)
-#define CSS_SGI_MAX_PE_PER_CPU		U(2)
-
-#define PLAT_CSS_MHU_BASE		UL(0x45400000)
-
-/* Base address of DMC-620 instances */
-#define RDE1EDGE_DMC620_BASE0		UL(0x4e000000)
-#define RDE1EDGE_DMC620_BASE1		UL(0x4e100000)
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
-
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL3
-
-/* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(36)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
deleted file mode 100644
index 4a9a467..0000000
--- a/plat/arm/board/rde1edge/platform.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning Platform ${PLAT} is deprecated. \
-  Some of the features might not work as expected)
-
-include plat/arm/css/sgi/sgi-common.mk
-
-RDE1EDGE_BASE		=	plat/arm/board/rde1edge
-
-PLAT_INCLUDES		+=	-I${RDE1EDGE_BASE}/include/
-
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_e1.S
-
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
-
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
-				${RDE1EDGE_BASE}/rde1edge_err.c
-
-BL2_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_plat.c	\
-				${RDE1EDGE_BASE}/rde1edge_security.c	\
-				${RDE1EDGE_BASE}/rde1edge_err.c		\
-				drivers/arm/tzc/tzc_dmc620.c		\
-				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
-
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
-				${RDE1EDGE_BASE}/rde1edge_plat.c	\
-				${RDE1EDGE_BASE}/rde1edge_topology.c	\
-				drivers/cfi/v2m/v2m_flash.c		\
-				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
-
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
-BL2_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
-endif
-
-# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES		+=	${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts	\
-				${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
-FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
-TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
-
-# Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
-
-FDT_SOURCES		+=	${RDE1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts
-NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
-
-# Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
-
-ifneq ($(CSS_SGI_CHIP_COUNT),1)
- $(error  "Chip count for RDE1Edge should be 1, currently set to \
-   ${CSS_SGI_CHIP_COUNT}.")
-endif
-
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-E1-Edge should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
-endif
-
-override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rde1edge/rde1edge_err.c b/plat/arm/board/rde1edge/rde1edge_err.c
deleted file mode 100644
index c72c18c..0000000
--- a/plat/arm/board/rde1edge/rde1edge_err.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * rde1edge error handler
- */
-void __dead2 plat_arm_error_handler(int err)
-{
-	while (true) {
-		wfi();
-	}
-}
diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c
deleted file mode 100644
index 44d818a..0000000
--- a/plat/arm/board/rde1edge/rde1edge_plat.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/common/platform.h>
-#include <sgi_plat.h>
-
-unsigned int plat_arm_sgi_get_platform_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
-				& SID_SYSTEM_ID_PART_NUM_MASK;
-}
-
-unsigned int plat_arm_sgi_get_config_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
-}
-
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
-{
-	return 0;
-}
-
-void bl31_platform_setup(void)
-{
-	sgi_bl31_common_platform_setup();
-}
diff --git a/plat/arm/board/rde1edge/rde1edge_security.c b/plat/arm/board/rde1edge/rde1edge_security.c
deleted file mode 100644
index 35f81d1..0000000
--- a/plat/arm/board/rde1edge/rde1edge_security.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <sgi_dmc620_tzc_regions.h>
-
-uintptr_t rde1edge_dmc_base[] = {
-	RDE1EDGE_DMC620_BASE0,
-	RDE1EDGE_DMC620_BASE1
-};
-
-static const tzc_dmc620_driver_data_t rde1edge_plat_driver_data = {
-	.dmc_base = rde1edge_dmc_base,
-	.dmc_count = ARRAY_SIZE(rde1edge_dmc_base)
-};
-
-static const tzc_dmc620_acc_addr_data_t rde1edge_acc_addr_data[] = {
-	CSS_SGI_DMC620_TZC_REGIONS_DEF
-};
-
-static const tzc_dmc620_config_data_t rde1edge_plat_config_data = {
-	.plat_drv_data = &rde1edge_plat_driver_data,
-	.plat_acc_addr_data = rde1edge_acc_addr_data,
-	.acc_addr_count = ARRAY_SIZE(rde1edge_acc_addr_data)
-};
-
-/* Initialize the secure environment */
-void plat_arm_security_setup(void)
-{
-	arm_tzc_dmc620_setup(&rde1edge_plat_config_data);
-}
diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c
deleted file mode 100644
index 91cc37e..0000000
--- a/plat/arm/board/rde1edge/rde1edge_topology.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/******************************************************************************
- * The power domain tree descriptor. RD-E1-Edge platform consists of two
- * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with
- * two threads per CPU.
- ******************************************************************************/
-static const unsigned char rde1edge_pd_tree_desc[] = {
-	CSS_SGI_CHIP_COUNT,
-	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU
-};
-
-/******************************************************************************
- * This function returns the topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return rde1edge_pd_tree_desc;
-}
-
-/*******************************************************************************
- * The array mapping platform core position (implemented by plat_my_core_pos())
- * to the SCMI power domain ID implemented by SCP.
- ******************************************************************************/
-const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
-	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
-};
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
deleted file mode 100644
index de01902..0000000
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def.h>
-
-#define PLAT_ARM_CLUSTER_COUNT		U(2)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_CSS_MHU_BASE		UL(0x45400000)
-
-/* Base address of DMC-620 instances */
-#define RDN1EDGE_DMC620_BASE0		UL(0x4e000000)
-#define RDN1EDGE_DMC620_BASE1		UL(0x4e100000)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
-/* Virtual address used by dynamic mem_protect for chunk_base */
-#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
-
-/* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
deleted file mode 100644
index 2391b72..0000000
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def_v2.h>
-
-#if (CSS_SGI_PLATFORM_VARIANT == 1)
-#define PLAT_ARM_CLUSTER_COUNT		U(8)
-#elif (CSS_SGI_PLATFORM_VARIANT == 2)
-#define PLAT_ARM_CLUSTER_COUNT		U(4)
-#else
-#define PLAT_ARM_CLUSTER_COUNT		U(16)
-#endif
-
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_CSS_MHU_BASE		UL(0x2A920000)
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
-
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
-/* TZC Related Constants */
-#define PLAT_ARM_TZC_BASE		UL(0x10720000)
-#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
-
-#define TZC400_OFFSET			UL(0x1000000)
-
-#if (CSS_SGI_PLATFORM_VARIANT == 1)
-#define TZC400_COUNT			U(2)
-#elif (CSS_SGI_PLATFORM_VARIANT == 2)
-#define TZC400_COUNT			U(4)
-#else
-#define TZC400_COUNT			U(8)
-#endif
-
-#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
-						(n * TZC400_OFFSET))
-
-#define TZC_NSAID_ALL_AP		U(0)
-#define TZC_NSAID_PCI			U(1)
-#define TZC_NSAID_HDLCD0		U(2)
-#define TZC_NSAID_DMA			U(5)
-#define TZC_NSAID_DMA2			U(8)
-#define TZC_NSAID_CLCD			U(7)
-#define TZC_NSAID_AP			U(9)
-#define TZC_NSAID_VIRTIO		U(15)
-
-#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA))    | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA2))   | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(46)	/* 64TB */
-#else
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)	/* 4TB */
-#endif
-
-#define PLAT_PHY_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-
-/* Virtual address used by dynamic mem_protect for chunk_base */
-#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
-
-#if (CSS_SGI_PLATFORM_VARIANT == 1)
-#define PLAT_ARM_GICR_BASE		UL(0x30100000)
-#elif (CSS_SGI_PLATFORM_VARIANT == 3)
-#define PLAT_ARM_GICR_BASE		UL(0x30300000)
-#else
-#define PLAT_ARM_GICR_BASE		UL(0x301C0000)
-#endif
-
-/* Interrupt priority level for shutdown/reboot */
-#define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
-#define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
-
-/*
- * Number of Secure Partitions supported.
- * SPMC at EL3, uses this count to configure the maximum number of supported
- * secure partitions.
- */
-#define SECURE_PARTITION_COUNT          1
-
-/*
- * Number of NWd Partitions supported.
- * SPMC at EL3, uses this count to configure the maximum number of supported
- * nwld partitions.
- */
-#define NS_PARTITION_COUNT              1
-
-/*
- * Number of Logical Partitions supported.
- * SPMC at EL3, uses this count to configure the maximum number of supported
- * logical partitions.
- */
-#define MAX_EL3_LP_DESCS_COUNT		1
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/include/rdn2_ras.h b/plat/arm/board/rdn2/include/rdn2_ras.h
deleted file mode 100644
index 1d9af60..0000000
--- a/plat/arm/board/rdn2/include/rdn2_ras.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RDN2_RAS_H
-#define RDN2_RAS_H
-
-#include <sgi_ras.h>
-
-extern struct plat_sgi_ras_config ras_config;
-
-#endif /* RDN2_RAS_H */
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
deleted file mode 100644
index 7cd4a1c..0000000
--- a/plat/arm/board/rdn2/rdn2_security.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-#include <platform_def.h>
-
-#define RDN2_TZC_CPER_REGION					\
-	{CSS_SGI_SP_CPER_BUF_BASE, (CSS_SGI_SP_CPER_BUF_BASE +	\
-	CSS_SGI_SP_CPER_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
-	PLAT_ARM_TZC_NS_DEV_ACCESS}
-
-static const arm_tzc_regions_info_t tzc_regions[] = {
-	ARM_TZC_REGIONS_DEF,
-#if ENABLE_FEAT_RAS && FFH_SUPPORT
-	RDN2_TZC_CPER_REGION,
-#endif
-	{}
-};
-
-#if (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1)
-static const arm_tzc_regions_info_t tzc_regions_mc[][CSS_SGI_CHIP_COUNT - 1] = {
-	{
-		/* TZC memory regions for second chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(1),
-		{}
-	},
-#if CSS_SGI_CHIP_COUNT > 2
-	{
-		/* TZC memory regions for third chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(2),
-		{}
-	},
-#endif
-#if CSS_SGI_CHIP_COUNT > 3
-	{
-		/* TZC memory regions for fourth chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(3),
-		{}
-	},
-#endif
-};
-#endif /* CSS_SGI_PLATFORM_VARIANT && CSS_SGI_CHIP_COUNT */
-
-/* Initialize the secure environment */
-void plat_arm_security_setup(void)
-{
-	unsigned int i;
-
-	INFO("Configuring TrustZone Controller for Chip 0\n");
-
-	for (i = 0; i < TZC400_COUNT; i++) {
-		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
-	}
-
-#if (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1)
-	unsigned int j;
-
-	for (i = 1; i < CSS_SGI_CHIP_COUNT; i++) {
-		INFO("Configuring TrustZone Controller for Chip %u\n", i);
-
-		for (j = 0; j < TZC400_COUNT; j++) {
-			arm_tzc400_setup(CSS_SGI_REMOTE_CHIP_MEM_OFFSET(i)
-				+ TZC400_BASE(j), tzc_regions_mc[i-1]);
-		}
-	}
-#endif
-}
diff --git a/plat/arm/board/rdn2/rdn2_trusted_boot.c b/plat/arm/board/rdn2/rdn2_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/rdn2/rdn2_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts
deleted file mode 100644
index 49eda27..0000000
--- a/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
-	tb_fw-config {
-		compatible = "arm,tb_fw";
-
-		/* Disable authentication for development */
-		disable_auth = <0x0>;
-
-		/*
-		 * The following two entries are placeholders for Mbed TLS
-		 * heap information. The default values don't matter since
-		 * they will be overwritten by BL1.
-		 * In case of having shared Mbed TLS heap between BL1 and BL2,
-		 * BL1 will populate these two properties with the respective
-		 * info about the shared heap. This info will be available for
-		 * BL2 in order to locate and re-use the heap.
-		 */
-		mbedtls_heap_addr = <0x0 0x0>;
-		mbedtls_heap_size = <0x0>;
-	};
-};
diff --git a/plat/arm/board/rdv1/rdv1_plat.c b/plat/arm/board/rdv1/rdv1_plat.c
deleted file mode 100644
index ab5251e..0000000
--- a/plat/arm/board/rdv1/rdv1_plat.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/common/platform.h>
-#include <sgi_plat.h>
-
-unsigned int plat_arm_sgi_get_platform_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
-				& SID_SYSTEM_ID_PART_NUM_MASK;
-}
-
-unsigned int plat_arm_sgi_get_config_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
-}
-
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
-{
-	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
-			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
-}
-
-void bl31_platform_setup(void)
-{
-	sgi_bl31_common_platform_setup();
-}
diff --git a/plat/arm/board/rdv1/rdv1_trusted_boot.c b/plat/arm/board/rdv1/rdv1_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/rdv1/rdv1_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts
deleted file mode 100644
index 9c9cefe..0000000
--- a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/tbbr/tbbr_img_def.h>
-
-/dts-v1/;
-
-/ {
-	dtb-registry {
-		compatible = "fconf,dyn_cfg-dtb_registry";
-
-		tb_fw-config {
-			load-address = <0x0 0x4001300>;
-			max-size = <0x200>;
-			id = <TB_FW_CONFIG_ID>;
-		};
-
-		nt_fw-config {
-			load-address = <0x0 0xFEF00000>;
-			max-size = <0x0100000>;
-			id = <NT_FW_CONFIG_ID>;
-		};
-	};
-};
diff --git a/plat/arm/board/rdv1mc/rdv1mc_plat.c b/plat/arm/board/rdv1mc/rdv1mc_plat.c
deleted file mode 100644
index e4469dc..0000000
--- a/plat/arm/board/rdv1mc/rdv1mc_plat.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <drivers/arm/gic600_multichip.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
-#include <sgi_soc_platform_def.h>
-#include <sgi_plat.h>
-
-#if defined(IMAGE_BL31)
-static const mmap_region_t rdv1mc_dynamic_mmap[] = {
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1),
-#if (CSS_SGI_CHIP_COUNT > 2)
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(2),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2),
-#endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(3),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3)
-#endif
-};
-
-static struct gic600_multichip_data rdv1mc_multichip_data __init = {
-	.rt_owner_base = PLAT_ARM_GICD_BASE,
-	.rt_owner = 0,
-	.chip_count = CSS_SGI_CHIP_COUNT,
-	.chip_addrs = {
-		PLAT_ARM_GICD_BASE >> 16,
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
-#if (CSS_SGI_CHIP_COUNT > 2)
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
-#endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
-#endif
-	},
-	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 255},
-		{0, 0, 0},
-#if (CSS_SGI_CHIP_COUNT > 2)
-		{0, 0, 0},
-#endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-		{0, 0, 0},
-#endif
-	}
-};
-
-static uintptr_t rdv1mc_multichip_gicr_frames[] = {
-	/* Chip 0's GICR Base */
-	PLAT_ARM_GICR_BASE,
-	/* Chip 1's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
-#if (CSS_SGI_CHIP_COUNT > 2)
-	/* Chip 2's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
-#endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-	/* Chip 3's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
-#endif
-	UL(0)	/* Zero Termination */
-};
-#endif /* IMAGE_BL31 */
-
-unsigned int plat_arm_sgi_get_platform_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
-				& SID_SYSTEM_ID_PART_NUM_MASK;
-}
-
-unsigned int plat_arm_sgi_get_config_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
-}
-
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
-{
-	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
-			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
-}
-
-/*
- * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because
- * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
- * for other stages.
- */
-#if defined(IMAGE_BL31)
-void bl31_platform_setup(void)
-{
-	int ret;
-	unsigned int i;
-
-	if ((plat_arm_sgi_get_multi_chip_mode() == 0) &&
-			(CSS_SGI_CHIP_COUNT > 1)) {
-		ERROR("Chip Count is set to %u but multi-chip mode is not "
-			"enabled\n", CSS_SGI_CHIP_COUNT);
-		panic();
-	} else if ((plat_arm_sgi_get_multi_chip_mode() == 1) &&
-			(CSS_SGI_CHIP_COUNT > 1)) {
-		INFO("Enabling support for multi-chip in RD-V1-MC\n");
-
-		for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) {
-			ret = mmap_add_dynamic_region(
-					rdv1mc_dynamic_mmap[i].base_pa,
-					rdv1mc_dynamic_mmap[i].base_va,
-					rdv1mc_dynamic_mmap[i].size,
-					rdv1mc_dynamic_mmap[i].attr);
-			if (ret != 0) {
-				ERROR("Failed to add dynamic mmap entry "
-						"(ret=%d)\n", ret);
-				panic();
-			}
-		}
-
-		plat_arm_override_gicr_frames(
-			rdv1mc_multichip_gicr_frames);
-		gic600_multichip_init(&rdv1mc_multichip_data);
-	}
-
-	sgi_bl31_common_platform_setup();
-}
-#endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c b/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
deleted file mode 100644
index 84fc1ad..0000000
--- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/tbbr/tbbr_img_def.h>
-
-/dts-v1/;
-
-/ {
-	dtb-registry {
-		compatible = "fconf,dyn_cfg-dtb_registry";
-
-		tb_fw-config {
-			load-address = <0x0 0x4001300>;
-			max-size = <0x200>;
-			id = <TB_FW_CONFIG_ID>;
-		};
-
-		nt_fw-config {
-			load-address = <0x0 0xFEF00000>;
-			max-size = <0x0100000>;
-			id = <NT_FW_CONFIG_ID>;
-		};
-	};
-};
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
deleted file mode 100644
index 82a38c5..0000000
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def.h>
-
-#define PLAT_ARM_CLUSTER_COUNT		U(2)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_CSS_MHU_BASE		UL(0x45000000)
-
-/* Base address of DMC-620 instances */
-#define SGI575_DMC620_BASE0		UL(0x4e000000)
-#define SGI575_DMC620_BASE1		UL(0x4e100000)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
-/* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(36)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c
deleted file mode 100644
index dc294e6..0000000
--- a/plat/arm/board/sgi575/sgi575_plat.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/common/platform.h>
-#include <sgi_plat.h>
-#include <sgi_variant.h>
-
-unsigned int plat_arm_sgi_get_platform_id(void)
-{
-	return mmio_read_32(SSC_VERSION) & SSC_VERSION_PART_NUM_MASK;
-}
-
-unsigned int plat_arm_sgi_get_config_id(void)
-{
-	return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
-			& SSC_VERSION_CONFIG_MASK;
-}
-
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
-{
-	return 0;
-}
-
-void bl31_platform_setup(void)
-{
-	sgi_bl31_common_platform_setup();
-}
diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/sgi575/sgi575_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/tc/fdts/dice_prot_env.dtsi b/plat/arm/board/tc/fdts/dice_prot_env.dtsi
new file mode 100644
index 0000000..118f995
--- /dev/null
+++ b/plat/arm/board/tc/fdts/dice_prot_env.dtsi
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* DICE Protection Environment Client Config */
+dice_protection_environment: context_handle {
+	compatible = "arm,dpe_ctx_handle";
+	dpe_ctx_handle = <0x0>;
+};
diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts
index 982da5b..de446ea 100644
--- a/plat/arm/board/tc/fdts/tc_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_fw_config.dts
@@ -27,8 +27,13 @@
 
 		hw-config {
 			load-address = <0x0 PLAT_HW_CONFIG_DTB_BASE>;
-			max-size = <PLAT_HW_CONFIG_DTB_SIZE>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
+		nt_fw-config {
+			load-address = <0x0 (PLAT_HW_CONFIG_DTB_BASE + PLAT_ARM_HW_CONFIG_SIZE)>;
+			max-size = <0x1000>;
+			id = <NT_FW_CONFIG_ID>;
+		};
 	};
 };
diff --git a/plat/arm/board/tc/fdts/tc_nt_fw_config.dts b/plat/arm/board/tc/fdts/tc_nt_fw_config.dts
new file mode 100644
index 0000000..bb3086d
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_nt_fw_config.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+#if DICE_PROTECTION_ENVIRONMENT
+	#include "dice_prot_env.dtsi"
+#endif
+};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
index 3bc0cbb..a6b63a1 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
@@ -107,4 +107,14 @@
 		      <HI(PLAT_ARM_DRAM2_BASE) LO(PLAT_ARM_DRAM2_BASE)
 		       HI(TC_NS_DRAM2_SIZE) LO(TC_NS_DRAM2_SIZE)>;
 	};
+
+	memory@2 {
+		device_type = "device-memory";
+		reg = <0x0 0x25000000 0x0 0x10000>; /* For cactus tertiary dummy device. */
+	};
+
+	s_uart {
+		device_type = "device-memory";
+		reg = <0x0 PLAT_ARM_BOOT_UART_BASE 0x0 0x01000>;
+	};
 };
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
index c58f17b..cb741a3 100644
--- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
@@ -82,4 +82,7 @@
 #endif
 #endif /* ARM_BL2_SP_LIST_DTS */
 	};
+#if DICE_PROTECTION_ENVIRONMENT
+	#include "dice_prot_env.dtsi"
+#endif
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index a42e39d..38413ef 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -32,6 +32,9 @@
  *               |       DTB      |
  *               |      (32K)     |
  *  0x8000_8000  ------------------
+ *               | NT_FW_CONFIG   |
+ *               |      (4KB)     |
+ *  0x8000_9000  ------------------
  *               |       ...      |
  *  0xf8a0_0000  ------------------   TC_NS_FWU_BASE
  *               |    FWU shmem   |
@@ -85,11 +88,11 @@
 						MT_MEMORY | MT_RW | MT_SECURE)
 
 #define PLAT_HW_CONFIG_DTB_BASE	TC_NS_DRAM1_BASE
-#define PLAT_HW_CONFIG_DTB_SIZE	ULL(0x8000)
+#define PLAT_ARM_HW_CONFIG_SIZE	ULL(0x8000)
 
 #define PLAT_DTB_DRAM_NS MAP_REGION_FLAT(	\
 					PLAT_HW_CONFIG_DTB_BASE,	\
-					PLAT_HW_CONFIG_DTB_SIZE,	\
+					PLAT_ARM_HW_CONFIG_SIZE,	\
 					MT_MEMORY | MT_RO | MT_NS)
 /*
  * Max size of SPMC is 2MB for tc. With SPMD enabled this value corresponds to
@@ -165,17 +168,9 @@
  * Size of cacheable stacks
  */
 #if defined(IMAGE_BL1)
-# if TRUSTED_BOARD_BOOT
 #  define PLATFORM_STACK_SIZE		0x1000
-# else
-#  define PLATFORM_STACK_SIZE		0x440
-# endif
 #elif defined(IMAGE_BL2)
-# if TRUSTED_BOARD_BOOT
 #  define PLATFORM_STACK_SIZE		0x1000
-# else
-#  define PLATFORM_STACK_SIZE		0x400
-# endif
 #elif defined(IMAGE_BL2U)
 # define PLATFORM_STACK_SIZE		0x400
 #elif defined(IMAGE_BL31)
@@ -190,11 +185,11 @@
 
 /*
  * In the current implementation the RoT Service request that requires the
- * biggest message buffer is the RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * biggest message buffer is the RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
  * maximum required buffer size is calculated based on the platform-specific
  * needs of this request.
  */
-#define PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE	0x500
+#define PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE	0x500
 
 #define TC_DEVICE_BASE			0x21000000
 #define TC_DEVICE_SIZE			0x5f000000
@@ -276,13 +271,13 @@
 
 /* Index of SDS region used in the communication with SCP */
 #define SDS_SCP_AP_REGION_ID		U(0)
-/* Index of SDS region used in the communication with RSS */
-#define SDS_RSS_AP_REGION_ID		U(1)
+/* Index of SDS region used in the communication with RSE */
+#define SDS_RSE_AP_REGION_ID		U(1)
 /*
- * Memory region for RSS's shared data storage (SDS)
+ * Memory region for RSE's shared data storage (SDS)
  * It is placed right after the SCMI payload area.
  */
-#define PLAT_ARM_RSS_AP_SDS_MEM_BASE	(CSS_SCMI_PAYLOAD_BASE + \
+#define PLAT_ARM_RSE_AP_SDS_MEM_BASE	(CSS_SCMI_PAYLOAD_BASE + \
 					 CSS_SCMI_PAYLOAD_SIZE_MAX)
 
 #define PLAT_ARM_CLUSTER_COUNT		U(1)
@@ -303,9 +298,14 @@
 #endif /* TARGET_PLATFORM == 3 */
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-/* TC2: AP<->RSS MHUs */
-#define PLAT_RSS_AP_SND_MHU_BASE	UL(0x2A840000)
-#define PLAT_RSS_AP_RCV_MHU_BASE	UL(0x2A850000)
+/* AP<->RSS MHUs */
+#if TARGET_PLATFORM <= 2
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x2A840000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x2A850000)
+#elif TARGET_PLATFORM == 3
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49100000)
+#endif
 
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
@@ -388,8 +388,6 @@
  */
 #undef PLAT_ARM_BOOT_UART_BASE
 #undef PLAT_ARM_RUN_UART_BASE
-#undef PLAT_ARM_SP_MIN_RUN_UART_BASE
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE	PLAT_ARM_RUN_UART_BASE
 
 #undef PLAT_ARM_CRASH_UART_BASE
 #undef PLAT_ARM_BOOT_UART_CLK_IN_HZ
@@ -410,10 +408,42 @@
 #endif /* TARGET_FLAVOUR_FPGA */
 
 #define PLAT_ARM_RUN_UART_BASE		TC_UART0
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE	PLAT_ARM_RUN_UART_BASE
 #define PLAT_ARM_CRASH_UART_BASE	PLAT_ARM_RUN_UART_BASE
 
 #define PLAT_ARM_BOOT_UART_CLK_IN_HZ	TC_UARTCLK
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ	TC_UARTCLK
 
+#if TARGET_PLATFORM == 3
+#define NCI_BASE_ADDR			UL(0x4F000000)
+#ifdef TARGET_FLAVOUR_FPGA
+#define MCN_ADDRESS_SPACE_SIZE		0x00120000
+#else
+#define MCN_ADDRESS_SPACE_SIZE		0x00130000
+#endif	/* TARGET_FLAVOUR_FPGA */
+#define MCN_OFFSET_IN_NCI		0x00C90000
+#define MCN_BASE_ADDR			(NCI_BASE_ADDR + MCN_OFFSET_IN_NCI)
+#define MCN_PMU_OFFSET			0x000C4000
+#define MCN_MICROARCH_OFFSET		0x000E4000
+#define MCN_MICROARCH_BASE_ADDR		(MCN_BASE_ADDR + MCN_MICROARCH_OFFSET)
+#define MCN_SCR_OFFSET			0x4
+#define MCN_SCR_PMU_BIT			10
+#define MCN_INSTANCES			4
+#define MCN_PMU_ADDR(n)			(MCN_BASE_ADDR + \
+					 (n * MCN_ADDRESS_SPACE_SIZE) + \
+					 MCN_PMU_OFFSET)
+#define MCN_MPAM_NS_OFFSET		0x000D0000
+#define MCN_MPAM_NS_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_NS_OFFSET)
+#define MCN_MPAM_S_OFFSET		0x000D4000
+#define MCN_MPAM_S_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_S_OFFSET)
+#define MPAM_SLCCFG_CTL_OFFSET		0x00003018
+#define SLC_RDALLOCMODE_SHIFT		8
+#define SLC_RDALLOCMODE_MASK		(3 << SLC_RDALLOCMODE_SHIFT)
+#define SLC_WRALLOCMODE_SHIFT		12
+#define SLC_WRALLOCMODE_MASK		(3 << SLC_WRALLOCMODE_SHIFT)
+
+#define SLC_DONT_ALLOC			0
+#define SLC_ALWAYS_ALLOC		1
+#define SLC_ALLOC_BUS_SIGNAL_ATTR	2
+#endif /* TARGET_PLATFORM == 3 */
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index a6b2b0d..6ba4694 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -8,7 +8,7 @@
 #define TC_PLAT_H
 
 #ifdef PLATFORM_TEST_ROTPK
-#include <rss_crypto_defs.h>
+#include <rse_crypto_defs.h>
 #endif
 
 void tc_bl31_common_platform_setup(void);
@@ -23,7 +23,7 @@
 
 #ifdef PLATFORM_TEST_ROTPK
 struct key_id_info {
-	enum rss_key_id_builtin_t key_id;
+	enum rse_key_id_builtin_t key_id;
 	const char *key_id_name;
 };
 
diff --git a/plat/arm/board/tc/nv_counter_test.c b/plat/arm/board/tc/nv_counter_test.c
index 179ec4b..9025569 100644
--- a/plat/arm/board/tc/nv_counter_test.c
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -7,9 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#include <drivers/arm/rss_comms.h>
+#include <drivers/arm/rse_comms.h>
 #include <plat/common/platform.h>
-#include "rss_platform_api.h"
+#include "rse_platform_api.h"
 
 #include <platform_def.h>
 
@@ -20,30 +20,30 @@
 	uint32_t new_val;
 	uint32_t id;
 
-	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
-		printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+		printf("Failed to initialize RSE 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);
+		status = rse_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 - psa_status = %d\n",
+			printf("Failed during first id=(%d) rse_platform_nv_counter_read - psa_status = %d\n",
 				       id, status);
 			return -1;
 		}
 
-		status = rss_platform_nv_counter_increment(id);
+		status = rse_platform_nv_counter_increment(id);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during id=(%d) rss_platform_nv_counter_increment - psa_status = %d\n",
+			printf("Failed during id=(%d) rse_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);
+		status = rse_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 - psa_status = %d\n",
+			printf("Failed during second id=(%d) rse_platform_nv_counter_read - psa_status = %d\n",
 					id, status);
 			return -1;
 		}
diff --git a/plat/arm/board/tc/plat_def_fip_uuid.h b/plat/arm/board/tc/plat_def_fip_uuid.h
index 631f7c9..46a455c 100644
--- a/plat/arm/board/tc/plat_def_fip_uuid.h
+++ b/plat/arm/board/tc/plat_def_fip_uuid.h
@@ -10,28 +10,28 @@
 
 #include "uuid.h"
 
-#define UUID_RSS_FIRMWARE_BL1_2 \
+#define UUID_RSE_FIRMWARE_BL1_2 \
 	{{0x0a, 0xa5, 0xb1, 0xbe}, {0xe7, 0x84}, {0x41, 0xc5}, 0x81, 0xb8, {0x4a, 0x41, 0xcb, 0x4a, 0xd2, 0xdf}}
 
-#define UUID_RSS_FIRMWARE_BL2 \
+#define UUID_RSE_FIRMWARE_BL2 \
 	{{0xa3, 0xb3, 0xb3, 0x0d}, {0xeb, 0xc9}, {0x40, 0x48}, 0xb4, 0x80, {0x15, 0x53, 0x61, 0xc1, 0x70, 0x48}}
 
-#define UUID_RSS_FIRMWARE_SCP_BL1 \
+#define UUID_RSE_FIRMWARE_SCP_BL1 \
 	{{0xbf, 0xd5, 0x09, 0x8d}, {0xa7, 0x07}, {0x4f, 0x15}, 0x89, 0x1c, {0x37, 0x22, 0x10, 0xcb, 0x51, 0xe2}}
 
-#define UUID_RSS_FIRMWARE_AP_BL1 \
+#define UUID_RSE_FIRMWARE_AP_BL1 \
 	{{0x12, 0x4c, 0x50, 0xe0}, {0xf2, 0xda}, {0x45, 0xe9}, 0x85, 0xc8, {0xda, 0xd9, 0x60, 0x9b, 0x7a, 0x11}}
 
-#define UUID_RSS_FIRMWARE_NS \
+#define UUID_RSE_FIRMWARE_NS \
 	{{0x8d, 0x95, 0x9f, 0x72}, {0xb8, 0xb1}, {0x42, 0x11}, 0x9a, 0xe6, {0x4b, 0x80, 0x97, 0x47, 0x5a, 0xd9}}
 
-#define UUID_RSS_FIRMWARE_S \
+#define UUID_RSE_FIRMWARE_S \
 	{{0x22, 0xea, 0x33, 0x85}, {0xf8, 0x6e}, {0x47, 0x93}, 0x96, 0x8a, {0x2f, 0xe3, 0xdd, 0x50, 0x33, 0xcc}}
 
-#define UUID_RSS_SIC_TABLES_NS \
+#define UUID_RSE_SIC_TABLES_NS \
 	{{0xd9, 0x10, 0x00, 0x72}, {0x6a, 0x28}, {0x4b, 0xec}, 0xb0, 0xd6, {0x8c, 0xed, 0xc4, 0x15, 0x7c, 0xe0}}
 
-#define UUID_RSS_SIC_TABLES_S \
+#define UUID_RSE_SIC_TABLES_S \
 	{{0xc7, 0x38, 0xd0, 0xde}, {0x8c, 0x26}, {0x48, 0x51}, 0x93, 0x36, {0xf3, 0xdb, 0xe2, 0x96, 0x65, 0x18}}
 
 #endif /* __PLAT_DEF_FIP_UUID__ */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 652a17e..28b98c2 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -10,8 +10,6 @@
 TC_DPU_USE_SCMI_CLK		:=	1
 # SCMI power domain control enable
 TC_SCMI_PD_CTRL_EN		:=	1
-# IOMMU: Enable the use of system or individual MMUs
-TC_IOMMU_EN			:=	1
 
 # System setup
 CSS_USE_SCMI_SDS_DRIVER		:=	1
@@ -40,10 +38,22 @@
 
 ifeq (${SPD},spmd)
 	SPMD_SPM_AT_SEL2	:=	1
-	ENABLE_FEAT_MTE		:=	1
+	ENABLE_FEAT_MTE2	:=	1
 	CTX_INCLUDE_PAUTH_REGS	:=	1
 endif
 
+# TC RESOLUTION - LIST OF VALID OPTIONS (this impacts only FVP)
+TC_RESOLUTION_OPTIONS		:= 	640x480p60 \
+					1920x1080p60
+# Set default to the 640x480p60 resolution mode
+TC_RESOLUTION ?= $(firstword $(TC_RESOLUTION_OPTIONS))
+
+# Check resolution option for FVP
+ifneq ($(filter ${TARGET_FLAVOUR}, fvp),)
+ifeq ($(filter ${TC_RESOLUTION}, ${TC_RESOLUTION_OPTIONS}),)
+        $(error TC_RESOLUTION is ${TC_RESOLUTION}, it must be: ${TC_RESOLUTION_OPTIONS})
+endif
+endif
 
 ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
         $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
@@ -61,13 +71,23 @@
 $(eval $(call add_defines, \
 	TARGET_PLATFORM \
 	TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
+	TC_RESOLUTION_$(call uppercase,${TC_RESOLUTION}) \
 	TC_DPU_USE_SCMI_CLK \
 	TC_SCMI_PD_CTRL_EN \
-	TC_IOMMU_EN \
 ))
 
 CSS_LOAD_SCP_IMAGES	:=	1
 
+# Save DSU PMU registers on cluster off and restore them on cluster on
+PRESERVE_DSU_PMU_REGS		:= 1
+
+# Specify MHU type based on platform
+ifneq ($(filter ${TARGET_PLATFORM}, 2),)
+	PLAT_MHU_VERSION	:= 2
+else
+	PLAT_MHU_VERSION	:= 3
+endif
+
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
@@ -97,8 +117,8 @@
 # CPU libraries for TARGET_PLATFORM=3
 ifeq (${TARGET_PLATFORM}, 3)
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
-			lib/cpus/aarch64/cortex_chaberton.S \
-			lib/cpus/aarch64/cortex_blackhawk.S
+			lib/cpus/aarch64/cortex_a725.S \
+			lib/cpus/aarch64/cortex_x925.S
 endif
 
 INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c
@@ -128,6 +148,7 @@
 				${TC_BASE}/tc_topology.c	\
 				lib/fconf/fconf.c			\
 				lib/fconf/fconf_dyn_cfg_getter.c	\
+				drivers/arm/css/dsu/dsu.c			\
 				drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
@@ -137,14 +158,18 @@
 
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${TC_BASE}/fdts/${PLAT}_fw_config.dts	\
-				${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts
+				${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts \
+				${TC_BASE}/fdts/${PLAT}_nt_fw_config.dts
 FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FVP_NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
 
 ifeq (${SPD},spmd)
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
@@ -159,7 +184,7 @@
 endif
 
 #Device tree
-TC_HW_CONFIG_DTS	:=	fdts/tc.dts
+TC_HW_CONFIG_DTS	:=	fdts/${PLAT}${TARGET_PLATFORM}.dts
 TC_HW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
 FDT_SOURCES		+=	${TC_HW_CONFIG_DTS}
 $(eval TC_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC_HW_CONFIG_DTS)))
@@ -170,27 +195,56 @@
 # Include Measured Boot makefile before any Crypto library makefile.
 # Crypto library makefile may need default definitions of Measured Boot build
 # flags present in Measured Boot makefile.
+$(info Including rse_comms.mk)
 ifeq (${MEASURED_BOOT},1)
-    MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
-    $(info Including ${MEASURED_BOOT_MK})
-    include ${MEASURED_BOOT_MK}
-    $(info Including rss_comms.mk)
-    include drivers/arm/rss/rss_comms.mk
+        $(info Including rse_comms.mk)
+        include drivers/arm/rse/rse_comms.mk
 
-    BL1_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+	BL1_SOURCES	+=	${RSE_COMMS_SOURCES}
+	BL2_SOURCES	+=	${RSE_COMMS_SOURCES}
+	PLAT_INCLUDES	+=	-Iinclude/lib/psa
+
+    ifeq (${DICE_PROTECTION_ENVIRONMENT},1)
+        $(info Including qcbor.mk)
+        include drivers/measured_boot/rse/qcbor.mk
+        $(info Including dice_prot_env.mk)
+        include drivers/measured_boot/rse/dice_prot_env.mk
+
+	BL1_SOURCES	+=	${QCBOR_SOURCES} \
+				${DPE_SOURCES} \
+				plat/arm/board/tc/tc_common_dpe.c \
+				plat/arm/board/tc/tc_bl1_dpe.c \
+				lib/psa/dice_protection_environment.c \
+				drivers/arm/css/sds/sds.c \
+				drivers/delay_timer/delay_timer.c \
+				drivers/delay_timer/generic_delay_timer.c
+
+	BL2_SOURCES	+=	${QCBOR_SOURCES} \
+				${DPE_SOURCES} \
+				plat/arm/board/tc/tc_common_dpe.c \
+				plat/arm/board/tc/tc_bl2_dpe.c \
+				lib/psa/dice_protection_environment.c
+
+	PLAT_INCLUDES	+=	-I${QCBOR_INCLUDES} \
+				-Iinclude/lib/dice
+    else
+        $(info Including rse_measured_boot.mk)
+        include drivers/measured_boot/rse/rse_measured_boot.mk
+
+	BL1_SOURCES	+=	${MEASURED_BOOT_SOURCES} \
 				plat/arm/board/tc/tc_common_measured_boot.c \
 				plat/arm/board/tc/tc_bl1_measured_boot.c \
-				lib/psa/measured_boot.c			 \
-				${RSS_COMMS_SOURCES}
+				lib/psa/measured_boot.c
 
-    BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+	BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
 				plat/arm/board/tc/tc_common_measured_boot.c \
 				plat/arm/board/tc/tc_bl2_measured_boot.c \
-				lib/psa/measured_boot.c			 \
-				${RSS_COMMS_SOURCES}
-
-PLAT_INCLUDES		+=	-Iinclude/lib/psa
+				lib/psa/measured_boot.c
+    endif
+endif
 
+ifeq (${TRNG_SUPPORT},1)
+	BL31_SOURCES	+=	plat/arm/board/tc/tc_trng.c
 endif
 
 ifneq (${PLATFORM_TEST},)
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index 4e81b2c..8d39325 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -5,42 +5,42 @@
 
 $(eval $(call add_define,PLATFORM_TESTS))
 
-ifeq (${PLATFORM_TEST},rss-nv-counters)
-    include drivers/arm/rss/rss_comms.mk
+ifeq (${PLATFORM_TEST},rse-nv-counters)
+    include drivers/arm/rse/rse_comms.mk
 
     # Test code.
     BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
 
     # Code under testing.
-    BL31_SOURCES	+=	lib/psa/rss_platform.c \
-				${RSS_COMMS_SOURCES}
+    BL31_SOURCES	+=	lib/psa/rse_platform.c \
+				${RSE_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
+else ifeq (${PLATFORM_TEST},rse-rotpk)
+    include drivers/arm/rse/rse_comms.mk
 
     # Test code.
     BL31_SOURCES	+=	plat/arm/board/tc/rotpk_test.c
 
     # Code under testing.
-    BL31_SOURCES	+=	lib/psa/rss_platform.c \
-				${RSS_COMMS_SOURCES}
+    BL31_SOURCES	+=	lib/psa/rse_platform.c \
+				${RSE_COMMS_SOURCES}
 
     PLAT_INCLUDES	+=	-Iinclude/lib/psa
 
     $(eval $(call add_define,PLATFORM_TEST_ROTPK))
 else ifeq (${PLATFORM_TEST},tfm-testsuite)
-    include drivers/arm/rss/rss_comms.mk
+    include drivers/arm/rse/rse_comms.mk
 
     # The variables need to be set to compile the platform test:
     ifeq (${TF_M_TESTS_PATH},)
-        # Example: ../rss/tf-m-tests
+        # Example: ../rse/tf-m-tests
         $(error Error: TF_M_TESTS_PATH not set)
     endif
     ifeq (${TF_M_EXTRAS_PATH},)
-        # Example: ../rss/tf-m-extras
+        # Example: ../rse/tf-m-extras
         $(error Error: TF_M_EXTRAS_PATH not set)
     endif
     ifeq (${MEASUREMENT_VALUE_SIZE},)
@@ -61,18 +61,19 @@
 					hmac_drbg.c				\
 					psa_crypto.c				\
 					psa_crypto_client.c			\
-					psa_crypto_driver_wrappers.c		\
+					psa_crypto_driver_wrappers_no_static.c	\
 					psa_crypto_hash.c			\
 					psa_crypto_rsa.c			\
 					psa_crypto_ecp.c			\
 					psa_crypto_slot_management.c		\
+					psa_util.c				\
 					)
 
-    BL31_SOURCES	+=	${RSS_COMMS_SOURCES}				\
+    BL31_SOURCES	+=	${RSE_COMMS_SOURCES}				\
 				plat/arm/common/arm_dyn_cfg.c			\
-				${TC_BASE}/rss_ap_tests.c			\
-				${TC_BASE}/rss_ap_testsuites.c			\
-				${TC_BASE}/rss_ap_test_stubs.c			\
+				${TC_BASE}/rse_ap_tests.c			\
+				${TC_BASE}/rse_ap_testsuites.c			\
+				${TC_BASE}/rse_ap_test_stubs.c			\
 				$(TF_M_TESTS_PATH)/tests_reg/test/framework/test_framework.c \
 				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_common.c \
 				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_tests_common.c \
diff --git a/plat/arm/board/tc/rotpk_test.c b/plat/arm/board/tc/rotpk_test.c
index ed56c31..2178f69 100644
--- a/plat/arm/board/tc/rotpk_test.c
+++ b/plat/arm/board/tc/rotpk_test.c
@@ -7,9 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#include <drivers/arm/rss_comms.h>
+#include <drivers/arm/rse_comms.h>
 #include <plat/common/platform.h>
-#include <rss_platform_api.h>
+#include <rse_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)
@@ -28,19 +28,19 @@
 	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"}
+	       {.key_id = RSE_BUILTIN_KEY_ID_HOST_S_ROTPK,  .key_id_name = "Secure-ROTPK"},
+	       {.key_id = RSE_BUILTIN_KEY_ID_HOST_NS_ROTPK,  .key_id_name = "NS-ROTPK"},
+	       {.key_id = RSE_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);
+	status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
-		printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+		printf("Failed to initialize RSE 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,
+		status = rse_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);
diff --git a/plat/arm/board/tc/rss_ap_test_stubs.c b/plat/arm/board/tc/rse_ap_test_stubs.c
similarity index 92%
rename from plat/arm/board/tc/rss_ap_test_stubs.c
rename to plat/arm/board/tc/rse_ap_test_stubs.c
index aa97476..cf79181 100644
--- a/plat/arm/board/tc/rss_ap_test_stubs.c
+++ b/plat/arm/board/tc/rse_ap_test_stubs.c
@@ -26,7 +26,7 @@
 				     size_t measurement_value_size,
 				     bool lock_measurement)
 {
-	return rss_measured_boot_extend_measurement(index,
+	return rse_measured_boot_extend_measurement(index,
 						    signer_id,
 						    signer_id_size,
 						    version,
@@ -56,7 +56,7 @@
 				   size_t *measurement_value_len,
 				   bool *is_locked)
 {
-	return rss_measured_boot_read_measurement(index,
+	return rse_measured_boot_read_measurement(index,
 						  signer_id,
 						  signer_id_size,
 						  signer_id_len,
@@ -80,7 +80,7 @@
 			       size_t         token_buf_size,
 			       size_t        *token_size)
 {
-	return rss_delegated_attest_get_token(dak_pub_hash,
+	return rse_delegated_attest_get_token(dak_pub_hash,
 					      dak_pub_hash_size,
 					      token_buf,
 					      token_buf_size,
@@ -95,7 +95,7 @@
 				       size_t   *key_size,
 				       uint32_t  hash_algo)
 {
-	return rss_delegated_attest_get_delegated_key(ecc_curve,
+	return rse_delegated_attest_get_delegated_key(ecc_curve,
 						      key_bits,
 						      key_buf,
 						      key_buf_size,
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rse_ap_tests.c
similarity index 94%
rename from plat/arm/board/tc/rss_ap_tests.c
rename to plat/arm/board/tc/rse_ap_tests.c
index ea90ac3..3ca628a 100644
--- a/plat/arm/board/tc/rss_ap_tests.c
+++ b/plat/arm/board/tc/rse_ap_tests.c
@@ -10,9 +10,9 @@
 #include <mbedtls_common.h>
 #include <plat/common/platform.h>
 #include <psa/crypto.h>
-#include <rss_comms.h>
+#include <rse_comms.h>
 
-#include "rss_ap_testsuites.h"
+#include "rse_ap_testsuites.h"
 
 static struct test_suite_t test_suites[] = {
 	{.freg = register_testsuite_delegated_attest},
@@ -32,7 +32,7 @@
 	size_t i;
 
 	/* Initialize test environment. */
-	rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
 	mbedtls_init();
 	status = psa_crypto_init();
 	if (status != PSA_SUCCESS) {
diff --git a/plat/arm/board/tc/rss_ap_testsuites.c b/plat/arm/board/tc/rse_ap_testsuites.c
similarity index 93%
rename from plat/arm/board/tc/rss_ap_testsuites.c
rename to plat/arm/board/tc/rse_ap_testsuites.c
index aa47d4c..5f4dc16 100644
--- a/plat/arm/board/tc/rss_ap_testsuites.c
+++ b/plat/arm/board/tc/rse_ap_testsuites.c
@@ -11,7 +11,7 @@
  * necessary because both files define the function `extra_tests_init`, so a
  * linker error occurs when both are linked to BL31. This file defines a macro
  * that renames the colliding function names to something unique.
- * `plat/arm/board/tc/rss_ap_tests.c` can call the test init functions with
+ * `plat/arm/board/tc/rse_ap_tests.c` can call the test init functions with
  * their new name.
  */
 
diff --git a/plat/arm/board/tc/rss_ap_testsuites.h b/plat/arm/board/tc/rse_ap_testsuites.h
similarity index 76%
rename from plat/arm/board/tc/rss_ap_testsuites.h
rename to plat/arm/board/tc/rse_ap_testsuites.h
index 58502ab..9bb42f5 100644
--- a/plat/arm/board/tc/rss_ap_testsuites.h
+++ b/plat/arm/board/tc/rse_ap_testsuites.h
@@ -5,12 +5,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef RSS_AP_TESTSUITES_H
-#define RSS_AP_TESTSUITES_H
+#ifndef RSE_AP_TESTSUITES_H
+#define RSE_AP_TESTSUITES_H
 
 #include <test_framework.h>
 
 void register_testsuite_measured_boot(struct test_suite_t *p_test_suite);
 void register_testsuite_delegated_attest(struct test_suite_t *p_test_suite);
 
-#endif /* RSS_AP_TESTSUITES_H */
+#endif /* RSE_AP_TESTSUITES_H */
diff --git a/plat/arm/board/tc/tc_bl1_dpe.c b/plat/arm/board/tc/tc_bl1_dpe.c
new file mode 100644
index 0000000..de5702a
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_dpe.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/zero_oid.h>
+
+#include "tc_dpe.h"
+
+struct dpe_metadata tc_dpe_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = ZERO_OID },
+	{
+		.id = TB_FW_CONFIG_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = ZERO_OID },
+	{
+		.id = BL2_IMAGE_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
+		.allow_new_context_to_derive = true,
+		.retain_parent_context = true, /* To handle restart */
+		.target_locality = LOCALITY_AP_S,
+		.create_certificate = false,
+		.pk_oid = ZERO_OID },
+	{
+		.id = DPE_INVALID_ID }
+};
+
+/* Effective timeout of 10000 ms */
+#define RSE_DPE_BOOT_10US_RETRIES		1000000
+#define TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID	0x0000000A
+
+/* Context handle is meant to be used by BL2. Sharing it via TB_FW_CONFIG */
+static int new_ctx_handle;
+/* Save a valid parent context handle to be able to send commands to DPE service
+ * in case of an AP cold restart.
+ */
+static int new_parent_ctx_handle;
+
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle)
+{
+	new_ctx_handle = *ctx_handle;
+	new_parent_ctx_handle = *parent_ctx_handle;
+}
+
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int retry = RSE_DPE_BOOT_10US_RETRIES;
+	int ret;
+
+	/* Initialize System level generic or SP804 timer */
+	generic_delay_timer_init();
+
+	/* Check the initialization of the Shared Data Storage area between RSE
+	 * and AP. Since AP_BL1 is executed first then a bit later the RSE
+	 * runtime, which initialize this area, therefore AP needs to check it
+	 * in a loop until it gets written by RSE Secure Runtime.
+	 */
+	VERBOSE("Waiting for DPE service initialization in RSE Secure Runtime\n");
+	while (retry > 0) {
+		ret = sds_init(SDS_RSE_AP_REGION_ID);
+		if (ret != SDS_OK) {
+			udelay(10);
+			retry--;
+		} else {
+			break;
+		}
+	}
+
+	if (retry == 0) {
+		ERROR("DPE init timeout\n");
+		plat_panic_handler();
+	} else {
+		VERBOSE("DPE init succeeded in %dms.\n",
+			(RSE_DPE_BOOT_10US_RETRIES - retry) / 100);
+	}
+
+	/* TODO: call this in a loop to avoid reading unfinished data */
+	ret = sds_struct_read(SDS_RSE_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      ctx_handle,
+			      sizeof(*ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (ret != SDS_OK) {
+		ERROR("Unable to get DPE context handle from SDS area\n");
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
+
+	dpe_init(tc_dpe_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	int rc;
+
+	VERBOSE("Share DPE context handle with BL2: 0x%x\n", new_ctx_handle);
+	rc = arm_set_tb_fw_info(&new_ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to set DPE context handle in TB_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on TC platform, BL2 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL1.
+		 */
+		plat_panic_handler();
+	}
+
+	VERBOSE("Save parent context handle: 0x%x\n", new_parent_ctx_handle);
+	rc = sds_struct_write(SDS_RSE_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      &new_parent_ctx_handle,
+			      sizeof(new_parent_ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (rc != SDS_OK) {
+		ERROR("Unable to save DPE parent context handle to SDS area\n");
+		plat_panic_handler();
+	}
+}
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
index 6821a6a..28a1e31 100644
--- a/plat/arm/board/tc/tc_bl1_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
 
-#include <drivers/arm/rss_comms.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
-#include <lib/psa/measured_boot.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 #include <tools_share/zero_oid.h>
 
 #include <plat/arm/common/plat_arm.h>
@@ -17,40 +17,40 @@
 /* Table with platform specific image IDs and metadata. Intentionally not a
  * const struct, some members might set by bootloaders during trusted boot.
  */
-struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+struct rse_mboot_metadata tc_rse_mboot_metadata[] = {
 	{
 		.id = FW_CONFIG_ID,
 		.slot = U(6),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+		.sw_type = 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,
+		.sw_type = 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,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 
 	{
-		.id = RSS_MBOOT_INVALID_ID }
+		.id = RSE_MBOOT_INVALID_ID }
 };
 
 void bl1_plat_mboot_init(void)
 {
-	/* Initialize the communication channel between AP and RSS */
-	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
-			     PLAT_RSS_AP_RCV_MHU_BASE);
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init(tc_rss_mboot_metadata);
+	rse_measured_boot_init(tc_rse_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl2_dpe.c b/plat/arm/board/tc/tc_bl2_dpe.c
new file mode 100644
index 0000000..c56612b
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_dpe.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/tbbr_oid.h>
+
+#include "tc_dpe.h"
+
+/*
+ * The content and the values of this array depends on:
+ * - build config: Which components are loaded: SPMD, TOS, SPx, etc ?
+ * - boot order: the last element in a layer should be treated differently.
+ */
+
+/*
+ * TODO:
+ *     - The content of the array must be tailored according to the build
+ *       config (TOS, SPMD, etc). All loaded components (executables and
+ *       config blobs) must be present in this array.
+ *     - Current content is according to the Trusty build config.
+ */
+struct dpe_metadata tc_dpe_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = BL31_IMAGE_KEY_OID },
+	{
+		.id = BL32_IMAGE_ID,
+		.cert_id =  DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL32_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = BL32_IMAGE_KEY_OID },
+	{
+		.id = BL33_IMAGE_ID,
+		.cert_id = DPE_HYPERVISOR_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL33_IMAGE_STRING,
+		.allow_new_context_to_derive = true,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_AP_NS,
+		.pk_oid = BL33_IMAGE_KEY_OID },
+
+	{
+		.id = HW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = HW_CONFIG_KEY_OID },
+	{
+		.id = NT_FW_CONFIG_ID,
+		.cert_id = DPE_HYPERVISOR_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_NT_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NT_FW_CONFIG_KEY_OID },
+	{
+		.id = SCP_BL2_IMAGE_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = SCP_BL2_IMAGE_KEY_OID },
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = SOC_FW_CONFIG_KEY_OID },
+	{
+		.id = TOS_FW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TOS_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = TOS_FW_CONFIG_KEY_OID },
+#if defined(SPD_spmd)
+	{
+		.id = SP_PKG1_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP1_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = true, /* With Trusty only one SP is loaded */
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG2_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP2_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG3_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP3_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG4_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP4_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG5_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP5_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG6_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP6_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG7_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP7_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG8_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP8_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+
+#endif
+	{
+		.id = DPE_INVALID_ID }
+};
+
+/* Context handle is meant to be used by BL33. Sharing it via NT_FW_CONFIG */
+static int new_ctx_handle;
+
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle)
+{
+	new_ctx_handle = *ctx_handle;
+
+	/* Irrelevant in BL2 because cold restart resumes CPU in BL1 */
+	(void)parent_ctx_handle;
+}
+
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int rc;
+
+	rc = arm_get_tb_fw_info(ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to get DPE context handle from TB_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on FVP platform, BL2 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL1.
+		 */
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
+
+	dpe_init(tc_dpe_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	int rc;
+
+	VERBOSE("Share DPE context handle with BL33: 0x%x\n", new_ctx_handle);
+	rc = arm_set_nt_fw_info(&new_ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to set DPE context handle in NT_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on TC platform, BL33 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL2.
+		 */
+		plat_panic_handler();
+	}
+}
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index 4b79170..3957c90 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
 
-#include <drivers/arm/rss_comms.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
-#include <lib/psa/measured_boot.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 #include <tools_share/tbbr_oid.h>
 
 #include <plat/common/common_def.h>
@@ -17,39 +17,46 @@
 /* TC specific table with image IDs and metadata. Intentionally not a
  * const struct, some members might set by bootloaders during trusted boot.
  */
-struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+struct rse_mboot_metadata tc_rse_mboot_metadata[] = {
 	{
 		.id = BL31_IMAGE_ID,
 		.slot = U(9),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL31_STRING,
+		.sw_type = MBOOT_BL31_IMAGE_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,
+		.sw_type = 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,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
 		.pk_oid = SOC_FW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
-		.id = RSS_MBOOT_INVALID_ID }
+		.id = SCP_BL2_IMAGE_ID,
+		.slot = U(12),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+		.pk_oid = SCP_BL2_IMAGE_KEY_OID,
+		.lock_measurement = true },
+	{
+		.id = RSE_MBOOT_INVALID_ID }
 };
 
 void bl2_plat_mboot_init(void)
 {
-	/* Initialize the communication channel between AP and RSS */
-	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
-			     PLAT_RSS_AP_RCV_MHU_BASE);
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init(tc_rss_mboot_metadata);
+	rse_measured_boot_init(tc_rse_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 d884366..7d1bc9c 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -50,50 +50,79 @@
 }
 #endif /* PLATFORM_TEST_TFM_TESTSUITE */
 
-static scmi_channel_plat_info_t tc_scmi_plat_info[] = {
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	}
+#if TARGET_PLATFORM <= 2
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhuv2_ring_doorbell,
+};
+#elif TARGET_PLATFORM == 3
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhu_ring_doorbell,
 };
 
+static void enable_ns_mcn_pmu(void)
+{
+	/*
+	 * Enable non-secure access to MCN PMU registers
+	 */
+	for (int i = 0; i < MCN_INSTANCES; i++) {
+		uintptr_t mcn_scr = MCN_MICROARCH_BASE_ADDR + MCN_SCR_OFFSET +
+			(i * MCN_ADDRESS_SPACE_SIZE);
+		mmio_setbits_32(mcn_scr, 1 << MCN_SCR_PMU_BIT);
+	}
+}
+
+static void set_mcn_slc_alloc_mode(void)
+{
+	/*
+	 * SLC WRALLOCMODE and RDALLOCMODE are configured by default to
+	 * 0b01 (always alloc), configure both to 0b10 (use bus signal
+	 * attribute from interface).
+	 */
+	for (int i = 0; i < MCN_INSTANCES; i++) {
+		uintptr_t slccfg_ctl_ns = MCN_MPAM_NS_BASE_ADDR +
+			(i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
+		uintptr_t slccfg_ctl_s = MCN_MPAM_S_BASE_ADDR +
+			(i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
+
+		mmio_clrsetbits_32(slccfg_ctl_ns,
+				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_RDALLOCMODE_SHIFT) |
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_WRALLOCMODE_SHIFT));
+		mmio_clrsetbits_32(slccfg_ctl_s,
+				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_RDALLOCMODE_SHIFT) |
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_WRALLOCMODE_SHIFT));
+	}
+}
+#endif
+
 void bl31_platform_setup(void)
 {
 	tc_bl31_common_platform_setup();
+#if TARGET_PLATFORM == 3
+	enable_ns_mcn_pmu();
+	set_mcn_slc_alloc_mode();
+#endif
 }
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id __unused)
 {
 
-	return &tc_scmi_plat_info[channel_id];
+	return &tc_scmi_plat_info;
 
 }
 
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	/*
-	 * Pass the hw_config to BL33 in R0. You'll notice that
-	 * arm_bl31_early_platform_setup does something similar but only behind
-	 * ARM_LINUX_KERNEL_AS_BL33 and we want to pass the DTB even to a
-	 * bootloader. Lucky for us, it copies the ep_info BL2 gave us to BL33
-	 * unconditionally in the generic case so hijack that.
-	 * TODO: this goes away with firmware handoff when it will be proper
-	 */
-
-	bl_params_node_t *bl_params = ((bl_params_t *)arg0)->head;
-
-	while (bl_params != NULL) {
-		if (bl_params->image_id == BL33_IMAGE_ID) {
-			bl_params->ep_info->args.arg0 = arg2;
-			break;
-		}
-		bl_params = bl_params->next_params_info;
-	}
-
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 
 	/* Fill the properties struct with the info from the config dtb */
@@ -154,10 +183,10 @@
 #if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
 void tc_bl31_plat_runtime_setup(void)
 {
-	arm_bl31_plat_runtime_setup();
-
 	/* Start secure watchdog timer. */
 	plat_arm_secure_wdt_start();
+
+	arm_bl31_plat_runtime_setup();
 }
 
 void bl31_plat_runtime_setup(void)
diff --git a/plat/arm/board/tc/tc_common_dpe.c b/plat/arm/board/tc/tc_common_dpe.c
new file mode 100644
index 0000000..72ac673
--- /dev/null
+++ b/plat/arm/board/tc/tc_common_dpe.c
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+
+extern struct dpe_metadata tc_dpe_metadata[];
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int err;
+
+	/* Calculate image hash and record it in the DPE service in RSE. */
+	err = dpe_measure_and_record(tc_dpe_metadata,
+				     image_data->image_base,
+				     image_data->image_size,
+				     image_id);
+	if (err != 0) {
+		ERROR("%s%s image id %u (%i)\n",
+		      "Failed to ", "record in DPE", image_id, err);
+	}
+
+	return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return dpe_set_signer_id(tc_dpe_metadata, pk_oid, pk_ptr, pk_len);
+}
diff --git a/plat/arm/board/tc/tc_common_measured_boot.c b/plat/arm/board/tc/tc_common_measured_boot.c
index 925a411..6b8d41a 100644
--- a/plat/arm/board/tc/tc_common_measured_boot.c
+++ b/plat/arm/board/tc/tc_common_measured_boot.c
@@ -8,22 +8,22 @@
 #include <stdint.h>
 
 #include <common/desc_image_load.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 
-extern struct rss_mboot_metadata tc_rss_mboot_metadata[];
+extern struct rse_mboot_metadata tc_rse_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(tc_rss_mboot_metadata,
+	/* Calculate image hash and record data in RSE */
+	err = rse_mboot_measure_and_record(tc_rse_mboot_metadata,
 					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
 	if (err != 0) {
 		ERROR("%s%s image id %u (%i)\n",
-		      "Failed to ", "record in RSS", image_id, err);
+		      "Failed to ", "record in RSE", image_id, err);
 	}
 
 	return err;
@@ -31,6 +31,6 @@
 
 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,
+	return rse_mboot_set_signer_id(tc_rse_mboot_metadata, pk_oid, pk_ptr,
 				       pk_len);
 }
diff --git a/plat/arm/board/tc/tc_dpe.h b/plat/arm/board/tc/tc_dpe.h
new file mode 100644
index 0000000..3e1af5a
--- /dev/null
+++ b/plat/arm/board/tc/tc_dpe.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TC_DPE_H
+#define TC_DPE_H
+
+/*
+ * The certificate structure on the TC platform:
+ *   - The arrows indicate the parent/child relationships (who loads who).
+ *   - The boxes indicate the certificates.
+ *
+ *                                                                  AP FW Cert.
+ *                                                      +--------------------------------+
+ *                                                      |                                |
+ *                             Plat Cert.               |                +->SPx          |           Hyper Cert.
+ *                     +--------------------------+     |                +->SP1          |     +--------------------+
+ *     RoT Cert.       |                          |     |                +->TOS_FW_CONF  |     |                    |
+ *  +------------+     |      +->SCP_BL1    +-----+-----+-->FW_CONF      +->AP_BL32      |     |     +->PVMFW       |
+ *  |            |     |      |             |     |     |                |               |     |     |              |
+ *  | RSE_BL1_2--+-----+-->RSE_BL2------->AP_BL1--+-----+------------->AP_BL2------------+-----+-->AP_BL33          |
+ *  |            |     |      |             |     |     |                |               |     |     |              |
+ *  +------------+     |      +->RSE_S      +-----+-----+-->TB_FW_CONF   +->AP_BL31      |     |     +->HYPERVISOR  |
+ *                     |      +->RSE_NS           |     |                +->SCP_BL2      |     |                    |
+ *                     |                          |     |                +->HW_CONF      |     |                    |
+ *                     +--------------------------+     |                +---------------+-----+-->NT_FW_CONF       |
+ *                                                      |                                |     |                    |
+ *                                                      +--------------------------------+     +--------------------+
+ */
+
+#define DPE_AP_FW_CERT_ID		0x300 /* Includes: FW_CONF - SP1 */
+#define DPE_HYPERVISOR_CERT_ID		0x400 /* Includes: AP_BL33 - PVMFW */
+
+/* Common definition */
+#define DPE_CERT_ID_SAME_AS_PARENT	0xFFFFFFFF
+
+/*
+ * Target Locality:
+ *    The goal is to specify that a certain component is expected to run and
+ *    thereby send DPE commands from a given security domain. RSE is capable of
+ *    of distinguishing the client's locality based on the MHU channel used for
+ *    communication.
+ *    Defines here must match with RSE side:
+ */
+#define LOCALITY_NONE		-1
+/* #define LOCALITY_RSE_S	0 */  /* Not applicable on AP side */
+/* #define LOCALITY_RSE_NS	1 */  /* Not applicable on AP side */
+#define LOCALITY_AP_S		 2
+#define LOCALITY_AP_NS		 3
+
+#endif /* TC_DPE_H */
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index e5d05c4..fed14f7 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -165,7 +165,7 @@
 
 static sds_region_desc_t tc_sds_regions[] = {
 	{ .base = PLAT_ARM_SDS_MEM_BASE },
-	{ .base = PLAT_ARM_RSS_AP_SDS_MEM_BASE },
+	{ .base = PLAT_ARM_RSE_AP_SDS_MEM_BASE },
 };
 
 sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
diff --git a/plat/arm/board/tc/tc_topology.c b/plat/arm/board/tc/tc_topology.c
index cc0dcc2..7631873 100644
--- a/plat/arm/board/tc/tc_topology.c
+++ b/plat/arm/board/tc/tc_topology.c
@@ -65,3 +65,11 @@
 	return PLAT_MAX_PE_PER_CPU;
 }
 #endif
+
+/******************************************************************************
+ * Return the cluster ID of current CPU
+ *****************************************************************************/
+unsigned int plat_cluster_id_by_mpidr(u_register_t mpidr)
+{
+	return MPIDR_AFFLVL2_VAL(mpidr);
+}
diff --git a/plat/arm/board/tc/tc_trng.c b/plat/arm/board/tc/tc_trng.c
new file mode 100644
index 0000000..e5ec48a
--- /dev/null
+++ b/plat/arm/board/tc/tc_trng.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_acle.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+	0x23523c58, 0x7448, 0x4083, 0x9d, 0x16,
+	0xe3, 0xfa, 0xb9, 0xf1, 0x73, 0xbc
+);
+uuid_t plat_trng_uuid;
+
+/* Dummy implementation */
+bool plat_get_entropy(uint64_t *out)
+{
+	*out = 0xABBAEDDAACDCDEAD;
+
+	return true;
+}
+
+void plat_entropy_setup(void)
+{
+	uint64_t dummy;
+
+	plat_trng_uuid = _plat_trng_uuid;
+
+	/* Initialise the entropy source and trigger RNG generation */
+	plat_get_entropy(&dummy);
+}
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index feff691..f043f59 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,9 @@
 #include <common/debug.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
@@ -61,6 +64,10 @@
 /* Boolean variable to hold condition whether firmware update needed or not */
 static bool is_fwu_needed;
 
+#if TRANSFER_LIST
+static struct transfer_list_header *secure_tl;
+#endif
+
 struct meminfo *bl1_plat_sec_mem_layout(void)
 {
 	return &bl1_tzram_layout;
@@ -144,9 +151,13 @@
  */
 void arm_bl1_platform_setup(void)
 {
-	const struct dyn_cfg_dtb_info_t *fw_config_info;
+	const struct dyn_cfg_dtb_info_t *config_info __unused;
+	uint32_t fw_config_max_size __unused;
+	image_info_t config_image_info __unused;
+	struct transfer_list_entry *te __unused;
+
 	image_desc_t *desc;
-	uint32_t fw_config_max_size;
+
 	int err = -1;
 
 	/* Initialise the IO layer and register platform IO devices */
@@ -159,6 +170,37 @@
 		return;
 	}
 
+#if TRANSFER_LIST
+	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+				       PLAT_ARM_FW_HANDOFF_SIZE);
+
+	if (secure_tl == NULL) {
+		ERROR("Secure transfer list initialisation failed!\n");
+		panic();
+	}
+
+	te = transfer_list_add(secure_tl, TL_TAG_TB_FW_CONFIG,
+			       ARM_TB_FW_CONFIG_MAX_SIZE, NULL);
+	assert(te != NULL);
+
+	/*
+	 * Set the load address of TB_FW_CONFIG in the data section of the TE just
+	 * allocated in the secure transfer list.
+	 */
+	SET_PARAM_HEAD(&config_image_info, PARAM_IMAGE_BINARY, VERSION_2, 0);
+	config_image_info.image_base = (uintptr_t)transfer_list_entry_data(te);
+	config_image_info.image_max_size = te->data_size;
+
+	VERBOSE("FCONF: Loading config with image ID: %u\n", TB_FW_CONFIG_ID);
+	err = load_auth_image(TB_FW_CONFIG_ID, &config_image_info);
+	if (err != 0) {
+		VERBOSE("Failed to load config %u\n", TB_FW_CONFIG_ID);
+		plat_error_handler(err);
+	}
+
+	transfer_list_update_checksum(secure_tl);
+	fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+#else
 	/* Set global DTB info for fixed fw_config information */
 	fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
 	set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size, FW_CONFIG_ID);
@@ -174,13 +216,14 @@
 	 * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing
 	 * is successful then load TB_FW_CONFIG device tree.
 	 */
-	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
-	if (fw_config_info != NULL) {
-		err = fconf_populate_dtb_registry(fw_config_info->config_addr);
+	config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+	if (config_info != NULL) {
+		err = fconf_populate_dtb_registry(config_info->config_addr);
 		if (err < 0) {
 			ERROR("Parsing of FW_CONFIG failed %d\n", err);
 			plat_error_handler(err);
 		}
+
 		/* load TB_FW_CONFIG */
 		err = fconf_load_config(TB_FW_CONFIG_ID);
 		if (err < 0) {
@@ -191,11 +234,17 @@
 		ERROR("Invalid FW_CONFIG address\n");
 		plat_error_handler(err);
 	}
+#endif /* TRANSFER_LIST */
 
-	/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
 	desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+
+#if TRANSFER_LIST
+	transfer_list_set_handoff_args(secure_tl, &desc->ep_info);
+#else
+	/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
 	assert(desc != NULL);
-	desc->ep_info.args.arg0 = fw_config_info->config_addr;
+	desc->ep_info.args.arg0 = config_info->config_addr;
+#endif /* TRANSFER_LIST */
 
 #if CRYPTO_SUPPORT
 	/* Share the Mbed TLS heap info with other images */
@@ -250,3 +299,32 @@
 {
 	return  is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
 }
+
+// Use the default implementation of this function when Firmware Handoff is
+// disabled to avoid duplicating its logic.
+#if TRANSFER_LIST
+int bl1_plat_handle_post_image_load(unsigned int image_id)
+{
+	image_desc_t *image_desc __unused;
+
+	assert(image_id == BL2_IMAGE_ID);
+	struct transfer_list_entry *te;
+
+	/* Convey this information to BL2 via its TL. */
+	te = transfer_list_add(secure_tl, TL_TAG_SRAM_LAYOUT64,
+			       sizeof(meminfo_t), NULL);
+	assert(te != NULL);
+
+	bl1_plat_calc_bl2_layout(&bl1_tzram_layout,
+				 (meminfo_t *)transfer_list_entry_data(te));
+
+	transfer_list_update_checksum(secure_tl);
+
+	/**
+	 * Before exiting make sure the contents of the TL are flushed in case there's no
+	 * support for hardware cache coherency.
+	 */
+	flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
+	return 0;
+}
+#endif /* TRANSFER_LIST*/
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 30d0647..58a14ab 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -19,6 +19,9 @@
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/gpt_rme/gpt_rme.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #ifdef SPD_opteed
 #include <lib/optee_utils.h>
 #endif
@@ -30,13 +33,18 @@
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
 
 /* Base address of fw_config received from BL1 */
-static uintptr_t config_base;
+static uintptr_t config_base __unused;
 
 /*
  * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is
  * for `meminfo_t` data structure and fw_configs passed from BL1.
  */
+#if TRANSFER_LIST
+CASSERT(BL2_BASE >= PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE,
+	assert_bl2_base_overflows);
+#else
 CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
+#endif /* TRANSFER_LIST */
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl2_early_platform_setup2
@@ -58,6 +66,9 @@
 
 #pragma weak arm_bl2_plat_handle_post_image_load
 
+static struct transfer_list_header *secure_tl __unused;
+static struct transfer_list_header *ns_tl __unused;
+
 /*******************************************************************************
  * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
@@ -66,16 +77,28 @@
 void arm_bl2_early_platform_setup(uintptr_t fw_config,
 				  struct meminfo *mem_layout)
 {
+	struct transfer_list_entry *te __unused;
 	int __maybe_unused ret;
 
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
-	/* Setup the BL2 memory layout */
-	bl2_tzram_layout = *mem_layout;
+#if TRANSFER_LIST
+	// TODO: modify the prototype of this function fw_config != bl2_tl
+	secure_tl = (struct transfer_list_header *)fw_config;
 
+	te = transfer_list_find(secure_tl, TL_TAG_SRAM_LAYOUT64);
+	assert(te != NULL);
+
+	bl2_tzram_layout = *(meminfo_t *)transfer_list_entry_data(te);
+	transfer_list_rem(secure_tl, te);
+#else
 	config_base = fw_config;
 
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+#endif
+
 	/* Initialise the IO layer and register platform IO devices */
 	plat_arm_io_setup();
 
@@ -103,7 +126,22 @@
  */
 void bl2_plat_preload_setup(void)
 {
+#if TRANSFER_LIST
+/* Assume the secure TL hasn't been initialised if BL2 is running at EL3. */
+#if RESET_TO_BL2
+	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+				       PLAT_ARM_FW_HANDOFF_SIZE);
+
+	if (secure_tl == NULL) {
+		ERROR("Secure transfer list initialisation failed!\n");
+		panic();
+	}
+#endif
+
+	arm_transfer_list_dyn_cfg_init(secure_tl);
+#else
 	arm_bl2_dyn_cfg_init();
+#endif
 
 #if ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT
 	/* Always use the FIP from bank 0 */
@@ -124,6 +162,16 @@
 #if defined(PLAT_ARM_MEM_PROT_ADDR)
 	arm_nor_psci_do_static_mem_protect();
 #endif
+
+#if TRANSFER_LIST
+	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
+				   PLAT_ARM_FW_HANDOFF_SIZE);
+
+	if (ns_tl == NULL) {
+		ERROR("Non-secure transfer list initialisation failed!");
+		panic();
+	}
+#endif
 }
 
 void bl2_platform_setup(void)
@@ -151,11 +199,13 @@
 		ARM_MAP_ROMLIB_CODE,
 		ARM_MAP_ROMLIB_DATA,
 #endif
+#if !TRANSFER_LIST
 		ARM_MAP_BL_CONFIG_REGION,
+#endif /* TRANSFER_LIST */
 #if ENABLE_RME
 		ARM_MAP_L0_GPT_REGION,
 #endif
-		{0}
+		{ 0 }
 	};
 
 #if ENABLE_RME
@@ -167,7 +217,7 @@
 #ifdef __aarch64__
 #if ENABLE_RME
 	/* BL2 runs in EL3 when RME enabled. */
-	assert(get_armv9_2_feat_rme_support() != 0U);
+	assert(is_feat_rme_present());
 	enable_mmu_el3(0);
 
 	/* Initialise and enable granule protection after MMU. */
@@ -184,10 +234,17 @@
 
 void bl2_plat_arch_setup(void)
 {
-	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
-
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info __unused;
+	struct transfer_list_entry *te __unused;
 	arm_bl2_plat_arch_setup();
 
+#if TRANSFER_LIST
+	te = transfer_list_find(secure_tl, TL_TAG_TB_FW_CONFIG);
+	assert(te != NULL);
+
+	fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+	transfer_list_rem(secure_tl, te);
+#else
 	/* Fill the properties struct with the info from the config dtb */
 	fconf_populate("FW_CONFIG", config_base);
 
@@ -196,6 +253,7 @@
 	assert(tb_fw_config_info != NULL);
 
 	fconf_populate("TB_FW", tb_fw_config_info->config_addr);
+#endif
 }
 
 int arm_bl2_handle_post_image_load(unsigned int image_id)
@@ -265,5 +323,20 @@
 		return 0;
 	}
 #endif
+
+#if TRANSFER_LIST
+	if (image_id == HW_CONFIG_ID) {
+		arm_transfer_list_copy_hw_config(secure_tl, ns_tl);
+	}
+#endif /* TRANSFER_LIST */
+
 	return arm_bl2_handle_post_image_load(image_id);
 }
+
+void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node)
+{
+	assert(transfer_list_set_handoff_args(
+		       secure_tl, &next_param_node->ep_info) != NULL);
+
+	arm_transfer_list_populate_ep_info(next_param_node, secure_tl, ns_tl);
+}
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 8e90615..b7941ec 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,13 +13,18 @@
 #include <drivers/console.h>
 #include <lib/debugfs.h>
 #include <lib/extensions/ras.h>
+#include <lib/fconf/fconf.h>
 #include <lib/gpt_rme/gpt_rme.h>
 #include <lib/mmio.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
+static struct transfer_list_header *secure_tl __unused;
 /*
  * Placeholder variables for copying the arguments that have been passed to
  * BL31 from BL2.
@@ -35,8 +40,12 @@
  * 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.
  */
+#if TRANSFER_LIST
+CASSERT(BL31_BASE >= PLAT_ARM_EL3_FW_HANDOFF_LIMIT, assert_bl31_base_overflows);
+#else
 CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
-#endif
+#endif /* TRANSFER_LIST */
+#endif /* RESET_TO_BL31 */
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl31_early_platform_setup2
@@ -115,6 +124,44 @@
  * while creating page tables. BL2 has flushed this information to memory, so
  * we are guaranteed to pick up good data.
  ******************************************************************************/
+#if TRANSFER_LIST
+void __init arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
+					  u_register_t arg2, u_register_t arg3)
+{
+	struct transfer_list_entry *te = NULL;
+	struct entry_point_info *ep;
+
+	secure_tl = (struct transfer_list_header *)arg3;
+
+	/*
+	 * Populate the global entry point structures used to execute subsequent
+	 * images.
+	 */
+	while ((te = transfer_list_next(secure_tl, te)) != NULL) {
+		ep = transfer_list_entry_data(te);
+
+		if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
+			switch (GET_SECURITY_STATE(ep->h.attr)) {
+			case NON_SECURE:
+				bl33_image_ep_info = *ep;
+				break;
+#if ENABLE_RME
+			case REALM:
+				rmm_image_ep_info = *ep;
+				break;
+#endif
+			case SECURE:
+				bl32_image_ep_info = *ep;
+				break;
+			default:
+				ERROR("Unrecognized Image Security State %lu\n",
+				      GET_SECURITY_STATE(ep->h.attr));
+				panic();
+			}
+		}
+	}
+}
+#else
 void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
 				uintptr_t hw_config, void *plat_params_from_bl2)
 {
@@ -258,11 +305,16 @@
 	bl33_image_ep_info.args.arg3 = 0U;
 # endif
 }
+#endif
 
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+#if TRANSFER_LIST
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
+#else
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+#endif
 
 	/*
 	 * Initialize Interconnect for this cluster during cold boot.
@@ -325,12 +377,9 @@
 /*******************************************************************************
  * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
  * standard platforms
- * Perform BL31 platform setup
  ******************************************************************************/
 void arm_bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
 	/* Initialize the runtime console */
 	arm_console_runtime_init();
 
@@ -448,5 +497,15 @@
 
 void __init bl31_plat_arch_setup(void)
 {
+	struct transfer_list_entry *te __unused;
+
 	arm_bl31_plat_arch_setup();
+
+#if TRANSFER_LIST && !RESET_TO_BL2
+	te = transfer_list_find(secure_tl, TL_TAG_FDT);
+	assert(te != NULL);
+
+	/* Populate HW_CONFIG device tree with the mapped address */
+	fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te));
+#endif
 }
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 5084ea9..f5919ab 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -26,7 +26,7 @@
   else ifeq (${ARM_TSP_RAM_LOCATION}, dram)
     ARM_TSP_RAM_LOCATION_ID = ARM_DRAM_ID
   else
-    $(error "Unsupported ARM_TSP_RAM_LOCATION value")
+    $(error Unsupported ARM_TSP_RAM_LOCATION value)
   endif
 
   # Process flags
@@ -83,7 +83,7 @@
 # memory. This means we must not run BL31 from TZC-protected DRAM.
 ifeq (${ARM_BL31_IN_DRAM},1)
   ifeq (${ENABLE_RME},1)
-    $(error "BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0")
+    $(error BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0)
   endif
 endif
 
@@ -105,16 +105,15 @@
 ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
   ifneq (${ARCH},aarch64)
     ifneq (${RESET_TO_SP_MIN},1)
-      $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if 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.")
+    $(error PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.)
   endif
   ifeq (${RESET_TO_BL31},1)
     ifndef ARM_PRELOADED_DTB_BASE
-      $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is
-       used with RESET_TO_BL31.")
+      $(error ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used with RESET_TO_BL31.)
     endif
     $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
   endif
@@ -299,6 +298,10 @@
 				plat/arm/common/arm_topology.c			\
 				plat/common/plat_psci_common.c
 
+ifeq (${TRANSFER_LIST}, 1)
+	TRANSFER_LIST_SOURCES += plat/arm/common/arm_transfer_list.c
+endif
+
 ifneq ($(filter 1,${ENABLE_PMF} ${ETHOSN_NPU_DRIVER}),)
 ARM_SVC_HANDLER_SRCS :=
 
@@ -381,7 +384,12 @@
             endif
         endif
     else ifeq (${COT},dualroot)
-        AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
+        BL1_SOURCES	+=	drivers/auth/dualroot/cot.c
+        ifneq (${COT_DESC_IN_DTB},0)
+            BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
+        else
+            BL2_SOURCES	+=	drivers/auth/dualroot/cot.c
+        endif
     else ifeq (${COT},cca)
         BL1_SOURCES	+=	drivers/auth/cca/cot.c
         ifneq (${COT_DESC_IN_DTB},0)
@@ -447,6 +455,6 @@
 
 ifeq (${RECLAIM_INIT_CODE}, 1)
     ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-        $(error "To reclaim init code xlat tables v2 must be used")
+        $(error To reclaim init code xlat tables v2 must be used)
     endif
 endif
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 99e2809..18ab5be 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -120,6 +120,7 @@
 }
 #endif /* CRYPTO_SUPPORT */
 
+#if IMAGE_BL2
 /*
  * BL2 utility function to initialize dynamic configuration specified by
  * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
@@ -229,3 +230,4 @@
 		panic();
 	}
 }
+#endif /* IMAGE_BL2 */
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 5dc1115..d13be99 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -124,6 +124,150 @@
 }
 
 #if MEASURED_BOOT
+#if DICE_PROTECTION_ENVIRONMENT
+
+#include <common/desc_image_load.h>
+
+#define DTB_PROP_DPE_CTX_HANDLE		"dpe_ctx_handle"
+
+static int arm_set_dpe_context_handle(uintptr_t config_base,
+				      int *ctx_handle)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	void *dtb = (void *)config_base;
+	const char *compatible = "arm,dpe_ctx_handle";
+	int err, node;
+
+	/*
+	 * Verify that the DTB is valid, before attempting to write to it,
+	 * and get the DTB root node.
+	 */
+
+	/* Check if the pointer to DT is correct */
+	err = fdt_check_header(dtb);
+	if (err < 0) {
+		WARN("Invalid DTB file passed\n");
+		return err;
+	}
+
+	/* Assert the node offset point to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+	if (node < 0) {
+		WARN("The compatible property '%s' not%s", compatible,
+			" found in the config\n");
+		return node;
+	}
+
+	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+	err = fdtw_write_inplace_cells(dtb, node,
+		DTB_PROP_DPE_CTX_HANDLE, 1, ctx_handle);
+	if (err < 0) {
+		ERROR("%sDTB property '%s'\n",
+			"Unable to write ", DTB_PROP_DPE_CTX_HANDLE);
+	} else {
+		/*
+		 * Ensure that the info written to the DTB is visible
+		 * to other images.
+		 */
+		flush_dcache_range(config_base, fdt_totalsize(dtb));
+	}
+
+	return err;
+}
+
+/*
+ * This function writes the DPE context handle value to the NT_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int arm_set_nt_fw_info(int *ctx_handle)
+{
+	uintptr_t config_base;
+	const bl_mem_params_node_t *cfg_mem_params;
+
+	/* Get the config load address and size from NT_FW_CONFIG */
+	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
+	assert(cfg_mem_params != NULL);
+
+	config_base = cfg_mem_params->image_info.image_base;
+
+	/* Write the context handle value in the DTB */
+	return arm_set_dpe_context_handle(config_base, ctx_handle);
+}
+
+/*
+ * This function writes the DPE context handle value to the TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int arm_set_tb_fw_info(int *ctx_handle)
+{
+	/*
+	 * Read tb_fw_config device tree for Event Log properties
+	 * and write the Event Log address and its size in the DTB
+	 */
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+	uintptr_t tb_fw_cfg_dtb;
+
+	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+	assert(tb_fw_config_info != NULL);
+
+	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
+
+	/* Write the context handle value in the DTB */
+	return arm_set_dpe_context_handle(tb_fw_cfg_dtb, ctx_handle);
+}
+
+/*
+ * This function reads the initial DPE context handle from TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+
+int arm_get_tb_fw_info(int *ctx_handle)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+	int node, rc;
+
+	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+	assert(tb_fw_config_info != NULL);
+
+	void *dtb = (void *)tb_fw_config_info->config_addr;
+	const char *compatible = "arm,dpe_ctx_handle";
+
+	/* Assert the node offset point to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+	if (node < 0) {
+		WARN("The compatible property '%s'%s", compatible,
+		     " not specified in TB_FW config.\n");
+		return node;
+	}
+
+	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+	rc = fdt_read_uint32(dtb, node, DTB_PROP_DPE_CTX_HANDLE, (uint32_t *)ctx_handle);
+	if (rc != 0) {
+		ERROR("%s%s", DTB_PROP_DPE_CTX_HANDLE,
+		      " not specified in TB_FW config.\n");
+	}
+
+	return rc;
+}
+#else
 /*
  * Write the Event Log address and its size in the DTB.
  *
@@ -393,4 +537,5 @@
 
 	return rc;
 }
+#endif /* DICE_PROTECTION_ENVIRONMENT */
 #endif /* MEASURED_BOOT */
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index c411c6c..2525266 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,10 @@
 #pragma weak plat_get_bl_image_load_info
 #pragma weak plat_get_next_bl_params
 
-static bl_params_t *next_bl_params_cpy_ptr;
+#if TRANSFER_LIST
+static bl_params_t next_bl_params_cpy;
+#endif
+bl_params_t *next_bl_params_cpy_ptr;
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
@@ -96,9 +99,15 @@
  ******************************************************************************/
 struct bl_params *arm_get_next_bl_params(void)
 {
-	bl_mem_params_node_t *bl2_mem_params_descs_cpy
-			= (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
-	const bl_params_t *next_bl_params;
+	bl_mem_params_node_t *bl2_mem_params_descs_cpy __unused;
+	const bl_params_t *next_bl_params __unused;
+
+#if TRANSFER_LIST
+	next_bl_params_cpy_ptr = &next_bl_params_cpy;
+	SET_PARAM_HEAD(next_bl_params_cpy_ptr, PARAM_BL_PARAMS, VERSION_2, 0U);
+#else
+	bl2_mem_params_descs_cpy =
+		(bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
 
 	next_bl_params_cpy_ptr =
 		(bl_params_t *)(ARM_BL2_MEM_DESC_BASE +
@@ -127,6 +136,7 @@
 						(sizeof(bl_params_t)));
 
 	populate_next_bl_params_config(next_bl_params_cpy_ptr);
+#endif /* TRANSFER_LIST */
 
 	return next_bl_params_cpy_ptr;
 }
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 055ab36..498dedf 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,12 +79,8 @@
 	 *  search if the number of entries justify the additional complexity.
 	 */
 	for (i = 0; !!arm_pm_idle_states[i]; i++) {
-#if PSCI_OS_INIT_MODE
 		if ((power_state & ~ARM_LAST_AT_PLVL_MASK) ==
 					arm_pm_idle_states[i])
-#else
-		if (power_state == arm_pm_idle_states[i])
-#endif /* __PSCI_OS_INIT_MODE__ */
 			break;
 	}
 
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 09226f4..18e9381 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,9 +22,11 @@
 
 static int arm_sip_setup(void)
 {
+#if ENABLE_PMF
 	if (pmf_setup() != 0) {
 		return 1;
 	}
+#endif /* ENABLE_PMF */
 
 #if USE_DEBUGFS
 
@@ -60,12 +62,13 @@
 	int call_count = 0;
 
 #if ENABLE_PMF
-
 	/*
 	 * Dispatch PMF calls to PMF SMC handler and return its return
 	 * value
 	 */
-	if (is_pmf_fid(smc_fid)) {
+	if (is_pmf_fid_deprecated(smc_fid)) {
+		NOTICE("PMF Interface usage from arm-sip range is deprecated. \
+			Please migrate smc call to Vendor-specific el3 range.\n");
 		return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
 				handle, flags);
 	}
@@ -73,8 +76,9 @@
 #endif /* ENABLE_PMF */
 
 #if USE_DEBUGFS
-
-	if (is_debugfs_fid(smc_fid)) {
+	if (is_debugfs_fid_deprecated(smc_fid)) {
+		NOTICE("Debugfs Interface usage from arm-sip range is deprecated. \
+			Please migrate smc call to vendor-specific el3 range.\n");
 		return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
 					   handle, flags);
 	}
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
new file mode 100644
index 0000000..d144bbb
--- /dev/null
+++ b/plat/arm/common/arm_transfer_list.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl)
+{
+	struct transfer_list_entry *te;
+	bl_mem_params_node_t *next_param_node =
+		get_bl_mem_params_node(HW_CONFIG_ID);
+	assert(next_param_node != NULL);
+
+	/*
+	 * The HW_CONFIG needs to be authenticated via the normal loading
+	 * mechanism. Pre-allocate a TE for the configuration and update the
+	 * load information so the configuration is loaded directly into the TE.
+	 */
+	te = transfer_list_add(secure_tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE,
+			       NULL);
+	assert(te != NULL);
+
+	next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+	next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE;
+	next_param_node->image_info.image_base =
+		(uintptr_t)transfer_list_entry_data(te);
+}
+
+void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
+					struct transfer_list_header *secure_tl,
+					struct transfer_list_header *ns_tl)
+{
+	uint32_t next_exe_img_id;
+	entry_point_info_t *ep;
+	struct transfer_list_entry *te;
+
+	assert(next_param_node != NULL);
+
+	while ((next_exe_img_id = next_param_node->next_handoff_image_id) !=
+	       INVALID_IMAGE_ID) {
+		next_param_node =
+			&bl_mem_params_desc_ptr[get_bl_params_node_index(
+				next_exe_img_id)];
+		assert(next_param_node != NULL);
+
+		te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64,
+				       sizeof(entry_point_info_t),
+				       &next_param_node->ep_info);
+		assert(te != NULL);
+
+		ep = transfer_list_entry_data(te);
+
+		if (next_exe_img_id == BL33_IMAGE_ID) {
+			ep = transfer_list_set_handoff_args(ns_tl, ep);
+			assert(ep != NULL);
+		} else if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) {
+			/*
+			 * Populate the BL32 image base, size and max limit in
+			 * the entry point information, since there is no
+			 * platform function to retrieve them in generic
+			 * code. We choose arg2, arg3 and arg4 since the generic
+			 * code uses arg1 for stashing the SP manifest size. The
+			 * SPMC setup uses these arguments to update SP manifest
+			 * with actual SP's base address and it size.
+			 */
+			ep->args.arg2 = next_param_node->image_info.image_base;
+			ep->args.arg3 = next_param_node->image_info.image_size;
+			ep->args.arg4 =
+				next_param_node->image_info.image_base +
+				next_param_node->image_info.image_max_size;
+		}
+
+		next_exe_img_id = next_param_node->next_handoff_image_id;
+	}
+
+	flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
+}
+
+void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl,
+				      struct transfer_list_header *ns_tl)
+{
+	struct transfer_list_entry *te =
+		transfer_list_find(secure_tl, TL_TAG_FDT);
+	assert(te != NULL);
+
+	/* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */
+	transfer_list_update_checksum(secure_tl);
+
+	/* Copy the hardware configuration to the non-secure TL. */
+	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
+			       transfer_list_entry_data(te));
+	assert(te != NULL);
+}
diff --git a/plat/arm/common/plat_arm_sip_svc.c b/plat/arm/common/plat_arm_sip_svc.c
index d496d2e..d6341e2 100644
--- a/plat/arm/common/plat_arm_sip_svc.c
+++ b/plat/arm/common/plat_arm_sip_svc.c
@@ -111,11 +111,11 @@
 
 #if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
 	case PLAT_PROTECT_MEM_SMC64:
-		INFO("Sip Call - Protect memory\n");
+		VERBOSE("Sip Call - Protect memory\n");
 		return plat_protect_memory(true, secure_origin, x1, x2, handle);
 		break;
 	case PLAT_UNPROTECT_MEM_SMC64:
-		INFO("Sip Call - Unprotect memory\n");
+		VERBOSE("Sip Call - Unprotect memory\n");
 		return plat_protect_memory(false, secure_origin, x1, x2, handle);
 		break;
 #endif
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index f15c137..4cd514b 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,10 +68,6 @@
 	arm_console_boot_init();
 
 #if RESET_TO_SP_MIN
-	/* There are no parameters from BL2 if SP_MIN is a reset vector */
-	assert(from_bl2 == NULL);
-	assert(plat_params_from_bl2 == NULL);
-
 	/* Populate entry point information for BL33 */
 	SET_PARAM_HEAD(&bl33_image_ep_info,
 				PARAM_EP,
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index bb64e73..db4a169 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -12,6 +12,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/dsu.h>
 #include <lib/cassert.h>
 #include <plat/arm/common/plat_arm.h>
 
@@ -82,8 +83,12 @@
 	 * Perform the common cluster specific operations i.e enable coherency
 	 * if this cluster was off.
 	 */
-	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+#if PRESERVE_DSU_PMU_REGS
+		cluster_on_dsu_pmu_context_restore();
+#endif
 		plat_arm_interconnect_enter_coherency();
+	}
 }
 
 /*******************************************************************************
@@ -131,8 +136,12 @@
 	plat_arm_gic_cpuif_disable();
 
 	/* Cluster is to be turned off, so disable coherency */
-	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+#if PRESERVE_DSU_PMU_REGS
+		cluster_off_dsu_pmu_context_save();
+#endif
 		plat_arm_interconnect_exit_coherency();
+	}
 }
 
 /*******************************************************************************
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
deleted file mode 100644
index 2126a86..0000000
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_BASE_PLATFORM_DEF_H
-#define SGI_BASE_PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables_defs.h>
-#include <plat/arm/common/arm_def.h>
-#include <plat/arm/common/arm_spm_def.h>
-#include <plat/arm/css/common/css_def.h>
-#include <plat/common/common_def.h>
-
-#define PLATFORM_CORE_COUNT		(CSS_SGI_CHIP_COUNT *		\
-					PLAT_ARM_CLUSTER_COUNT *	\
-					CSS_SGI_MAX_CPUS_PER_CLUSTER *	\
-					CSS_SGI_MAX_PE_PER_CPU)
-
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
-
-/* Remote chip address offset */
-#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n)	\
-		((ULL(1) << CSS_SGI_ADDR_BITS_PER_CHIP) * (n))
-
-/*
- * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
- * plat_arm_mmap array defined for each BL stage. In addition to that, on
- * multi-chip platforms, address regions on each of the remote chips are
- * also mapped. In BL31, for instance, three address regions on the remote
- * chips are accessed - secure ram, css device and soc device regions.
- */
-#if defined(IMAGE_BL31)
-# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
-#  define PLAT_ARM_MMAP_ENTRIES		(10  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define MAX_XLAT_TABLES		(8  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define PLAT_SP_IMAGE_MMAP_REGIONS	12
-#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	14
-# else
-#  define PLAT_ARM_MMAP_ENTRIES		(5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define MAX_XLAT_TABLES		(6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-# endif
-#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES		8
-# define MAX_XLAT_TABLES		5
-#elif defined(IMAGE_BL2)
-# define PLAT_ARM_MMAP_ENTRIES		(11 + (CSS_SGI_CHIP_COUNT - 1))
-
-/*
- * MAX_XLAT_TABLES entries need to be doubled because when the address width
- * exceeds 40 bits an additional level of translation is required. In case of
- * multichip platforms peripherals also fall into address space with width
- * > 40 bits
- *
- */
-# define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 2))
-#elif !USE_ROMLIB
-# define PLAT_ARM_MMAP_ENTRIES		11
-# define MAX_XLAT_TABLES		7
-#else
-# define PLAT_ARM_MMAP_ENTRIES		12
-# define MAX_XLAT_TABLES		6
-#endif
-
-/*
- * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
- * plus a little space for growth.
- */
-#define PLAT_ARM_MAX_BL1_RW_SIZE	(64 * 1024)	/* 64 KB */
-
-/*
- * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
- */
-
-#if USE_ROMLIB
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0x1000
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0xe000
-#else
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0
-#endif
-
-/*
- * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth. Additional 8KiB space is added per chip in
- * order to accommodate the additional level of translation required for "TZC"
- * peripheral access which lies in >4TB address space.
- *
- */
-#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		(0x20000 + ((CSS_SGI_CHIP_COUNT - 1) * \
-							0x2000))
-#else
-# define PLAT_ARM_MAX_BL2_SIZE		(0x14000 + ((CSS_SGI_CHIP_COUNT - 1) * \
-							0x2000))
-#endif
-
-/*
- * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
- * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
- * and BL1-RW. CSS_SGI_BL31_SIZE - is tuned with respect to the actual BL31
- * PROGBITS size which is around 64-68KB at the time this change is being made.
- * A buffer of ~35KB is added to account for future expansion of the image,
- * making it a total of 100KB.
- */
-#define CSS_SGI_BL31_SIZE		(116 * 1024)	/* 116 KB */
-#define PLAT_ARM_MAX_BL31_SIZE		(CSS_SGI_BL31_SIZE +		\
-						PLAT_ARM_MAX_BL2_SIZE +	\
-						PLAT_ARM_MAX_BL1_RW_SIZE)
-
-/*
- * Size of cacheable stacks
- */
-#if defined(IMAGE_BL1)
-# if TRUSTED_BOARD_BOOT
-#  define PLATFORM_STACK_SIZE 0x1000
-# else
-#  define PLATFORM_STACK_SIZE 0x440
-# endif
-#elif defined(IMAGE_BL2)
-# if TRUSTED_BOARD_BOOT
-#  define PLATFORM_STACK_SIZE 0x1000
-# else
-#  define PLATFORM_STACK_SIZE 0x400
-# endif
-#elif defined(IMAGE_BL2U)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-# if SPM_MM
-#  define PLATFORM_STACK_SIZE 0x500
-# else
-#  define PLATFORM_STACK_SIZE 0x400
-# endif
-#elif defined(IMAGE_BL32)
-# define PLATFORM_STACK_SIZE 0x440
-#endif
-
-/* PL011 UART related constants */
-#define SOC_CSS_SEC_UART_BASE			UL(0x2A410000)
-#define SOC_CSS_NSEC_UART_BASE			UL(0x2A400000)
-#define SOC_CSS_UART_SIZE			UL(0x10000)
-#define SOC_CSS_UART_CLK_IN_HZ			UL(7372800)
-
-/* UART related constants */
-#define PLAT_ARM_BOOT_UART_BASE			SOC_CSS_SEC_UART_BASE
-#define PLAT_ARM_BOOT_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
-
-#define PLAT_ARM_RUN_UART_BASE			SOC_CSS_SEC_UART_BASE
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
-
-#define PLAT_ARM_CRASH_UART_BASE		SOC_CSS_SEC_UART_BASE
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
-
-#define PLAT_ARM_NSTIMER_FRAME_ID	0
-
-#define PLAT_ARM_TRUSTED_ROM_BASE	0x0
-#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000	/* 512KB */
-
-#define PLAT_ARM_NSRAM_BASE		0x06000000
-#define PLAT_ARM_NSRAM_SIZE		0x00080000	/* 512KB */
-
-#define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
-#define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
-
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
-#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
-
-#define CSS_SGI_DEVICE_BASE	(0x20000000)
-#define CSS_SGI_DEVICE_SIZE	(0x20000000)
-#define CSS_SGI_MAP_DEVICE	MAP_REGION_FLAT(		\
-					CSS_SGI_DEVICE_BASE,	\
-					CSS_SGI_DEVICE_SIZE,	\
-					MT_DEVICE | MT_RW | MT_SECURE)
-
-#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n)					\
-			MAP_REGION_FLAT(					\
-				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
-				ARM_SHARED_RAM_BASE,				\
-				ARM_SHARED_RAM_SIZE,				\
-				MT_NON_CACHEABLE | MT_RW | MT_SECURE		\
-			)
-
-#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n)					\
-			MAP_REGION_FLAT(					\
-				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
-				CSS_SGI_DEVICE_BASE,				\
-				CSS_SGI_DEVICE_SIZE,				\
-				MT_DEVICE | MT_RW | MT_SECURE			\
-			)
-
-#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n)					\
-			MAP_REGION_FLAT(					\
-				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
-				SOC_CSS_DEVICE_BASE,				\
-				SOC_CSS_DEVICE_SIZE,				\
-				MT_DEVICE | MT_RW | MT_SECURE			\
-			)
-
-/* Map the secure region for access from S-EL0 */
-#define PLAT_ARM_SECURE_MAP_DEVICE	MAP_REGION_FLAT(	\
-					SOC_CSS_DEVICE_BASE,	\
-					SOC_CSS_DEVICE_SIZE,	\
-					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
-
-#if ENABLE_FEAT_RAS && FFH_SUPPORT
-#define PLAT_SP_PRI				PLAT_RAS_PRI
-#else
-#define PLAT_SP_PRI				0x10
-#endif
-
-#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && ENABLE_FEAT_RAS && FFH_SUPPORT
-/*
- * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
- * memory shared between EL3 and S-EL0.
- */
-#define CSS_SGI_SP_CPER_BUF_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE + \
-					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#define CSS_SGI_SP_CPER_BUF_SIZE	ULL(0x10000)
-#define CSS_SGI_SP_CPER_BUF_MMAP	MAP_REGION2(			       \
-						CSS_SGI_SP_CPER_BUF_BASE,      \
-						CSS_SGI_SP_CPER_BUF_BASE,      \
-						CSS_SGI_SP_CPER_BUF_SIZE,      \
-						MT_RW_DATA | MT_NS | MT_USER,  \
-						PAGE_SIZE)
-
-/*
- * Secure partition stack follows right after the memory space reserved for
- * CPER buffer memory.
- */
-#define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE +   \
-						 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
-						 CSS_SGI_SP_CPER_BUF_SIZE)
-#elif (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
-/*
- * Secure partition stack follows right after the memory region that is shared
- * between EL3 and S-EL0.
- */
-#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
-					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
-
-/* Platform ID address */
-#define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
-#ifndef __ASSEMBLER__
-/* SSC_VERSION related accessors */
-/* Returns the part number of the platform */
-#define GET_SGI_PART_NUM                                       \
-		GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
-/* Returns the configuration number of the platform */
-#define GET_SGI_CONFIG_NUM                                     \
-		GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
-#endif /* __ASSEMBLER__ */
-
-/*******************************************************************************
- * Memprotect definitions
- ******************************************************************************/
-/* PSCI memory protect definitions:
- * This variable is stored in a non-secure flash because some ARM reference
- * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
- * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
- */
-#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
-					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-/*Secure Watchdog Constants */
-#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
-#define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
-
-/* Number of SCMI channels on the platform */
-#define PLAT_ARM_SCMI_CHANNEL_COUNT	CSS_SGI_CHIP_COUNT
-
-/*
- * Mapping definition of the TrustZone Controller for ARM SGI/RD platforms
- * where both the DRAM regions are marked for non-secure access. This applies
- * to multi-chip platforms.
- */
-#define SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(n)				\
-	{CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
-		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,	\
-		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
-	{CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
-		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,	\
-		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
-
-#if SPM_MM
-
-/*
- * Stand-alone MM logs would be routed via secure UART. Define page table
- * entry for secure UART which would be common to all platforms.
- */
-#define SOC_PLATFORM_SECURE_UART	MAP_REGION_FLAT(		\
-					SOC_CSS_SEC_UART_BASE,		\
-					SOC_CSS_UART_SIZE,		\
-					MT_DEVICE | MT_RW | 		\
-					MT_SECURE | MT_USER)
-
-#endif
-
-/* Index of SDS region used in the communication with SCP */
-#define SDS_SCP_AP_REGION_ID			U(0)
-/* SDS ID for unusable CPU MPID list structure */
-#define SDS_ISOLATED_CPU_LIST_ID		U(128)
-
-#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h
deleted file mode 100644
index a5fbded..0000000
--- a/plat/arm/css/sgi/include/sgi_plat.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_PLAT_H
-#define SGI_PLAT_H
-
-/* BL31 platform setup common to all SGI based platforms */
-void sgi_bl31_common_platform_setup(void);
-
-#endif /* SGI_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_sdei.h b/plat/arm/css/sgi/include/sgi_sdei.h
deleted file mode 100644
index f380122..0000000
--- a/plat/arm/css/sgi/include/sgi_sdei.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SDEI_H
-#define SGI_SDEI_H
-
-#if SDEI_SUPPORT
-
-/* ARM SDEI dynamic shared event numbers */
-#define SGI_SDEI_DS_EVENT_0		U(804)
-#define SGI_SDEI_DS_EVENT_1		U(805)
-
-#define PLAT_ARM_PRIVATE_SDEI_EVENTS					      \
-		SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),			      \
-		SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
-		SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
-
-#define PLAT_ARM_SHARED_SDEI_EVENTS
-
-#endif /* SDEI_SUPPORT */
-
-#endif /* SGI_SDEI_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def.h b/plat/arm/css/sgi/include/sgi_soc_css_def.h
deleted file mode 100644
index f78b45a..0000000
--- a/plat/arm/css/sgi/include/sgi_soc_css_def.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_CSS_DEF_H
-#define SGI_SOC_CSS_DEF_H
-
-#include <lib/utils_def.h>
-#include <plat/arm/board/common/v2m_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <plat/common/common_def.h>
-
-/*
- * Definitions common to all ARM CSSv1-based development platforms
- */
-
-/* Platform ID address */
-#define BOARD_CSS_PLAT_ID_REG_ADDR		UL(0x7ffe00e0)
-
-/* Platform ID related accessors */
-#define BOARD_CSS_PLAT_ID_REG_ID_MASK		0x0f
-#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		0x0
-#define BOARD_CSS_PLAT_TYPE_EMULATOR		0x02
-
-#ifndef __ASSEMBLER__
-
-#include <lib/mmio.h>
-
-#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
-	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
-	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
-
-#endif /* __ASSEMBLER__ */
-
-#define MAX_IO_DEVICES			3
-#define MAX_IO_HANDLES			4
-
-/* Reserve the last block of flash for PSCI MEM PROTECT flag */
-#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
-#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
-#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#endif /* SGI_SOC_CSS_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
deleted file mode 100644
index d659ae5..0000000
--- a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_CSS_DEF_V2_H
-#define SGI_SOC_CSS_DEF_V2_H
-
-#include <lib/utils_def.h>
-#include <plat/common/common_def.h>
-
-/*
- * Definitions common to all ARM CSS SoCs
- */
-
-/* Following covers ARM CSS SoC Peripherals */
-
-#define SOC_SYSTEM_PERIPH_BASE		UL(0x0C000000)
-#define SOC_SYSTEM_PERIPH_SIZE		UL(0x02000000)
-
-#define SOC_PLATFORM_PERIPH_BASE	UL(0x0E000000)
-#define SOC_PLATFORM_PERIPH_SIZE	UL(0x02000000)
-
-#define SOC_CSS_PCIE_CONTROL_BASE	UL(0x0ef20000)
-
-/* Memory controller */
-#define SOC_MEMCNTRL_BASE		UL(0x10000000)
-#define SOC_MEMCNTRL_SIZE		UL(0x10000000)
-
-/* SoC NIC-400 Global Programmers View (GPV) */
-#define SOC_CSS_NIC400_BASE		UL(0x0ED00000)
-
-#define SOC_CSS_NIC400_USB_EHCI		U(0)
-#define SOC_CSS_NIC400_TLX_MASTER	U(1)
-#define SOC_CSS_NIC400_USB_OHCI		U(2)
-#define SOC_CSS_NIC400_PL354_SMC	U(3)
-/*
- * The apb4_bridge controls access to:
- *   - the PCIe configuration registers
- *   - the MMU units for USB, HDLCD and DMA
- */
-#define SOC_CSS_NIC400_APB4_BRIDGE	U(4)
-
-/* Non-volatile counters */
-#define SOC_TRUSTED_NVCTR_BASE		UL(0x0EE70000)
-#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0000)
-#define TFW_NVCTR_SIZE			U(4)
-#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
-#define NTFW_CTR_SIZE			U(4)
-
-/* Keys */
-#define SOC_KEYS_BASE			UL(0x0EE80000)
-#define TZ_PUB_KEY_HASH_BASE		(SOC_KEYS_BASE + 0x0000)
-#define TZ_PUB_KEY_HASH_SIZE		U(32)
-#define HU_KEY_BASE			(SOC_KEYS_BASE + 0x0020)
-#define HU_KEY_SIZE			U(16)
-#define END_KEY_BASE			(SOC_KEYS_BASE + 0x0044)
-#define END_KEY_SIZE			U(32)
-
-/* Base Element RAM error definitions */
-#define SOC_NS_RAM_ERR_REC_BASE		UL(0x2A4C0000)
-#define NS_RAM_ECC_CE_INT		U(87)
-#define NS_RAM_ECC_UE_INT		U(88)
-
-#define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
-						SOC_PLATFORM_PERIPH_BASE, 	\
-						SOC_PLATFORM_PERIPH_SIZE, 	\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#if SPM_MM
-/*
- * Memory map definition for the platform peripheral memory region that is
- * accessible from S-EL0 (with secure user mode access).
- */
-#define SOC_PLATFORM_PERIPH_MAP_DEVICE_USER				       \
-		MAP_REGION_FLAT(					       \
-			SOC_PLATFORM_PERIPH_BASE,			       \
-			SOC_PLATFORM_PERIPH_SIZE,			       \
-			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
-#endif
-
-#define SOC_SYSTEM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
-						SOC_SYSTEM_PERIPH_BASE,		\
-						SOC_SYSTEM_PERIPH_SIZE,		\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define SOC_MEMCNTRL_MAP_DEVICE		MAP_REGION_FLAT(			\
-						SOC_MEMCNTRL_BASE,		\
-						SOC_MEMCNTRL_SIZE,		\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(n)					\
-		MAP_REGION_FLAT(						\
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + SOC_MEMCNTRL_BASE,	\
-			SOC_MEMCNTRL_SIZE,					\
-			MT_DEVICE | MT_RW | MT_SECURE)
-
-/*
- * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
- */
-#define SOC_CSS_NIC400_BOOTSEC_BRIDGE		U(5)
-#define SOC_CSS_NIC400_BOOTSEC_BRIDGE_UART1	UL(1 << 12)
-
-/*
- * Required platform porting definitions common to all ARM CSS SoCs
- */
-/* 2MB used for SCP DDR retraining */
-#define PLAT_ARM_SCP_TZC_DRAM1_SIZE	UL(0x00200000)
-
-/* V2M motherboard system registers & offsets */
-#define V2M_SYSREGS_BASE		UL(0x0C010000)
-#define V2M_SYS_LED			U(0x8)
-
-/*
- * V2M sysled bit definitions. The values written to this
- * register are defined in arch.h & runtime_svc.h. Only
- * used by the primary cpu to diagnose any cold boot issues.
- *
- * SYS_LED[0]   - Security state (S=0/NS=1)
- * SYS_LED[2:1] - Exception Level (EL3-EL0)
- * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
- *
- */
-#define V2M_SYS_LED_SS_SHIFT		U(0)
-#define V2M_SYS_LED_EL_SHIFT		U(1)
-#define V2M_SYS_LED_EC_SHIFT		U(3)
-
-#define V2M_SYS_LED_SS_MASK		U(0x01)
-#define V2M_SYS_LED_EL_MASK		U(0x03)
-#define V2M_SYS_LED_EC_MASK		U(0x1f)
-
-/* NOR Flash */
-#define V2M_FLASH0_BASE			UL(0x08000000)
-#define V2M_FLASH0_SIZE			UL(0x04000000)
-#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
-
-/*
- * The flash can be mapped either as read-only or read-write.
- *
- * If it is read-write then it should also be mapped as device memory because
- * NOR flash programming involves sending a fixed, ordered sequence of commands.
- *
- * If it is read-only then it should also be mapped as:
- * - Normal memory, because reading from NOR flash is transparent, it is like
- *   reading from RAM.
- * - Non-executable by default. If some parts of the flash need to be executable
- *   then platform code is responsible for re-mapping the appropriate portion
- *   of it as executable.
- */
-#define V2M_MAP_FLASH0_RW		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define V2M_MAP_FLASH0_RO		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_RO_DATA | MT_SECURE)
-
-#define SGI_MAP_FLASH0_RO		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_DEVICE | MT_RO | MT_SECURE)
-
-/* Platform ID address */
-#define BOARD_CSS_PLAT_ID_REG_ADDR		UL(0x0EFE00E0)
-
-/* Platform ID related accessors */
-#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
-#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
-#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
-#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
-#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
-#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
-#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
-#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
-
-#ifndef __ASSEMBLER__
-
-#include <lib/mmio.h>
-
-#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
-	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
-	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
-
-#endif /* __ASSEMBLER__ */
-
-
-#define MAX_IO_DEVICES			U(3)
-#define MAX_IO_HANDLES			U(4)
-
-/* Reserve the last block of flash for PSCI MEM PROTECT flag */
-#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
-#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#if ARM_GPT_SUPPORT
-/*
- * Offset of the FIP in the GPT image. BL1 component uses this option
- * as it does not load the partition table to get the FIP base
- * address. At sector 34 by default (i.e. after reserved sectors 0-33)
- * Offset = 34 * 512(sector size) = 17408 i.e. 0x4400
- */
-#define PLAT_ARM_FIP_OFFSET_IN_GPT		0x4400
-#endif /* ARM_GPT_SUPPORT */
-
-#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
-#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#endif /* SGI_SOC_CSS_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
deleted file mode 100644
index 3b8d9c6..0000000
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_PLATFORM_DEF_H
-#define SGI_SOC_PLATFORM_DEF_H
-
-#include <plat/arm/board/common/v2m_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <sgi_base_platform_def.h>
-#include <sgi_soc_css_def.h>
-
-/* Map the System registers to access from S-EL0 */
-#define CSS_SYSTEMREG_DEVICE_BASE	(0x1C010000)
-#define CSS_SYSTEMREG_DEVICE_SIZE	(0x00010000)
-#define PLAT_ARM_SECURE_MAP_SYSTEMREG	MAP_REGION_FLAT(		    \
-						CSS_SYSTEMREG_DEVICE_BASE,  \
-						CSS_SYSTEMREG_DEVICE_SIZE,  \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-/* Map the NOR2 Flash to access from S-EL0 */
-#define CSS_NOR2_FLASH_DEVICE_BASE	(0x10000000)
-#define CSS_NOR2_FLASH_DEVICE_SIZE	(0x04000000)
-#define PLAT_ARM_SECURE_MAP_NOR2	MAP_REGION_FLAT(                    \
-						CSS_NOR2_FLASH_DEVICE_BASE, \
-						CSS_NOR2_FLASH_DEVICE_SIZE, \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-#endif /* SGI_SOC_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
deleted file mode 100644
index 20dd682..0000000
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_PLATFORM_DEF_V2_H
-#define SGI_SOC_PLATFORM_DEF_V2_H
-
-#include <sgi_base_platform_def.h>
-#include <sgi_soc_css_def_v2.h>
-
-/* Map the System registers to access from S-EL0 */
-#define CSS_SYSTEMREG_DEVICE_BASE	(0x0C010000)
-#define CSS_SYSTEMREG_DEVICE_SIZE	(0x00010000)
-#define PLAT_ARM_SECURE_MAP_SYSTEMREG	MAP_REGION_FLAT(                    \
-						CSS_SYSTEMREG_DEVICE_BASE,  \
-						CSS_SYSTEMREG_DEVICE_SIZE,  \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-/* Map the NOR2 Flash to access from S-EL0 */
-#define CSS_NOR2_FLASH_DEVICE_BASE	(0x001054000000)
-#define CSS_NOR2_FLASH_DEVICE_SIZE	(0x000004000000)
-#define PLAT_ARM_SECURE_MAP_NOR2	MAP_REGION_FLAT(                    \
-						CSS_NOR2_FLASH_DEVICE_BASE, \
-						CSS_NOR2_FLASH_DEVICE_SIZE, \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-#endif /* SGI_SOC_PLATFORM_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
deleted file mode 100644
index 8f9529a..0000000
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_VARIANT_H
-#define SGI_VARIANT_H
-
-/* SSC_VERSION values for SGI575 */
-#define SGI575_SSC_VER_PART_NUM			0x0783
-
-/* SID Version values for RD-N1E1-Edge */
-#define RD_N1E1_EDGE_SID_VER_PART_NUM		0x0786
-#define RD_E1_EDGE_CONFIG_ID			0x2
-
-/* SID Version values for RD-V1 */
-#define RD_V1_SID_VER_PART_NUM			0x078a
-
-/* SID Version values for RD-N2 */
-#define RD_N2_SID_VER_PART_NUM			0x07B7
-
-/* SID Version values for RD-N2 variants */
-#define RD_N2_CFG1_SID_VER_PART_NUM		0x07B6
-#define RD_N2_CFG3_SID_VER_PART_NUM		0x07F1
-
-/* SID Version values for RD-V2 */
-#define RD_V2_SID_VER_PART_NUM			0x07F2
-#define RD_V2_CONFIG_ID				0x1
-
-/* Structure containing SGI platform variant information */
-typedef struct sgi_platform_info {
-	unsigned int platform_id;	/* Part Number of the platform */
-	unsigned int config_id;		/* Config Id of the platform */
-	unsigned int chip_id;		/* Chip Id or Node number */
-	unsigned int multi_chip_mode;	/* Multi-chip mode availability */
-} sgi_platform_info_t;
-
-extern sgi_platform_info_t sgi_plat_info;
-
-/* returns the part number of the platform*/
-unsigned int plat_arm_sgi_get_platform_id(void);
-
-/* returns the configuration id of the platform */
-unsigned int plat_arm_sgi_get_config_id(void);
-
-/* returns true if operating in multi-chip configuration */
-unsigned int plat_arm_sgi_get_multi_chip_mode(void);
-
-#endif /* SGI_VARIANT_H */
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
deleted file mode 100644
index ac1ea48..0000000
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <libfdt.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/css/css_mhu_doorbell.h>
-#include <drivers/arm/css/scmi.h>
-#include <drivers/generic_delay_timer.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <plat/common/platform.h>
-
-#include <plat/arm/css/common/css_pm.h>
-
-#include <sgi_ras.h>
-#include <sgi_variant.h>
-
-sgi_platform_info_t sgi_plat_info;
-
-static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhu_ring_doorbell,
-};
-
-static scmi_channel_plat_info_t plat_rd_scmi_info[] = {
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#if (CSS_SGI_CHIP_COUNT > 1)
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
-		.db_reg_addr = PLAT_CSS_MHU_BASE
-			+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#endif
-	#if (CSS_SGI_CHIP_COUNT > 2)
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
-		.db_reg_addr = PLAT_CSS_MHU_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#endif
-	#if (CSS_SGI_CHIP_COUNT > 3)
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
-		.db_reg_addr = PLAT_CSS_MHU_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#endif
-};
-
-scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
-{
-	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_CFG3_SID_VER_PART_NUM) {
-		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
-			panic();
-		return &plat_rd_scmi_info[channel_id];
-	}
-	else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
-		return &sgi575_scmi_plat_info;
-	else
-		panic();
-}
-
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
-				u_register_t arg2, u_register_t arg3)
-{
-	sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id();
-	sgi_plat_info.config_id = plat_arm_sgi_get_config_id();
-	sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode();
-
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-}
-
-void sgi_bl31_common_platform_setup(void)
-{
-	generic_delay_timer_init();
-
-	arm_bl31_platform_setup();
-
-	/* Configure the warm reboot SGI for primary core */
-	css_setup_cpu_pwr_down_intr();
-
-#if CSS_SYSTEM_GRACEFUL_RESET
-	/* Register priority level handlers for reboot */
-	ehf_register_priority_handler(PLAT_REBOOT_PRI,
-			css_reboot_interrupt_handler);
-#endif
-}
-
-const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
-{
-	/*
-	 * For RD-E1-Edge, only CPU power ON/OFF, PSCI platform callbacks are
-	 * supported.
-	 */
-	if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
-	    (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID))) {
-		ops->cpu_standby = NULL;
-		ops->system_off = NULL;
-		ops->system_reset = NULL;
-		ops->get_sys_suspend_power_state = NULL;
-		ops->pwr_domain_suspend = NULL;
-		ops->pwr_domain_suspend_finish = NULL;
-	}
-
-	return css_scmi_override_pm_ops(ops);
-}
diff --git a/plat/aspeed/ast2700/include/platform_def.h b/plat/aspeed/ast2700/include/platform_def.h
index 8be26c3..e668115 100644
--- a/plat/aspeed/ast2700/include/platform_def.h
+++ b/plat/aspeed/ast2700/include/platform_def.h
@@ -21,9 +21,6 @@
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
 					 PLATFORM_CORE_COUNT_PER_CLUSTER)
 
-/* arch timer */
-#define PLAT_SYSCNT_CLKIN_HZ		U(1600000000)
-
 /* power domain */
 #define PLAT_MAX_PWR_LVL		U(1)
 #define PLAT_NUM_PWR_DOMAINS		U(5)
@@ -55,4 +52,12 @@
 #define CONSOLE_UART_CLKIN_HZ		U(1846153)
 #define CONSOLE_UART_BAUDRATE		U(115200)
 
+/* CLK information */
+#define CLKIN_25M			UL(25000000)
+
+#define PLAT_CLK_GATE_NUM		U(29)
+#define PLAT_CLK_HPLL			(PLAT_CLK_GATE_NUM + 5)
+#define PLAT_CLK_DPLL			(PLAT_CLK_GATE_NUM + 6)
+#define PLAT_CLK_MPLL			(PLAT_CLK_GATE_NUM + 7)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/aspeed/ast2700/include/platform_reg.h b/plat/aspeed/ast2700/include/platform_reg.h
index 7f26865..3c164a4 100644
--- a/plat/aspeed/ast2700/include/platform_reg.h
+++ b/plat/aspeed/ast2700/include/platform_reg.h
@@ -19,6 +19,10 @@
 
 /* CPU-die SCU */
 #define SCU_CPU_BASE	U(0x12c02000)
+#define SCU_CPU_HW_STRAP1	(SCU_CPU_BASE + 0x010)
+#define SCU_CPU_HPLL	(SCU_CPU_BASE + 0x300)
+#define SCU_CPU_DPLL	(SCU_CPU_BASE + 0x308)
+#define SCU_CPU_MPLL	(SCU_CPU_BASE + 0x310)
 #define SCU_CPU_SMP_EP0	(SCU_CPU_BASE + 0x780)
 #define SCU_CPU_SMP_EP1	(SCU_CPU_BASE + 0x788)
 #define SCU_CPU_SMP_EP2	(SCU_CPU_BASE + 0x790)
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index 92a48ff..9fec3e8 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
 #include <arch.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
@@ -112,3 +113,90 @@
 
 	return ep_info;
 }
+
+/*
+ * Clock divider/multiplier configuration struct.
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ *
+ */
+union plat_pll_reg {
+	uint32_t w;
+	struct {
+		uint16_t m : 13;		/* bit[12:0]	*/
+		uint8_t n : 6;			/* bit[18:13]	*/
+		uint8_t p : 4;			/* bit[22:19]	*/
+		uint8_t off : 1;		/* bit[23]	*/
+		uint8_t bypass : 1;		/* bit[24]	*/
+		uint8_t reset : 1;		/* bit[25]	*/
+		uint8_t reserved : 6;		/* bit[31:26]	*/
+	} b;
+};
+
+static uint32_t plat_get_pll_rate(int pll_idx)
+{
+	union plat_pll_reg pll_reg;
+	uint32_t mul = 1, div = 1;
+	uint32_t rate = 0;
+
+	switch (pll_idx) {
+	case PLAT_CLK_HPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_HPLL);
+		break;
+	case PLAT_CLK_DPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_DPLL);
+		break;
+	case PLAT_CLK_MPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_MPLL);
+		break;
+	default:
+		ERROR("%s: invalid PSP clock source (%d)\n", __func__, pll_idx);
+		return -EINVAL;
+	}
+
+	if (pll_idx == PLAT_CLK_HPLL && ((mmio_read_32(SCU_CPU_HW_STRAP1) & GENMASK(3, 2)) != 0U)) {
+		switch ((mmio_read_32(SCU_CPU_HW_STRAP1) & GENMASK(3, 2)) >> 2) {
+		case 1U:
+			rate = 1900000000;
+			break;
+		case 2U:
+			rate = 1800000000;
+			break;
+		case 3U:
+			rate = 1700000000;
+			break;
+		default:
+			rate = 2000000000;
+			break;
+		}
+	} else {
+		if (pll_reg.b.bypass != 0U) {
+			if (pll_idx == PLAT_CLK_MPLL) {
+				/* F = 25Mhz * [M / (n + 1)] / (p + 1) */
+				mul = (pll_reg.b.m) / ((pll_reg.b.n + 1));
+				div = (pll_reg.b.p + 1);
+			} else {
+				/* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+				mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+				div = (pll_reg.b.p + 1);
+			}
+		}
+
+		rate = ((CLKIN_25M * mul) / div);
+	}
+
+	return rate;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	if (mmio_read_32(SCU_CPU_HW_STRAP1) & BIT(4)) {
+		return plat_get_pll_rate(PLAT_CLK_HPLL);
+	} else {
+		return plat_get_pll_rate(PLAT_CLK_MPLL);
+	}
+}
diff --git a/plat/aspeed/ast2700/plat_helpers.S b/plat/aspeed/ast2700/plat_helpers.S
index c6d987e..e4a283c 100644
--- a/plat/aspeed/ast2700/plat_helpers.S
+++ b/plat/aspeed/ast2700/plat_helpers.S
@@ -59,12 +59,6 @@
 	br	x0
 endfunc plat_secondary_cold_boot_setup
 
-/* unsigned int plat_get_syscnt_freq2(void); */
-func plat_get_syscnt_freq2
-	mov_imm	w0, PLAT_SYSCNT_CLKIN_HZ
-	ret
-endfunc plat_get_syscnt_freq2
-
 /* int plat_crash_console_init(void); */
 func plat_crash_console_init
 	mov_imm	x0, CONSOLE_UART_BASE
diff --git a/plat/brcm/common/brcm_bl31_setup.c b/plat/brcm/common/brcm_bl31_setup.c
index d3fa83d..6eef1d4 100644
--- a/plat/brcm/common/brcm_bl31_setup.c
+++ b/plat/brcm/common/brcm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -235,8 +235,6 @@
  ******************************************************************************/
 void brcm_bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
 	/* Initialize the runtime console */
 	bcm_console_runtime_init();
 }
diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c
index 2c1a8fa..8979171 100644
--- a/plat/common/aarch32/plat_common.c
+++ b/plat/common/aarch32/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,14 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+	plat_try_img_ops = plat_try_ops;
+}
+
 /*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that may be re-used by multiple
@@ -14,7 +22,6 @@
  */
 #pragma weak bl32_plat_enable_mmu
 
-
 void bl32_plat_enable_mmu(uint32_t flags)
 {
 	enable_mmu_svc_mon(flags);
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
index 75b4208..1a50091 100644
--- a/plat/common/aarch64/crash_console_helpers.S
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -100,7 +100,7 @@
 	 * int plat_crash_console_putc(char c)
 	 * Prints the character on all consoles registered with the console
 	 * framework that have CONSOLE_FLAG_CRASH set. Note that this is only
-	 * helpful for crashes that occur after the platform intialization code
+	 * helpful for crashes that occur after the platform initialization code
 	 * has registered a console. Platforms using this implementation need to
 	 * ensure that all console drivers they use that have the CRASH flag set
 	 * support this (i.e. are written in assembly and comply to the register
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index ab99b15..7a228b9 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,14 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+	plat_try_img_ops = plat_try_ops;
+}
+
 /*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that may be re-used by multiple
@@ -35,7 +43,6 @@
 
 void bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -71,12 +78,19 @@
 
 const char *get_el_str(unsigned int el)
 {
-	if (el == MODE_EL3) {
+	switch (el) {
+	case MODE_EL3:
 		return "EL3";
-	} else if (el == MODE_EL2) {
+	case MODE_EL2:
 		return "EL2";
+	case MODE_EL1:
+		return "EL1";
+	case MODE_EL0:
+		return "EL0";
+	default:
+		assert(false);
+		return NULL;
 	}
-	return "EL1";
 }
 
 #if FFH_SUPPORT
diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c
index bcf9f89..ff0e082 100644
--- a/plat/common/plat_bl1_common.c
+++ b/plat/common/plat_bl1_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,10 +80,8 @@
  */
 int bl1_plat_handle_post_image_load(unsigned int image_id)
 {
-	meminfo_t *bl2_secram_layout;
-	meminfo_t *bl1_secram_layout;
+	meminfo_t *bl1_tzram_layout;
 	image_desc_t *image_desc;
-	entry_point_info_t *ep_info;
 
 	if (image_id != BL2_IMAGE_ID)
 		return 0;
@@ -92,26 +90,41 @@
 	image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
 	assert(image_desc != NULL);
 
-	/* Get the entry point info */
-	ep_info = &image_desc->ep_info;
-
 	/* Find out how much free trusted ram remains after BL1 load */
-	bl1_secram_layout = bl1_plat_sec_mem_layout();
+	bl1_tzram_layout = bl1_plat_sec_mem_layout();
 
 	/*
-	 * Create a new layout of memory for BL2 as seen by BL1 i.e.
-	 * tell it the amount of total and free memory available.
-	 * This layout is created at the first free address visible
-	 * to BL2. BL2 will read the memory layout before using its
-	 * memory for other purposes.
+	 * Convey this information to BL2 by storing the layout at the first free
+	 * address visible to BL2.
 	 */
-	bl2_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
+	bl1_plat_calc_bl2_layout(bl1_tzram_layout,
+				 (meminfo_t *)bl1_tzram_layout->total_base);
 
-	bl1_calc_bl2_mem_layout(bl1_secram_layout, bl2_secram_layout);
-
-	ep_info->args.arg1 = (uintptr_t)bl2_secram_layout;
+	image_desc->ep_info.args.arg1 = (uintptr_t)bl1_tzram_layout->total_base;
 
 	VERBOSE("BL1: BL2 memory layout address = %p\n",
-		(void *) bl2_secram_layout);
+		(void *)image_desc->ep_info.args.arg1);
+
 	return 0;
 }
+
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+void bl1_plat_calc_bl2_layout(const meminfo_t *bl1_mem_layout,
+			      meminfo_t *bl2_mem_layout)
+{
+	assert(bl1_mem_layout != NULL);
+	assert(bl2_mem_layout != NULL);
+
+	/*
+	 * Remove BL1 RW data from the scope of memory visible to BL2.
+	 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
+	 */
+	assert(BL1_RW_BASE > bl1_mem_layout->total_base);
+	bl2_mem_layout->total_base = bl1_mem_layout->total_base;
+	bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
+
+	flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
+}
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 89b77ba..a603f2b 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,6 @@
 #pragma weak bl2_plat_preload_setup
 #pragma weak bl2_plat_handle_pre_image_load
 #pragma weak bl2_plat_handle_post_image_load
-#pragma weak plat_try_next_boot_source
 #pragma weak plat_get_enc_key_info
 #pragma weak plat_is_smccc_feature_available
 #pragma weak plat_get_soc_version
@@ -69,11 +68,6 @@
 	return 0;
 }
 
-int plat_try_next_boot_source(void)
-{
-	return 0;
-}
-
 /*
  * Weak implementation to provide dummy decryption key only for test purposes,
  * platforms must override this API for any real world firmware encryption
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index baa70e0..d0c7a31 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -344,6 +344,11 @@
 	return gicv3_set_pmr(mask);
 }
 
+unsigned int plat_ic_deactivate_priority(unsigned int mask)
+{
+	return gicv3_deactivate_priority(mask);
+}
+
 unsigned int plat_ic_get_interrupt_id(unsigned int raw)
 {
 	unsigned int id = raw & INT_ID_MASK;
diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c
index 7d008e7..55b425c 100644
--- a/plat/hisilicon/hikey/hikey_bl31_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -149,7 +149,3 @@
 	hisi_ipc_init();
 	hisi_pwrc_setup();
 }
-
-void bl31_plat_runtime_setup(void)
-{
-}
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 807a915..63eca37 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -153,12 +153,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 159eee9..6e80347 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index fd11a4d..c2c3122 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -146,12 +146,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index fe60ddc..5f4a18a 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -118,11 +118,6 @@
 	hisi_tzpc_sec_init();
 }
 
-void bl31_plat_runtime_setup(void)
-{
-	/* do nothing */
-}
-
 void bl31_plat_arch_setup(void)
 {
 	plat_configure_mmu_el3(BL31_BASE,
diff --git a/plat/imx/common/imx8_helpers.S b/plat/imx/common/imx8_helpers.S
index 19293bf..eb93833 100644
--- a/plat/imx/common/imx8_helpers.S
+++ b/plat/imx/common/imx8_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -86,6 +86,51 @@
 	ret
 endfunc plat_calc_core_pos
 
+	/* ----------------------------------------------
+	 * function to handle platform specific reset.
+	 * ----------------------------------------------
+	 */
+func plat_reset_handler
+#if defined(PLAT_imx8ulp)
+	/* enable the 512KB cache by default */
+	mov	x0, #IMX_SIM1_BASE
+	/*
+	 * if the RVBADDR is ROM entry, that means we did
+	 * NOT switch the L2 cache to 512KB. default is 256K config,
+	 * so skip
+	 */
+	ldr	w1, [x0, #0x5c]
+	cmp	w1, #0x1000
+	b.eq	1f
+	add	x0, x0, #0x30
+	ldr	w1, [x0]
+	/* if already 512KB config, skip */
+	tbnz	w1, #4, 1f
+	ldr	w1, [x0]
+	orr	w1, w1, #0x10
+	str	w1, [x0]
+	orr	w1, w1, #0x10000
+	str	w1, [x0]
+	b	.
+1:	mrs	x0, CORTEX_A35_CPUECTLR_EL1
+	orr     x0, x0, #(0x1 << 0)
+	orr     x0, x0, #(0x1 << 3)
+	msr	CORTEX_A35_CPUECTLR_EL1, x0
+
+	mrs	x0, CORTEX_A35_L2ECTLR_EL1
+	orr     x0, x0, #(0x1 << 0)
+	msr	CORTEX_A35_L2ECTLR_EL1, x0
+	isb
+#endif
+	/* enable EL2 cpuectlr RW access */
+	mov	x0, #0x73
+	msr	actlr_el3, x0
+	msr	actlr_el2, x0
+	isb
+
+	ret
+endfunc plat_reset_handler
+
 	/* ---------------------------------------------
 	 * function to get the entrypoint.
 	 * ---------------------------------------------
diff --git a/plat/imx/common/imx_bl31_common.c b/plat/imx/common/imx_bl31_common.c
new file mode 100644
index 0000000..f6d7e24
--- /dev/null
+++ b/plat/imx/common/imx_bl31_common.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <imx_plat_common.h>
+
+uint32_t plat_get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned long mode;
+	uint32_t spsr;
+
+	/* figure out what mode we enter the non-secure world */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
diff --git a/plat/imx/common/imx_common.c b/plat/imx/common/imx_common.c
new file mode 100644
index 0000000..01f354a
--- /dev/null
+++ b/plat/imx/common/imx_common.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024, Pengutronix, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+
+#include <plat_common.h>
+
+/*
+ * This function checks if @arg0 can safely be accessed as a pointer
+ * and if it does, it fills in @bl32_info and @bl33_info with data
+ * found in @arg0.
+ *
+ * Returns 0 when @arg0 can be used as entry point info and a negative
+ * error code otherwise.
+ */
+int imx_bl31_params_parse(uintptr_t arg0, uintptr_t ocram_base,
+			  uintptr_t ocram_size,
+			  entry_point_info_t *bl32_info,
+			  entry_point_info_t *bl33_info)
+{
+	bl_params_t *v2 = (void *)(uintptr_t)arg0;
+
+	if (arg0 & 0x3) {
+		return -EINVAL;
+	}
+
+	if (arg0 < ocram_base || arg0 >= ocram_base + ocram_size) {
+		return -EINVAL;
+	}
+
+	if (v2->h.version != PARAM_VERSION_2) {
+		return -EINVAL;
+	}
+
+	if (v2->h.type != PARAM_BL_PARAMS) {
+		return -EINVAL;
+	}
+
+	bl31_params_parse_helper(arg0, bl32_info, bl33_info);
+
+	return 0;
+}
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index f830b64..49fdacf 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -9,9 +9,10 @@
 #include <stdint.h>
 #include <services/std_svc.h>
 #include <string.h>
-#include <platform_def.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <platform_def.h>
 #include <imx_sip_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/mmio.h>
@@ -261,7 +262,7 @@
 		    u_register_t x4)
 {
 	/* Parse the version_string */
-	char *parse = (char *)version_string;
+	char *parse = (char *)build_version_string;
 	uint64_t hash = 0;
 
 	do {
@@ -332,3 +333,16 @@
 
 	return 0;
 }
+
+#if defined(PLAT_imx8ulp)
+int imx_hifi_xrdc(uint32_t smc_fid)
+{
+	mmio_setbits_32(IMX_SIM2_BASE + 0x8, BIT_32(19) | BIT_32(17) | BIT_32(18));
+	mmio_clrbits_32(IMX_SIM2_BASE + 0x8, BIT_32(16));
+
+	extern int xrdc_apply_hifi_config(void);
+	xrdc_apply_hifi_config();
+
+	return 0;
+}
+#endif
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 69d4f05..75b709a 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -1,14 +1,17 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
+
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
 #include <lib/pmf/pmf.h>
 #include <tools_share/uuid.h>
+
 #include <imx_sip_svc.h>
 
 static int32_t imx_sip_setup(void)
@@ -29,6 +32,17 @@
 	case IMX_SIP_AARCH32:
 		SMC_RET1(handle, imx_kernel_entry_handler(smc_fid, x1, x2, x3, x4));
 		break;
+#if defined(PLAT_imx8ulp)
+	case IMX_SIP_SCMI:
+		scmi_smt_fastcall_smc_entry(0);
+		SMC_RET1(handle, 0);
+		break;
+	case IMX_SIP_HIFI_XRDC:
+		SMC_RET1(handle, imx_hifi_xrdc(smc_fid));
+		break;
+	case IMX_SIP_DDR_DVFS:
+		return dram_dvfs_handler(smc_fid, handle, x1, x2, x3);
+#endif
 #if defined(PLAT_imx8mq)
 	case IMX_SIP_GET_SOC_INFO:
 		SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
@@ -66,7 +80,8 @@
 		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
 		break;
 #endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp) || \
+	defined(PLAT_imx8mq)
 	case IMX_SIP_HAB:
 		SMC_RET1(handle, imx_hab_handler(smc_fid, x1, x2, x3, x4));
 		break;
diff --git a/plat/imx/common/include/imx_plat_common.h b/plat/imx/common/include/imx_plat_common.h
new file mode 100644
index 0000000..8ec9481
--- /dev/null
+++ b/plat/imx/common/include/imx_plat_common.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_PLAT_COMMON_H
+#define IMX_PLAT_COMMON_H
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+
+uint32_t plat_get_spsr_for_bl33_entry(void);
+
+#endif /*IMX_PLAT_COMMON_H */
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 35a9f47..404a829 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,13 +52,26 @@
 int imx_kernel_entry_handler(uint32_t smc_fid, u_register_t x1,
 			     u_register_t x2, u_register_t x3,
 			     u_register_t x4);
+
+#define IMX_SIP_SCMI			0xC20000FE
+
+#define IMX_SIP_HIFI_XRDC		0xC200000E
+
 #if defined(PLAT_imx8mq)
 int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
 			 u_register_t x2, u_register_t x3);
 int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
 		    u_register_t x2, u_register_t x3);
+#if IMX_DRAM_RETENTION
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
 	u_register_t x1, u_register_t x2, u_register_t x3);
+#else
+static inline int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+		u_register_t x1, u_register_t x2, u_register_t x3)
+{
+	SMC_RET1(handle, SMC_UNK);
+}
+#endif
 #endif
 #if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
@@ -96,5 +109,12 @@
 uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
 			       u_register_t x2, u_register_t x3,
 			       u_register_t x4);
+int scmi_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3);
+int imx_hifi_xrdc(uint32_t smc_fid);
+
+#if defined(PLAT_imx8ulp)
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+	u_register_t x1, u_register_t x2, u_register_t x3);
+#endif
 
 #endif /* __IMX_SIP_SVC_H__ */
diff --git a/plat/imx/common/include/plat_common.h b/plat/imx/common/include/plat_common.h
new file mode 100644
index 0000000..6f41222
--- /dev/null
+++ b/plat/imx/common/include/plat_common.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2024, Pengutronix, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_COMMON_H
+#define PLAT_COMMON_H
+
+#include <stdint.h>
+#include <common/bl_common.h>
+
+int imx_bl31_params_parse(uintptr_t arg0, uintptr_t ocram_base,
+			  uintptr_t ocram_size,
+			  entry_point_info_t *bl32_info,
+			  entry_point_info_t *bl33_info);
+
+#endif /* PLAT_COMMON_H */
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 156c55d..950d8fd 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -78,14 +78,14 @@
 certificates: $(ROT_KEY)
 
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
diff --git a/plat/imx/imx8m/imx8m_measured_boot.c b/plat/imx/imx8m/imx8m_measured_boot.c
index bfcd6ce..159be00 100644
--- a/plat/imx/imx8m/imx8m_measured_boot.c
+++ b/plat/imx/imx8m/imx8m_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -9,6 +9,7 @@
 
 #include "./include/imx8m_measured_boot.h"
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/arm/common/plat_arm.h>
 
 /* Event Log data */
@@ -16,11 +17,11 @@
 
 /* FVP table with platform specific image IDs, names and PCRs */
 static const event_log_metadata_t imx8m_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
 
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index dc9dd59..f6e46eb 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -30,6 +30,7 @@
 #include <imx8m_ccm.h>
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -77,11 +78,31 @@
 
 static const struct imx_csu_cfg csu_cfg[] = {
 	/* peripherals csl setting */
-	CSU_CSLx(0x1, CSU_SEC_LEVEL_0, UNLOCKED),
+	CSU_CSLx(CSU_CSL_RDC, CSU_SEC_LEVEL_3, LOCKED),
+	CSU_CSLx(CSU_CSL_TZASC, CSU_SEC_LEVEL_5, LOCKED),
+	CSU_CSLx(CSU_CSL_CSU, CSU_SEC_LEVEL_5, LOCKED),
 
 	/* master HP0~1 */
 
 	/* SA setting */
+	CSU_SA(CSU_SA_M4, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_PCIE_CTRL1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GPU, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_APBHDMA, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ENET, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_HUGO, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_DAP, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_LCDIF, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_CSI, NON_SEC_ACCESS, LOCKED),
 
 	/* HP control setting */
 
@@ -134,7 +155,7 @@
 {
 	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
-	int i;
+	int i, ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -187,6 +208,13 @@
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
 #endif
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		ret = imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+					    &bl32_image_ep_info,
+					    &bl33_image_ep_info);
+	}
 
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
diff --git a/plat/imx/imx8m/imx8mm/include/imx_sec_def.h b/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
index 6215983..d53c922 100644
--- a/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
+++ b/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
@@ -213,4 +213,26 @@
 	CSU_CSL_CAAM = 114,
 };
 
+enum csu_sa_idx {
+	CSU_SA_M4 = 1,
+	CSU_SA_SDMA1 = 2,
+	CSU_SA_PCIE_CTRL1 = 3,
+	CSU_SA_USB1 = 4,
+	CSU_SA_USB2 = 5,
+	CSU_SA_VPU = 6,
+	CSU_SA_GPU = 7,
+	CSU_SA_APBHDMA = 8,
+	CSU_SA_ENET = 9,
+	CSU_SA_USDHC1 = 10,
+	CSU_SA_USDHC2 = 11,
+	CSU_SA_USDHC3 = 12,
+	CSU_SA_HUGO = 13,
+	CSU_SA_DAP = 14,
+	CSU_SA_SDMA2 = 15,
+	CSU_SA_CAAM = 16,
+	CSU_SA_SDMA3 = 17,
+	CSU_SA_LCDIF = 18,
+	CSU_SA_CSI = 19,
+};
+
 #endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 349233a..2fa6199 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -118,6 +118,8 @@
 #define IMX_ROM_SIZE			U(0x40000)
 #define IMX_NS_OCRAM_BASE		U(0x900000)
 #define IMX_NS_OCRAM_SIZE		U(0x20000)
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
 #define IMX_CAAM_RAM_BASE		U(0x100000)
 #define IMX_CAAM_RAM_SIZE		U(0x10000)
 #define IMX_DRAM_BASE			U(0x40000000)
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 6136820..40554c3 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -30,7 +30,8 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -46,13 +47,13 @@
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ifeq (${NEED_BL2},yes)
@@ -133,14 +134,14 @@
 certificates: $(ROT_KEY)
 
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
@@ -153,6 +154,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index f9e430b..befa769 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
 #include <platform_def.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -126,7 +127,7 @@
 	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	unsigned int val;
-	int i;
+	int i, ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -192,6 +193,13 @@
 #endif
 #endif
 
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+				      &bl32_image_ep_info, &bl33_image_ep_info);
+	}
+
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
 #endif
diff --git a/plat/imx/imx8m/imx8mn/include/imx_sec_def.h b/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
index 0ef14a9..83c5fa9 100644
--- a/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
+++ b/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
@@ -207,4 +207,23 @@
 	CSU_CSL_OCRAM_S = 119,
 };
 
+enum csu_sa_idx {
+	CSU_SA_M7 = 1,
+	CSU_SA_SDMA1 = 2,
+	CSU_SA_USB1 = 4,
+	CSU_SA_GPU = 7,
+	CSU_SA_APBHDMA = 8,
+	CSU_SA_ENET1 = 9,
+	CSU_SA_USDHC1 = 10,
+	CSU_SA_USDHC2 = 11,
+	CSU_SA_USDHC3 = 12,
+	CSU_SA_HUGO = 13,
+	CSU_SA_DAP = 14,
+	CSU_SA_SDMA2 = 15,
+	CSU_SA_CAAM = 16,
+	CSU_SA_SDMA3 = 17,
+	CSU_SA_LCDIF = 18,
+	CSU_SA_ISI = 19,
+};
+
 #endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index 8e7be98..569432d 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -140,6 +140,8 @@
 #define OCRAM_S_SIZE			U(0x8000)
 #define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
 #define SAVED_DRAM_TIMING_BASE		OCRAM_S_BASE
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
 
 #define COUNTER_FREQUENCY		8000000 /* 8MHz */
 
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 6036b6a..6a9d22e 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -25,7 +25,8 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -41,12 +42,12 @@
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
@@ -59,6 +60,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 43fa064..ffad3d1 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
 #include <platform_def.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -63,12 +64,45 @@
 
 static const struct imx_csu_cfg csu_cfg[] = {
 	/* peripherals csl setting */
-	CSU_CSLx(CSU_CSL_OCRAM, CSU_SEC_LEVEL_2, UNLOCKED),
-	CSU_CSLx(CSU_CSL_OCRAM_S, CSU_SEC_LEVEL_2, UNLOCKED),
+	CSU_CSLx(CSU_CSL_OCRAM, CSU_SEC_LEVEL_2, LOCKED),
+	CSU_CSLx(CSU_CSL_OCRAM_S, CSU_SEC_LEVEL_2, LOCKED),
+	CSU_CSLx(CSU_CSL_RDC, CSU_SEC_LEVEL_3, LOCKED),
+	CSU_CSLx(CSU_CSL_TZASC, CSU_SEC_LEVEL_5, LOCKED),
+	CSU_CSLx(CSU_CSL_CSU, CSU_SEC_LEVEL_5, LOCKED),
 
 	/* master HP0~1 */
 
 	/* SA setting */
+	CSU_SA(CSU_SA_M7, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_PCIE_CTRL1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_APB_HDMA, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ENET1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_HUGO, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_DAP, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_LCDIF1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ISI, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_NPU, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_LCDIF2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_HDMI_TX, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ENET2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GPU3D, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GPU2D, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU_G1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU_G2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU_VC8000E, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_AUDIO_EDMA, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ISP1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ISP2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_DEWARP, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GIC500, NON_SEC_ACCESS, LOCKED),
 
 	/* HP control setting */
 
@@ -123,6 +157,7 @@
 	static console_t console;
 	unsigned int val;
 	unsigned int i;
+	int ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -180,6 +215,13 @@
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
 #endif
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		ret = imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+					    &bl32_image_ep_info,
+					    &bl33_image_ep_info);
+	}
 
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
diff --git a/plat/imx/imx8m/imx8mp/include/imx_sec_def.h b/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
index ba248b5..1ba3033 100644
--- a/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
+++ b/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
@@ -269,6 +269,41 @@
 	CSU_CSL_OCRAM_A = 113,
 	CSU_CSL_OCRAM = 118,
 	CSU_CSL_OCRAM_S = 119,
+	CSU_CSL_VPU = 120,
+};
+
+enum csu_sa_idx {
+	CSU_SA_M7 = 1,
+	CSU_SA_SDMA1 = 2,
+	CSU_SA_PCIE_CTRL1 = 3,
+	CSU_SA_USB1 = 4,
+	CSU_SA_USB2 = 6,
+	CSU_SA_APB_HDMA = 8,
+	CSU_SA_ENET1 = 9,
+	CSU_SA_USDHC1 = 10,
+	CSU_SA_USDHC2 = 11,
+	CSU_SA_USDHC3 = 12,
+	CSU_SA_HUGO = 13,
+	CSU_SA_DAP = 14,
+	CSU_SA_SDMA2 = 15,
+	CSU_SA_CAAM = 16,
+	CSU_SA_SDMA3 = 17,
+	CSU_SA_LCDIF1 = 18,
+	CSU_SA_ISI = 19,
+	CSU_SA_NPU = 20,
+	CSU_SA_LCDIF2 = 21,
+	CSU_SA_HDMI_TX = 22,
+	CSU_SA_ENET2 = 23,
+	CSU_SA_GPU3D = 24,
+	CSU_SA_GPU2D = 25,
+	CSU_SA_VPU_G1 = 26,
+	CSU_SA_VPU_G2 = 27,
+	CSU_SA_VPU_VC8000E = 28,
+	CSU_SA_AUDIO_EDMA = 29,
+	CSU_SA_ISP1 = 30,
+	CSU_SA_ISP2 = 31,
+	CSU_SA_DEWARP = 32,
+	CSU_SA_GIC500 = 33,
 };
 
 #endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 4a03830..84a7e00 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -172,6 +172,9 @@
 
 #define MAX_CSU_NUM			U(64)
 
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
+
 #define OCRAM_S_BASE			U(0x00180000)
 #define OCRAM_S_SIZE			U(0x8000)
 #define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 40764b1..5f4ddee 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -26,7 +26,8 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -42,12 +43,12 @@
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
@@ -130,14 +131,14 @@
 certificates: $(ROT_KEY)
 
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
@@ -150,6 +151,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 7065a65..70c2def 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -26,6 +26,7 @@
 #include <imx_aipstz.h>
 #include <imx_uart.h>
 #include <imx8m_caam.h>
+#include <imx8m_ccm.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -145,6 +146,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;
 	/* enable CSU NS access permission */
@@ -154,7 +156,11 @@
 
 	imx_aipstz_init(aipstz);
 
-	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/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 2356cbd..73179dd 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -31,6 +31,7 @@
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
+				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
 				plat/imx/imx8m/imx8mq/gpc.c			\
 				plat/imx/common/imx8_topology.c			\
@@ -42,7 +43,6 @@
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ENABLE_PIE		:=	1
@@ -55,6 +55,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	0
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
@@ -66,6 +74,9 @@
 $(eval $(call add_define,BL32_SIZE))
 
 IMX_BOOT_UART_BASE	?=	0x30860000
+ifeq (${IMX_BOOT_UART_BASE},auto)
+    override IMX_BOOT_UART_BASE	:=	0
+endif
 $(eval $(call add_define,IMX_BOOT_UART_BASE))
 
 ifeq (${SPD},trusty)
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
index 719c390..1cf0666 100644
--- a/plat/imx/imx8m/include/dram.h
+++ b/plat/imx/imx8m/include/dram.h
@@ -70,13 +70,19 @@
 
 extern struct dram_info dram_info;
 
-void dram_info_init(unsigned long dram_timing_base);
 void dram_umctl2_init(struct dram_timing_info *timing);
 void dram_phy_init(struct dram_timing_info *timing);
 
 /* dram retention */
+#if IMX_DRAM_RETENTION
+void dram_info_init(unsigned long dram_timing_base);
 void dram_enter_retention(void);
 void dram_exit_retention(void);
+#else
+static inline void dram_info_init(unsigned long dram_timing_base) {}
+static inline void dram_enter_retention(void) {}
+static inline void dram_exit_retention(void) {}
+#endif
 
 void dram_clock_switch(unsigned int target_drate, bool bypass_mode);
 
diff --git a/plat/imx/imx8m/include/imx8m_csu.h b/plat/imx/imx8m/include/imx8m_csu.h
index dc634ed..3851e91 100644
--- a/plat/imx/imx8m/include/imx8m_csu.h
+++ b/plat/imx/imx8m/include/imx8m_csu.h
@@ -20,6 +20,9 @@
 #define CSU_SEC_LEVEL_6		0x03
 #define CSU_SEC_LEVEL_7		0x0
 
+#define SEC_ACCESS		0x0
+#define NON_SEC_ACCESS		0x1
+
 #define LOCKED			0x1
 #define UNLOCKED		0x0
 
@@ -27,11 +30,11 @@
 #define CSLx_LOCK(x)		((0x1 << (((x) % 2) * 16 + 8)))
 #define CSLx_CFG(x, n)		((x) << (((n) % 2) * 16))
 
-#define CSU_HP_REG(x)		(IMX_CSU_BASE + ((x) / 16) * 4 + 0x200)
+#define CSU_HP_REG(x)		(IMX_CSU_BASE + (((x) / 16) * 4) + 0x200)
 #define CSU_HP_LOCK(x)		((0x1 << (((x) % 16) * 2 + 1)))
 #define CSU_HP_CFG(x, n)	((x) << (((n) % 16) * 2))
 
-#define CSU_SA_REG(x)		(IMX_CSU_BASE + 0x218)
+#define CSU_SA_REG(x)		(IMX_CSU_BASE + (((x) / 16) * 4) + 0x218)
 #define CSU_SA_LOCK(x)		((0x1 << (((x) % 16) * 2 + 1)))
 #define CSU_SA_CFG(x, n)	((x) << (((n) % 16) * 2))
 
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index bd7896a..4c63740 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -408,8 +408,3 @@
 {
 	return COUNTER_FREQUENCY;
 }
-
-void bl31_plat_runtime_setup(void)
-{
-	return;
-}
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 13e80fb..08bf8f3 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -386,8 +386,3 @@
 {
 	return COUNTER_FREQUENCY;
 }
-
-void bl31_plat_runtime_setup(void)
-{
-	return;
-}
diff --git a/plat/imx/imx8ulp/apd_context.c b/plat/imx/imx8ulp/apd_context.c
new file mode 100644
index 0000000..54b8795
--- /dev/null
+++ b/plat/imx/imx8ulp/apd_context.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <plat_imx8.h>
+#include <xrdc.h>
+
+#define PCC_PR	BIT(31)
+#define PFD_VALID_MASK	U(0x40404040)
+
+#define S400_MU_BASE	U(0x27020000)
+#define S400_MU_RSR	(S400_MU_BASE + 0x12c)
+#define S400_MU_TRx(i)	(S400_MU_BASE + 0x200 + (i) * 4)
+#define S400_MU_RRx(i)	(S400_MU_BASE + 0x280 + (i) * 4)
+
+/*
+ * need to re-init the PLL, CGC1, PCC, CMC, XRDC, SIM, GPIO etc.
+ * init the PLL &PFD first, then switch the CA35 clock to PLL for
+ * performance consideration, restore other bus fabric clock.
+ */
+
+extern void imx8ulp_caam_init(void);
+extern void upower_wait_resp(void);
+extern void dram_enter_retention(void);
+extern void dram_exit_retention(void);
+
+struct plat_gic_ctx imx_gicv3_ctx;
+static uint32_t cmc1_pmprot;
+static uint32_t cmc1_srie;
+
+/* TPM5: global timer */
+static uint32_t tpm5[3];
+
+static uint32_t wdog3[2];
+
+/* CGC1 PLL2 */
+uint32_t pll2[][2] = {
+	{0x292c0510, 0x0}, {0x292c0518, 0x0}, {0x292c051c, 0x0},
+	{0x292c0520, 0x0}, {0x292c0500, 0x0},
+};
+
+/* CGC1 PLL3 */
+uint32_t pll3[][2] = {
+	{0x292c0604, 0x0}, {0x292c0608, 0x0}, {0x292c060c, 0x0},
+	{0x292c0610, 0x0}, {0x292c0618, 0x0}, {0x292c061c, 0x0},
+	{0x292c0620, 0x0}, {0x292c0624, 0x0}, {0x292c0600, 0x0},
+	{0x292c0614, 0x0},
+};
+
+/* CGC1 others */
+uint32_t cgc1[][2] = {
+	{0x292c0014, 0x0}, {0x292c0034, 0x0}, {0x292c0038, 0x0},
+	{0x292c0108, 0x0}, {0x292c0208, 0x0}, {0x292c0700, 0x0},
+	{0x292c0810, 0x0}, {0x292c0900, 0x0}, {0x292c0904, 0x0},
+	{0x292c0908, 0x0}, {0x292c090c, 0x0}, {0x292c0a00, 0x0},
+};
+
+static uint32_t pcc3[61];
+static uint32_t pcc4[32];
+
+static uint32_t pcc5_0[33];
+static uint32_t pcc5_1[][2] = {
+	{0x2da70084, 0x0}, {0x2da70088, 0x0}, {0x2da7008c, 0x0},
+	{0x2da700a0, 0x0}, {0x2da700a4, 0x0}, {0x2da700a8, 0x0},
+	{0x2da700ac, 0x0}, {0x2da700b0, 0x0}, {0x2da700b4, 0x0},
+	{0x2da700bc, 0x0}, {0x2da700c0, 0x0}, {0x2da700c8, 0x0},
+	{0x2da700cc, 0x0}, {0x2da700d0, 0x0}, {0x2da700f0, 0x0},
+	{0x2da700f4, 0x0}, {0x2da700f8, 0x0}, {0x2da70108, 0x0},
+	{0x2da7010c, 0x0}, {0x2da70110, 0x0}, {0x2da70114, 0x0},
+};
+
+static uint32_t cgc2[][2] = {
+	{0x2da60014, 0x0}, {0x2da60020, 0x0}, {0x2da6003c, 0x0},
+	{0x2da60040, 0x0}, {0x2da60108, 0x0}, {0x2da60208, 0x0},
+	{0x2da60900, 0x0}, {0x2da60904, 0x0}, {0x2da60908, 0x0},
+	{0x2da60910, 0x0}, {0x2da60a00, 0x0},
+};
+
+static uint32_t pll4[][2] = {
+	{0x2da60604, 0x0}, {0x2da60608, 0x0}, {0x2da6060c, 0x0},
+	{0x2da60610, 0x0}, {0x2da60618, 0x0}, {0x2da6061c, 0x0},
+	{0x2da60620, 0x0}, {0x2da60624, 0x0}, {0x2da60600, 0x0},
+	{0x2da60614, 0x0},
+};
+
+static uint32_t lpav_sim[][2] = {
+	{0x2da50000, 0x0}, {0x2da50004, 0x0}, {0x2da50008, 0x0},
+	{0x2da5001c, 0x0}, {0x2da50020, 0x0}, {0x2da50024, 0x0},
+	{0x2da50034, 0x0},
+};
+
+#define APD_GPIO_CTRL_NUM		2
+#define LPAV_GPIO_CTRL_NUM		1
+#define GPIO_CTRL_REG_NUM		8
+#define GPIO_PIN_MAX_NUM	32
+#define GPIO_CTX(addr, num)	\
+	{.base = (addr), .pin_num = (num), }
+
+struct gpio_ctx {
+	/* gpio base */
+	uintptr_t base;
+	/* port control */
+	uint32_t port_ctrl[GPIO_CTRL_REG_NUM];
+	/* GPIO ICR, Max 32 */
+	uint32_t pin_num;
+	uint32_t gpio_icr[GPIO_PIN_MAX_NUM];
+};
+
+static uint32_t gpio_ctrl_offset[GPIO_CTRL_REG_NUM] = {
+	 0xc, 0x10, 0x14, 0x18, 0x1c, 0x40, 0x54, 0x58
+};
+static struct gpio_ctx apd_gpio_ctx[APD_GPIO_CTRL_NUM] = {
+	GPIO_CTX(IMX_GPIOE_BASE, 24),
+	GPIO_CTX(IMX_GPIOF_BASE, 32),
+};
+
+static struct gpio_ctx lpav_gpio_ctx = GPIO_CTX(IMX_GPIOD_BASE, 24);
+/* iomuxc setting */
+#define IOMUXC_SECTION_NUM	8
+struct iomuxc_section {
+	uint32_t offset;
+	uint32_t reg_num;
+};
+
+struct iomuxc_section iomuxc_sections[IOMUXC_SECTION_NUM] = {
+	{.offset = IOMUXC_PTD_PCR_BASE, .reg_num = 24},
+	{.offset = IOMUXC_PTE_PCR_BASE, .reg_num = 24},
+	{.offset = IOMUXC_PTF_PCR_BASE, .reg_num = 32},
+	{.offset = IOMUXC_PSMI_BASE0, .reg_num = 10},
+	{.offset = IOMUXC_PSMI_BASE1, .reg_num = 61},
+	{.offset = IOMUXC_PSMI_BASE2, .reg_num = 12},
+	{.offset = IOMUXC_PSMI_BASE3, .reg_num = 20},
+	{.offset = IOMUXC_PSMI_BASE4, .reg_num = 75},
+};
+static uint32_t iomuxc_ctx[258];
+
+#define PORTS_NUM		3U
+void apd_io_pad_off(void)
+{
+	unsigned int i, j;
+
+	/* off the PTD/E/F, need to be customized based on actual user case */
+	for (i = 0; i < PORTS_NUM; i++) {
+		for (j = 0; j < iomuxc_sections[i].reg_num; j++) {
+			mmio_write_32(iomuxc_sections[i].offset + j * 4, 0);
+		}
+	}
+
+	/* disable the PTD compensation */
+	mmio_write_32(IMX_SIM1_BASE + 0x48, 0x800);
+}
+
+void iomuxc_save(void)
+{
+	unsigned int i, j;
+	unsigned int index = 0U;
+
+	for (i = 0U; i < IOMUXC_SECTION_NUM; i++) {
+		for (j = 0U; j < iomuxc_sections[i].reg_num; j++) {
+			iomuxc_ctx[index++] = mmio_read_32(iomuxc_sections[i].offset + j * 4);
+		}
+	}
+
+	apd_io_pad_off();
+}
+
+void iomuxc_restore(void)
+{
+	unsigned int i, j;
+	unsigned int index = 0U;
+
+	for (i = 0U; i < IOMUXC_SECTION_NUM; i++) {
+		for (j = 0U; j < iomuxc_sections[i].reg_num; j++) {
+			mmio_write_32(iomuxc_sections[i].offset + j * 4, iomuxc_ctx[index++]);
+		}
+	}
+}
+
+void gpio_save(struct gpio_ctx *ctx, int port_num)
+{
+	unsigned int i, j;
+
+	for (i = 0U; i < port_num; i++) {
+		/* save the port control setting */
+		for (j = 0U; j < GPIO_CTRL_REG_NUM; j++) {
+			if (j < 4U) {
+				ctx->port_ctrl[j] = mmio_read_32(ctx->base + gpio_ctrl_offset[j]);
+				/*
+				 * clear the permission setting to read the GPIO
+				 * non-secure world setting.
+				 */
+				mmio_write_32(ctx->base + gpio_ctrl_offset[j], 0x0);
+			} else {
+				ctx->port_ctrl[j] = mmio_read_32(ctx->base + gpio_ctrl_offset[j]);
+			}
+		}
+		/* save the gpio icr setting */
+		for (j = 0U; j < ctx->pin_num; j++) {
+			ctx->gpio_icr[j] = mmio_read_32(ctx->base + 0x80 + j * 4);
+		}
+
+		ctx++;
+	}
+}
+
+void gpio_restore(struct gpio_ctx *ctx, int port_num)
+{
+	unsigned int i, j;
+
+	for (i = 0U; i < port_num; i++) {
+		for (j = 0U; j < ctx->pin_num; j++)
+			mmio_write_32(ctx->base + 0x80 + j * 4, ctx->gpio_icr[j]);
+
+		for (j = 4U; j < GPIO_CTRL_REG_NUM; j++) {
+			mmio_write_32(ctx->base + gpio_ctrl_offset[j], ctx->port_ctrl[j]);
+		}
+
+		/* permission config retore last */
+		for (j = 0U; j < 4; j++) {
+			mmio_write_32(ctx->base + gpio_ctrl_offset[j], ctx->port_ctrl[j]);
+		}
+
+		ctx++;
+	}
+}
+
+void cgc1_save(void)
+{
+	unsigned int i;
+
+	/* PLL2 */
+	for (i = 0U; i < ARRAY_SIZE(pll2); i++) {
+		pll2[i][1] = mmio_read_32(pll2[i][0]);
+	}
+
+	/* PLL3 */
+	for (i = 0U; i < ARRAY_SIZE(pll3); i++) {
+		pll3[i][1] = mmio_read_32(pll3[i][0]);
+	}
+
+	/* CGC1 others */
+	for (i = 0U; i < ARRAY_SIZE(cgc1); i++) {
+		cgc1[i][1] = mmio_read_32(cgc1[i][0]);
+	}
+}
+
+void cgc1_restore(void)
+{
+	unsigned int i;
+
+	/* PLL2 */
+	for (i = 0U; i < ARRAY_SIZE(pll2); i++) {
+		mmio_write_32(pll2[i][0], pll2[i][1]);
+	}
+	/* wait for PLL2 lock */
+	while (!(mmio_read_32(pll2[4][0]) & BIT(24))) {
+		;
+	}
+
+	/* PLL3 */
+	for (i = 0U; i < 9U; i++) {
+		mmio_write_32(pll3[i][0], pll3[i][1]);
+	}
+
+	/* wait for PLL3 lock */
+	while (!(mmio_read_32(pll3[4][0]) & BIT(24))) {
+		;
+	}
+
+	/* restore the PFDs */
+	mmio_write_32(pll3[9][0], pll3[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
+	mmio_write_32(pll3[9][0], pll3[9][1]);
+
+	/* wait for the PFD is stable, only need to check the enabled PFDs */
+	while (!(mmio_read_32(pll3[9][0]) & PFD_VALID_MASK)) {
+		;
+	}
+
+	/* CGC1 others */
+	for (i = 0U; i < ARRAY_SIZE(cgc1); i++) {
+		mmio_write_32(cgc1[i][0], cgc1[i][1]);
+	}
+}
+
+void tpm5_save(void)
+{
+	tpm5[0] = mmio_read_32(IMX_TPM5_BASE + 0x10);
+	tpm5[1] = mmio_read_32(IMX_TPM5_BASE + 0x18);
+	tpm5[2] = mmio_read_32(IMX_TPM5_BASE + 0x20);
+}
+
+void tpm5_restore(void)
+{
+	mmio_write_32(IMX_TPM5_BASE + 0x10, tpm5[0]);
+	mmio_write_32(IMX_TPM5_BASE + 0x18, tpm5[1]);
+	mmio_write_32(IMX_TPM5_BASE + 0x20, tpm5[2]);
+}
+
+void wdog3_save(void)
+{
+	/* enable wdog3 clock */
+	mmio_write_32(IMX_PCC3_BASE + 0xa8, 0xd2800000);
+
+	/* save the CS & TOVAL regiter */
+	wdog3[0] = mmio_read_32(IMX_WDOG3_BASE);
+	wdog3[1] = mmio_read_32(IMX_WDOG3_BASE + 0x8);
+}
+
+void wdog3_restore(void)
+{
+	/* enable wdog3 clock */
+	mmio_write_32(IMX_PCC3_BASE + 0xa8, 0xd2800000);
+
+	/* reconfig the CS */
+	mmio_write_32(IMX_WDOG3_BASE, wdog3[0]);
+	/* set the tiemout value */
+	mmio_write_32(IMX_WDOG3_BASE + 0x8, wdog3[1]);
+
+	/* wait for the lock status */
+	while ((mmio_read_32(IMX_WDOG3_BASE) & BIT(11))) {
+		;
+	}
+
+	/* wait for the config done */
+	while (!(mmio_read_32(IMX_WDOG3_BASE) & BIT(10))) {
+		;
+	}
+}
+
+static uint32_t lpuart_regs[4];
+#define LPUART_BAUD     0x10
+#define LPUART_CTRL     0x18
+#define LPUART_FIFO     0x28
+#define LPUART_WATER    0x2c
+
+void lpuart_save(void)
+{
+	lpuart_regs[0] = mmio_read_32(IMX_LPUART5_BASE + LPUART_BAUD);
+	lpuart_regs[1] = mmio_read_32(IMX_LPUART5_BASE + LPUART_FIFO);
+	lpuart_regs[2] = mmio_read_32(IMX_LPUART5_BASE + LPUART_WATER);
+	lpuart_regs[3] = mmio_read_32(IMX_LPUART5_BASE + LPUART_CTRL);
+}
+
+void lpuart_restore(void)
+{
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_BAUD, lpuart_regs[0]);
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_FIFO, lpuart_regs[1]);
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_WATER, lpuart_regs[2]);
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_CTRL, lpuart_regs[3]);
+}
+
+bool is_lpav_owned_by_apd(void)
+{
+	return (mmio_read_32(0x2802b044) & BIT(7)) ? true : false;
+}
+
+void lpav_ctx_save(void)
+{
+	unsigned int i;
+	uint32_t val;
+
+	/* CGC2 save */
+	for (i = 0U; i < ARRAY_SIZE(cgc2); i++) {
+		cgc2[i][1] = mmio_read_32(cgc2[i][0]);
+	}
+
+	/* PLL4 */
+	for (i = 0U; i < ARRAY_SIZE(pll4); i++) {
+		pll4[i][1] = mmio_read_32(pll4[i][0]);
+	}
+
+	/* PCC5 save */
+	for (i = 0U; i < ARRAY_SIZE(pcc5_0); i++) {
+		val = mmio_read_32(IMX_PCC5_BASE + i * 4);
+		if (val & PCC_PR) {
+			pcc5_0[i] = val;
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(pcc5_1); i++) {
+		val = mmio_read_32(pcc5_1[i][0]);
+		if (val & PCC_PR) {
+			pcc5_1[i][1] = val;
+		}
+	}
+
+	/* LPAV SIM save */
+	for (i = 0U; i < ARRAY_SIZE(lpav_sim); i++) {
+		lpav_sim[i][1] = mmio_read_32(lpav_sim[i][0]);
+	}
+
+	/* Save GPIO port D */
+	gpio_save(&lpav_gpio_ctx, LPAV_GPIO_CTRL_NUM);
+
+	/* put DDR into retention */
+	dram_enter_retention();
+}
+
+void lpav_ctx_restore(void)
+{
+	unsigned int i;
+
+	/* PLL4 */
+	for (i = 0U; i < 9U; i++) {
+		mmio_write_32(pll4[i][0], pll4[i][1]);
+	}
+
+	/* wait for PLL4 lock */
+	while (!(mmio_read_32(pll4[8][0]) & BIT(24))) {
+		;
+	}
+
+	/* restore the PLL4 PFDs */
+	mmio_write_32(pll4[9][0], pll4[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
+	mmio_write_32(pll4[9][0], pll4[9][1]);
+
+	/* wait for the PFD is stable */
+	while (!(mmio_read_32(pll4[9][0]) & PFD_VALID_MASK)) {
+		;
+	}
+
+	/* CGC2 restore */
+	for (i = 0U; i < ARRAY_SIZE(cgc2); i++) {
+		mmio_write_32(cgc2[i][0], cgc2[i][1]);
+	}
+
+	/* PCC5 restore */
+	for (i = 0U; i < ARRAY_SIZE(pcc5_0); i++) {
+		if (pcc5_0[i] & PCC_PR) {
+			mmio_write_32(IMX_PCC5_BASE + i * 4, pcc5_0[i]);
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(pcc5_1); i++) {
+		if (pcc5_1[i][1] & PCC_PR) {
+			mmio_write_32(pcc5_1[i][0], pcc5_1[i][1]);
+		}
+	}
+
+	/* LPAV_SIM */
+	for (i = 0U; i < ARRAY_SIZE(lpav_sim); i++) {
+		mmio_write_32(lpav_sim[i][0], lpav_sim[i][1]);
+	}
+
+	gpio_restore(&lpav_gpio_ctx, LPAV_GPIO_CTRL_NUM);
+	/* DDR retention exit */
+	dram_exit_retention();
+}
+
+void imx_apd_ctx_save(unsigned int proc_num)
+{
+	unsigned int i;
+	uint32_t val;
+
+	/* enable LPUART5's clock by default */
+	mmio_setbits_32(IMX_PCC3_BASE + 0xe8, BIT(30));
+
+	/* save the gic config */
+	plat_gic_save(proc_num, &imx_gicv3_ctx);
+
+	cmc1_pmprot = mmio_read_32(IMX_CMC1_BASE + 0x18);
+	cmc1_srie = mmio_read_32(IMX_CMC1_BASE + 0x8c);
+
+	/* save the PCC3 */
+	for (i = 0U; i < ARRAY_SIZE(pcc3); i++) {
+		/* save the pcc if it is exist */
+		val = mmio_read_32(IMX_PCC3_BASE + i * 4);
+		if (val & PCC_PR) {
+			pcc3[i] = val;
+		}
+	}
+
+	/* save the PCC4 */
+	for (i = 0U; i < ARRAY_SIZE(pcc4); i++) {
+		/* save the pcc if it is exist */
+		val = mmio_read_32(IMX_PCC4_BASE + i * 4);
+		if (val & PCC_PR) {
+			pcc4[i] = val;
+		}
+	}
+
+	/* save the CGC1 */
+	cgc1_save();
+
+	wdog3_save();
+
+	gpio_save(apd_gpio_ctx, APD_GPIO_CTRL_NUM);
+
+	iomuxc_save();
+
+	tpm5_save();
+
+	lpuart_save();
+
+	/*
+	 * save the lpav ctx & put the ddr into retention
+	 * if lpav master is assigned to APD domain.
+	 */
+	if (is_lpav_owned_by_apd()) {
+		lpav_ctx_save();
+	}
+}
+
+void xrdc_reinit(void)
+{
+	xrdc_apply_apd_config();
+	xrdc_apply_lpav_config();
+
+	xrdc_enable();
+}
+
+void s400_release_caam(void)
+{
+	uint32_t msg, resp;
+
+	mmio_write_32(S400_MU_TRx(0), 0x17d70206);
+	mmio_write_32(S400_MU_TRx(1), 0x7);
+
+	do {
+		resp = mmio_read_32(S400_MU_RSR);
+	} while ((resp & 0x3) != 0x3);
+
+	msg = mmio_read_32(S400_MU_RRx(0));
+	resp = mmio_read_32(S400_MU_RRx(1));
+
+	VERBOSE("resp %x; %x", msg, resp);
+}
+
+void imx_apd_ctx_restore(unsigned int proc_num)
+{
+	unsigned int i;
+
+	/* restore the CCG1 */
+	cgc1_restore();
+
+	for (i = 0U; i < ARRAY_SIZE(pcc3); i++) {
+		/* save the pcc if it is exist */
+		if (pcc3[i] & PCC_PR) {
+			mmio_write_32(IMX_PCC3_BASE + i * 4, pcc3[i]);
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(pcc4); i++) {
+		if (pcc4[i] & PCC_PR) {
+			mmio_write_32(IMX_PCC4_BASE + i * 4, pcc4[i]);
+		}
+	}
+
+	wdog3_restore();
+
+	iomuxc_restore();
+
+	tpm5_restore();
+
+	xrdc_reinit();
+
+	/* Restore GPIO after xrdc_reinit, otherwise MSCs are invalid */
+	gpio_restore(apd_gpio_ctx, APD_GPIO_CTRL_NUM);
+
+	/* restore the gic config */
+	plat_gic_restore(proc_num, &imx_gicv3_ctx);
+
+	mmio_write_32(IMX_CMC1_BASE + 0x18, cmc1_pmprot);
+	mmio_write_32(IMX_CMC1_BASE + 0x8c, cmc1_srie);
+
+	/* enable LPUART5's clock by default */
+	mmio_setbits_32(IMX_PCC3_BASE + 0xe8, BIT(30));
+
+	/* restore the console lpuart */
+	lpuart_restore();
+
+	/* FIXME: make uart work for ATF */
+	mmio_write_32(IMX_LPUART_BASE + 0x18, 0xc0000);
+
+	/* Allow M core to reset A core */
+	mmio_clrbits_32(IMX_MU0B_BASE + 0x10, BIT(2));
+	/*
+	 * Ask S400 to release caam to APD as it is owned by s400
+	 */
+	s400_release_caam();
+
+	/* re-init the caam */
+	imx8ulp_caam_init();
+
+	/*
+	 * ack the upower, seems a necessary steps, otherwise the upower can
+	 * not response to the new API service call. put this just before the
+	 * ddr retention exit because that the dram retention exit flow need to
+	 * communicate with upower.
+	 */
+	upower_wait_resp();
+
+	/*
+	 * restore the lpav ctx & make ddr out of retention
+	 * if lpav master is assigned to APD domain.
+	 */
+	if (is_lpav_owned_by_apd()) {
+		lpav_ctx_restore();
+	}
+}
+
+#define DGO_CTRL1	U(0xc)
+#define USB_WAKEUP	U(0x44)
+#define USB1_PHY_DPD_WAKEUP_EN	BIT_32(5)
+#define USB0_PHY_DPD_WAKEUP_EN	BIT_32(4)
+#define USB1_PHY_WAKEUP_ISO_DISABLE	BIT_32(1)
+#define USB0_PHY_WAKEUP_ISO_DISABLE	BIT_32(0)
+
+void usb_wakeup_enable(bool enable)
+{
+	if (enable) {
+		mmio_setbits_32(IMX_SIM1_BASE + USB_WAKEUP,
+				USB1_PHY_WAKEUP_ISO_DISABLE | USB0_PHY_WAKEUP_ISO_DISABLE);
+		mmio_setbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
+			;
+		}
+
+		mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
+
+		/* Need to delay for a while to make sure the wakeup logic can work */
+		udelay(500);
+
+		mmio_setbits_32(IMX_SIM1_BASE + USB_WAKEUP,
+				USB1_PHY_DPD_WAKEUP_EN | USB0_PHY_DPD_WAKEUP_EN);
+		mmio_setbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
+			;
+		}
+
+		mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
+	} else {
+		/*
+		 * USBx_PHY_DPD_WAKEUP_EN should be cleared before USB0_PHY_WAKEUP_ISO_DISABLE
+		 * to provide the correct the wake-up functionality.
+		 */
+		mmio_write_32(IMX_SIM1_BASE + USB_WAKEUP, USB1_PHY_WAKEUP_ISO_DISABLE |
+			USB0_PHY_WAKEUP_ISO_DISABLE);
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
+			;
+		}
+
+		mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
+	}
+}
diff --git a/plat/imx/imx8ulp/dram.c b/plat/imx/imx8ulp/dram.c
new file mode 100644
index 0000000..00a5220
--- /dev/null
+++ b/plat/imx/imx8ulp/dram.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <bl31/interrupt_mgmt.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+#include <dram.h>
+#include <upower_api.h>
+
+#define PHY_FREQ_SEL_INDEX(x)		((x) << 16)
+#define PHY_FREQ_MULTICAST_EN(x)	((x) << 8)
+#define DENALI_PHY_1537			U(0x5804)
+
+#define IMX_DDRC_BASE			U(0x2E060000)
+#define SAVED_DRAM_DATA_BASE		U(0x20055000)
+#define DENALI_CTL_143			U(0x23C)
+#define DENALI_CTL_144			U(0x240)
+#define DENALI_CTL_146			U(0x248)
+#define LP_STATE_CS_IDLE		U(0x404000)
+#define LP_STATE_CS_PD_CG		U(0x4F4F00)
+#define LPI_WAKEUP_EN_SHIFT		U(8)
+#define IMX_LPAV_SIM_BASE		0x2DA50000
+#define LPDDR_CTRL			0x14
+#define LPDDR_AUTO_LP_MODE_DISABLE	BIT(24)
+#define SOC_LP_CMD_SHIFT		U(15)
+#define LPDDR_CTRL2			0x18
+#define LPDDR_EN_CLKGATE		(0x1<<17)
+#define LPDDR_MAX_CLKDIV_EN		(0x1 << 16)
+#define LP_AUTO_ENTRY_EN		0x4
+#define LP_AUTO_EXIT_EN			0xF
+
+#define DENALI_CTL_00			U(0x0)
+#define DENALI_CTL_23			U(0x5c)
+#define DFIBUS_FREQ_INIT_SHIFT		U(24)
+#define TSREF2PHYMSTR_SHIFT		U(8)
+#define TSREF2PHYMSTR_MASK		GENMASK(13, 8)
+
+#define DENALI_CTL_24			U(0x60)
+#define DENALI_CTL_25			U(0x64)
+
+#define DENALI_CTL_93			U(0x174)
+#define PWRUP_SREFRESH_EXIT		BIT(0)
+
+#define DENALI_CTL_127				U(0x1fc)
+#define PHYMSTR_TRAIN_AFTER_INIT_COMPLETE	BIT(16)
+
+#define DENALI_CTL_147			U(0x24c)
+#define DENALI_CTL_153			U(0x264)
+#define PCPCS_PD_EN			BIT(8)
+
+#define DENALI_CTL_249			U(0x3E4)
+#define DENALI_CTL_266			U(0x428)
+
+#define DENALI_PHY_1547			U(0x582c)
+#define PHY_LP4_BOOT_DISABLE		BIT(8)
+
+#define DENALI_PHY_1559			U(0x585c)
+#define DENALI_PHY_1590			U(0x58D8)
+
+#define DENALI_PI_00			U(0x2000)
+#define DENALI_PI_04			U(0x2010)
+#define DENALI_PI_52			U(0x20D0)
+#define DENALI_PI_26			U(0x2068)
+#define DENALI_PI_33			U(0x2084)
+#define DENALI_PI_65			U(0x2104)
+#define DENALI_PI_77			U(0x2134)
+#define DENALI_PI_134			U(0x2218)
+#define DENALI_PI_131			U(0x220C)
+#define DENALI_PI_132			U(0x2210)
+#define DENALI_PI_134			U(0x2218)
+#define DENALI_PI_137			U(0x2224)
+#define DENALI_PI_174			U(0x22B8)
+#define DENALI_PI_175			U(0x22BC)
+#define DENALI_PI_181			U(0x22D4)
+#define DENALI_PI_182			U(0x22D8)
+#define DENALI_PI_191			U(0x22FC)
+#define DENALI_PI_192			U(0x2300)
+#define DENALI_PI_212			U(0x2350)
+#define DENALI_PI_214			U(0x2358)
+#define DENALI_PI_217			U(0x2364)
+
+#define LPDDR3_TYPE	U(0x7)
+#define LPDDR4_TYPE	U(0xB)
+
+extern void upower_wait_resp(void);
+
+struct dram_cfg_param {
+	uint32_t reg;
+	uint32_t val;
+};
+
+struct dram_timing_info {
+	/* ddr controller config */
+	struct dram_cfg_param *ctl_cfg;
+	unsigned int ctl_cfg_num;
+	/* pi config */
+	struct dram_cfg_param *pi_cfg;
+	unsigned int pi_cfg_num;
+	/* phy freq1 config */
+	struct dram_cfg_param *phy_f1_cfg;
+	unsigned int phy_f1_cfg_num;
+	/* phy freq2 config */
+	struct dram_cfg_param *phy_f2_cfg;
+	unsigned int phy_f2_cfg_num;
+	/* automatic low power config */
+	struct dram_cfg_param *auto_lp_cfg;
+	unsigned int auto_lp_cfg_num;
+	/* initialized drate table */
+	unsigned int fsp_table[3];
+};
+
+#define CTL_NUM		U(680)
+#define PI_NUM		U(298)
+#define PHY_NUM		U(1654)
+#define PHY_DIFF_NUM	U(49)
+#define AUTO_LP_NUM	U(3)
+struct dram_cfg {
+	uint32_t ctl_cfg[CTL_NUM];
+	uint32_t pi_cfg[PI_NUM];
+	uint32_t phy_full[PHY_NUM];
+	uint32_t phy_diff[PHY_DIFF_NUM];
+	uint32_t auto_lp_cfg[AUTO_LP_NUM];
+};
+
+struct dram_timing_info *info;
+struct dram_cfg *dram_timing_cfg;
+
+/* mark if dram cfg is already saved */
+static bool dram_cfg_saved;
+static bool dram_auto_lp_true;
+static uint32_t dram_class, dram_ctl_143;
+
+/* PHY register index for frequency diff */
+uint32_t freq_specific_reg_array[PHY_DIFF_NUM] = {
+90, 92, 93, 96, 97, 100, 101, 102, 103, 104, 114,
+346, 348, 349, 352, 353, 356, 357, 358, 359, 360,
+370, 602, 604, 605, 608, 609, 612, 613, 614, 615,
+616, 626, 858, 860, 861, 864, 865, 868, 869, 870,
+871, 872, 882, 1063, 1319, 1566, 1624, 1625
+};
+
+/* lock used for DDR DVFS */
+spinlock_t dfs_lock;
+static volatile uint32_t core_count;
+static volatile bool in_progress;
+static volatile bool sys_dvfs;
+static int num_fsp;
+
+static void ddr_init(void)
+{
+	unsigned int i;
+
+	/* restore the ddr ctl config */
+	for (i = 0U; i < CTL_NUM; i++) {
+		mmio_write_32(IMX_DDRC_BASE + i * 4, dram_timing_cfg->ctl_cfg[i]);
+	}
+
+	/* load the PI registers */
+	for (i = 0U; i < PI_NUM; i++) {
+		mmio_write_32(IMX_DDRC_BASE + 0x2000 + i * 4, dram_timing_cfg->pi_cfg[i]);
+	}
+
+
+	 /* restore all PHY registers for all the fsp. */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x100);
+	/* restore all the phy configs */
+	for (i = 0U; i < PHY_NUM; i++) {
+		/* skip the reserved registers space */
+		if (i >= 121U && i <= 255U) {
+			continue;
+		}
+		if (i >= 377U && i <= 511U) {
+			continue;
+		}
+		if (i >= 633U && i <= 767U) {
+			continue;
+		}
+		if (i >= 889U && i <= 1023U) {
+			continue;
+		}
+		if (i >= 1065U && i <= 1279U) {
+			continue;
+		}
+		if (i >= 1321U && i <= 1535U) {
+			continue;
+		}
+		mmio_write_32(IMX_DDRC_BASE + 0x4000 + i * 4, dram_timing_cfg->phy_full[i]);
+	}
+
+	if (dram_class == LPDDR4_TYPE) {
+		/* restore only the diff. */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
+		for (i = 0U; i < PHY_DIFF_NUM; i++) {
+			mmio_write_32(IMX_DDRC_BASE + 0x4000 + freq_specific_reg_array[i] * 4,
+				      dram_timing_cfg->phy_diff[i]);
+		}
+	}
+
+	/* Re-enable MULTICAST mode */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, PHY_FREQ_MULTICAST_EN(1));
+}
+
+void dram_lp_auto_disable(void)
+{
+	uint32_t lp_auto_en;
+
+	dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
+					      sizeof(struct dram_timing_info));
+	lp_auto_en = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & (LP_AUTO_ENTRY_EN << 24));
+	/* Save initial config */
+	dram_ctl_143 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_143);
+
+	if (lp_auto_en && !dram_auto_lp_true) {
+		/* 0.a Save DDRC auto low-power mode parameter */
+		dram_timing_cfg->auto_lp_cfg[0] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
+		dram_timing_cfg->auto_lp_cfg[1] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_147);
+		dram_timing_cfg->auto_lp_cfg[2] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146);
+		/* Set LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2 to Maximum */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_143, 0xF << 24);
+		/* 0.b Disable DDRC auto low-power mode interface */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_146, LP_AUTO_ENTRY_EN << 24);
+		/* 0.c Read any location to get DRAM out of Self-refresh */
+		mmio_read_32(DEVICE2_BASE);
+		/* 0.d Confirm DRAM is out of Self-refresh */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) &
+			LP_STATE_CS_PD_CG) != LP_STATE_CS_IDLE) {
+			;
+		}
+		/* 0.e Disable DDRC auto low-power exit */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_147, LP_AUTO_EXIT_EN);
+		/* dram low power mode flag */
+		dram_auto_lp_true = true;
+	}
+}
+
+void dram_lp_auto_enable(void)
+{
+	/* Switch back to Auto Low-power mode */
+	if (dram_auto_lp_true) {
+		/* 12.a Confirm DRAM is out of Self-refresh */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) &
+			LP_STATE_CS_PD_CG) != LP_STATE_CS_IDLE) {
+			;
+		}
+		/* 12.b Enable DDRC auto low-power exit */
+		/*
+		 * 12.c TBC! : Set DENALI_CTL_144 [LPI_CTRL_REQ_EN[24]] and
+		 * [DFI_LP_VERSION[16]] back to default settings = 1b'1.
+		 */
+		/*
+		 * 12.d Reconfigure DENALI_CTL_144 [LPI_WAKEUP_EN[5:0]] bit
+		 * LPI_WAKEUP_EN[3] = 1b'1.
+		 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, dram_timing_cfg->auto_lp_cfg[0]);
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_147, dram_timing_cfg->auto_lp_cfg[1]);
+		/* 12.e Re-enable DDRC auto low-power mode interface */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_146, dram_timing_cfg->auto_lp_cfg[2]);
+		/* restore ctl config */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_143, dram_ctl_143);
+		/* dram low power mode flag */
+		dram_auto_lp_true = false;
+	}
+}
+
+void dram_enter_self_refresh(void)
+{
+	/* disable auto low power interface */
+	dram_lp_auto_disable();
+	/* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
+	/* 1.a Clock gate PCC_LPDDR4[CGC] and no software reset PCC_LPDDR4[SWRST] */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, (BIT(30) | BIT(28)));
+
+	/*
+	 * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
+	 * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
+	 * long with mem and ctlr clk gating or self-refresh power-down long
+	 * with mem and ctlr clk gating'
+	 */
+	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
+	/* TODO: Needed ? 2.a DENALI_CTL_144[LPI_TIMER_WAKEUP_F2] */
+	//mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(0));
+
+	/*
+	 * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
+	 * the logic to automatic handles low power entry/exit. This is the recommended
+	 * option over handling through software.
+	 * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
+	 * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
+	 * since LPPDR logic will be power gated).
+	 */
+	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
+	mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
+			   0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
+	/* 3.c clock gate ddr controller */
+	mmio_setbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL2, LPDDR_EN_CLKGATE);
+	/* 3.d lpddr max clk div en */
+	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL2, LPDDR_MAX_CLKDIV_EN);
+}
+
+void dram_exit_self_refresh(void)
+{
+	dram_lp_auto_enable();
+}
+
+void dram_enter_retention(void)
+{
+	unsigned int i;
+
+	dram_lp_auto_disable();
+
+	/* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
+
+	/*
+	 * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
+	 * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
+	 * long with mem and ctlr clk gating or self-refresh  power-down
+	 * long with mem and ctlr clk gating'
+	 */
+	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
+
+	/*
+	 * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
+	 * the logic to automatic handles low power entry/exit. This is the recommended
+	 * option over handling through software.
+	 * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
+	 * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
+	 * since LPPDR logic will be power gated).
+	 */
+	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
+	mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
+			   0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
+
+	/* Save DDR Controller & PHY config.
+	 * Set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=1. Read and store all
+	 * the PHY registers for F2 into phy_f1_cfg, then read/store the diff between
+	 * F1 & F2 into phy_f2_cfg.
+	 */
+	if (!dram_cfg_saved) {
+		info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
+		dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
+					sizeof(struct dram_timing_info));
+
+		/* get the dram type */
+		dram_class = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_00);
+		dram_class = (dram_class >> 8) & 0xf;
+
+		/* save the ctl registers */
+		for (i = 0U; i < CTL_NUM; i++) {
+			dram_timing_cfg->ctl_cfg[i] = mmio_read_32(IMX_DDRC_BASE + i * 4);
+		}
+		dram_timing_cfg->ctl_cfg[0] = dram_timing_cfg->ctl_cfg[0] & 0xFFFFFFFE;
+
+		/* save the PI registers */
+		for (i = 0U; i < PI_NUM; i++) {
+			dram_timing_cfg->pi_cfg[i] = mmio_read_32(IMX_DDRC_BASE + 0x2000 + i * 4);
+		}
+		dram_timing_cfg->pi_cfg[0] = dram_timing_cfg->pi_cfg[0] & 0xFFFFFFFE;
+
+		/*
+		 * Read and store all PHY registers. full array is a full
+		 * copy for all the setpoint
+		 */
+		if (dram_class == LPDDR4_TYPE) {
+			mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x10000);
+			for (i = 0U; i < PHY_NUM; i++) {
+				/* Make sure MULTICASE is enabled */
+				if (i == 1537U) {
+					dram_timing_cfg->phy_full[i] = 0x100;
+				} else {
+					dram_timing_cfg->phy_full[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 + i * 4);
+				}
+			}
+
+			/*
+			 * set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=0.
+			 * Read and store only the diff.
+			 */
+			mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
+			/* save only the frequency based diff config to save memory */
+			for (i = 0U; i < PHY_DIFF_NUM; i++) {
+				dram_timing_cfg->phy_diff[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 +
+									    freq_specific_reg_array[i] * 4);
+			}
+		} else {
+			/* LPDDR3, only f1 need to save */
+			for (i = 0U; i < info->phy_f1_cfg_num; i++) {
+				info->phy_f1_cfg[i].val = mmio_read_32(info->phy_f1_cfg[i].reg);
+			}
+		}
+
+		dram_cfg_saved = true;
+	}
+}
+
+void dram_exit_retention(void)
+{
+	uint32_t val;
+
+	/* 1. Config the LPAV PLL4 and DDR clock for the desired LPDDR operating frequency. */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
+
+	/* 2. Write PCC5.PCC_LPDDR4[SWRST] to 1b'1 to release LPDDR from reset. */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(28));
+
+	/* 3. Reload the LPDDR CTL/PI/PHY register */
+	ddr_init();
+
+	if (dram_class == LPDDR4_TYPE) {
+		/* 4a. FIXME Set PHY_SET_DFI_INPUT_N parameters to 4'h1. LPDDR4 only */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1559, 0x01010101);
+
+		/*
+		 * 4b. CTL PWRUP_SREFRESH_EXIT=1'b0 for disabling self refresh exit
+		 * from controller.
+		 */
+		/*
+		 * 4c. PI_PWRUP_SELF_REF_EXIT=1, PI_MC_PWRUP_SELF_REF_EXIT=0 for enabling
+		 * self refresh exit from PI
+		 */
+		/* 4c. PI_INT_LVL_EN=0 to skip Initialization trainings. */
+		/*
+		 * 4d. PI_WRLVL_EN_F0/1/2= PI_CALVL_EN_F0/1/2= PI_RDLVL_EN_F0/1/2=
+		 * PI_RDLVL_GATE_EN_F0/1/2= PI_WDQLVL_EN_F0/1/2=0x2.
+		 * Enable non initialization trainings.
+		 */
+		/* 4e. PI_PWRUP_SREFRESH_EXIT_CS=0xF */
+		/* 4f. PI_DLL_RESET=0x1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
+		/* PI_PWRUP_SELF_REF_EXIT = 1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
+		/* PI_MC_PWRUP_SELF_REF_EXIT = 0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
+		/* PI_INT_LVL_EN = 0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
+		/* PI_WRLVL_EN_F0 = 3, PI_WRLVL_EN_F1 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x03030000);
+		/* PI_WRLVL_EN_F2 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_175, 0x03);
+		/* PI_CALVL_EN_F0 = 3, PI_CALVL_EN_F1 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x03030000);
+		/* PI_CALVL_EN_F2 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_192, 0x03);
+		/* PI_WDQLVL_EN_F0 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_212, 0x300);
+		/* PI_WDQLVL_EN_F1 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_214, 0x03000000);
+		/* PI_WDQLVL_EN_F2 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_217, 0x300);
+		/* PI_EDLVL_EN_F0 = 3, PI_EDLVL_GATE_EN_F0 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
+		/*
+		 * PI_RDLVL_EN_F1 = 3, PI_RDLVL_GATE_EN_F1 = 3,
+		 * PI_RDLVL_EN_F2 = 3, PI_RDLVL_GATE_EN_F2 = 3
+		 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_182, 0x03030303);
+		/* PI_PWRUP_SREFRESH_EXIT_CS = 0xF */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
+	} else {
+		/* PI_DLL_RESET=1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
+		/* PI_PWRUP_SELF_REF_EXIT=1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
+		/* PI_MC_PWRUP_SELF_REF_EXIT=0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
+		/* PI_INT_LVL_EN=0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
+		/* PI_WRLVL_EN_F0=3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x00030000);
+		/* PI_CALVL_EN_F0=3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x00030000);
+		/* PI_RDLVL_EN_F0=3,PI_RDLVL_GATE_EN_F0=3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
+		/* PI_PWRUP_SREFRESH_EXIT_CS=0xF */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
+	}
+
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x00002D00);
+
+	/* Force in-order AXI read data */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x1);
+
+	/*
+	 * Disable special R/W group switches so that R/W group placement
+	 * is always at END of R/W group.
+	 */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_249, 0x0);
+
+	/* Reduce time for IO pad calibration */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1590, 0x01000000);
+
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_25, 0x00020100);
+
+	/* PD disable */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_153, 0x04040000);
+	/*
+	 * 5. Disable automatic LP entry and PCPCS modes LP_AUTO_ENTRY_EN
+	 * to 1b'0, PCPCS_PD_EN to 1b'0
+	 */
+
+	upwr_xcp_set_ddr_retention(APD_DOMAIN, 0, NULL);
+	upower_wait_resp();
+
+	if (dram_class == LPDDR4_TYPE) {
+		/* 7. Write PI START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000b01);
+
+		/* 8. Write CTL START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000b01);
+	} else {
+		/* 7. Write PI START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000701);
+
+		/* 8. Write CTL START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000701);
+	}
+
+	/* 9. DENALI_CTL_266:  Wait for INT_STATUS_INIT=0x2 */
+	do {
+		val = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_266) >> 8) & 0xFF;
+	} while (val != 0x2);
+
+	/*
+	 * 10. Run SW trainings by setting PI_CALVL_REQ,PI_WRLVL_REQ,PI_RDLVL_GATE_REQ,
+	 * PI_RDLVL_REQ,PI_WDQLVL_REQ(NA for LPDDR3) in same order.
+	 */
+	if (dram_class == LPDDR4_TYPE) {
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_65, 0x10000); /* WDQLVL */
+
+		/* 11. Wait for trainings to get complete by polling PI_INT_STATUS */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x07E00000) != 0x07E00000) {
+			;
+		}
+	} else {
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x05E00000) != 0x05E00000) {
+			;
+		}
+	}
+
+	dram_lp_auto_enable();
+}
+
+#define LPDDR_DONE       (0x1<<4)
+#define SOC_FREQ_CHG_ACK (0x1<<6)
+#define SOC_FREQ_CHG_REQ (0x1<<7)
+#define LPI_WAKEUP_EN    (0x4<<8)
+#define SOC_FREQ_REQ     (0x1<<11)
+
+static void set_cgc2_ddrclk(uint8_t src, uint8_t div)
+{
+
+	/* Wait until the reg is unlocked for writing */
+	while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31))
+		;
+
+	mmio_write_32(IMX_CGC2_BASE + 0x40, (src << 28) | (div << 21));
+	/* Wait for the clock switching done */
+	while (!(mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(27)))
+		;
+}
+static void set_ddr_clk(uint32_t ddr_freq)
+{
+	/* Disable DDR clock */
+	mmio_clrbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
+	switch (ddr_freq) {
+	/* boot frequency ? */
+	case 48:
+		set_cgc2_ddrclk(2, 0);
+		break;
+	/* default bypass frequency for fsp 1 */
+	case 192:
+		set_cgc2_ddrclk(0, 1);
+		break;
+	case 384:
+		set_cgc2_ddrclk(0, 0);
+		break;
+	case 264:
+		set_cgc2_ddrclk(4, 3);
+		break;
+	case 528:
+		set_cgc2_ddrclk(4, 1);
+		break;
+	default:
+		break;
+	}
+	/* Enable DDR clock */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
+
+	/* Wait until the reg is unlocked for writing */
+	while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31)) {
+		;
+	}
+}
+
+#define AVD_SIM_LPDDR_CTRL	(IMX_LPAV_SIM_BASE + 0x14)
+#define AVD_SIM_LPDDR_CTRL2	(IMX_LPAV_SIM_BASE + 0x18)
+#define MAX_FSP_NUM	U(3)
+#define DDR_DFS_GET_FSP_COUNT	0x10
+#define DDR_BYPASS_DRATE	U(400)
+
+extern int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val);
+
+/* Normally, we only switch frequency between 1(bypass) and 2(highest) */
+int lpddr4_dfs(uint32_t freq_index)
+{
+	uint32_t lpddr_ctrl, lpddr_ctrl2;
+	uint32_t ddr_ctl_144;
+
+	/*
+	 * Valid index: 0 to 2
+	 * index 0: boot frequency
+	 * index 1: bypass frequency
+	 * index 2: highest frequency
+	 */
+	if (freq_index > 2U) {
+		return -1;
+	}
+
+	/*
+	 * increase the voltage to 1.1V firstly before increase frequency
+	 * and APD enter OD mode
+	 */
+	if (freq_index == 2U && sys_dvfs) {
+		upower_pmic_i2c_write(0x22, 0x28);
+	}
+
+	/* Enable LPI_WAKEUP_EN */
+	ddr_ctl_144 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
+	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, LPI_WAKEUP_EN);
+
+	/* put DRAM into long self-refresh & clock gating */
+	lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
+	lpddr_ctrl = (lpddr_ctrl & ~((0x3f << 15) | (0x3 << 9))) | (0x28 << 15) | (freq_index << 9);
+	mmio_write_32(AVD_SIM_LPDDR_CTRL, lpddr_ctrl);
+
+	/* Gating the clock */
+	lpddr_ctrl2 = mmio_read_32(AVD_SIM_LPDDR_CTRL2);
+	mmio_setbits_32(AVD_SIM_LPDDR_CTRL2, LPDDR_EN_CLKGATE);
+
+	/* Request frequency change */
+	mmio_setbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_REQ);
+
+	do {
+		lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
+		if (lpddr_ctrl & SOC_FREQ_CHG_REQ) {
+			/* Bypass mode */
+			if (info->fsp_table[freq_index] < DDR_BYPASS_DRATE) {
+				/* Change to PLL bypass mode */
+				mmio_write_32(IMX_LPAV_SIM_BASE, 0x1);
+				/* change the ddr clock source & frequency */
+				set_ddr_clk(info->fsp_table[freq_index]);
+			} else {
+				/* Change to PLL unbypass mode */
+				mmio_write_32(IMX_LPAV_SIM_BASE, 0x0);
+				/* change the ddr clock source & frequency */
+				set_ddr_clk(info->fsp_table[freq_index] >> 1);
+			}
+
+			mmio_clrsetbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_CHG_REQ, SOC_FREQ_CHG_ACK);
+			continue;
+		}
+	} while ((lpddr_ctrl & LPDDR_DONE) != 0); /* several try? */
+
+	/* restore the original setting */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, ddr_ctl_144);
+	mmio_write_32(AVD_SIM_LPDDR_CTRL2, lpddr_ctrl2);
+
+	/* Check the DFS result */
+	lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL) & 0xF;
+	if (lpddr_ctrl != 0U) {
+		/* Must be something wrong, return failure */
+		return -1;
+	}
+
+	/* decrease the BUCK3 voltage after frequency changed to lower
+	 * and APD in ND_MODE
+	 */
+	if (freq_index == 1U && sys_dvfs) {
+		upower_pmic_i2c_write(0x22, 0x20);
+	}
+
+	/* DFS done successfully */
+	return 0;
+}
+
+/* for the non-primary core, waiting for DFS done */
+static uint64_t waiting_dvfs(uint32_t id, uint32_t flags,
+		void *handle, void *cookie)
+{
+	uint32_t irq;
+
+	irq = plat_ic_acknowledge_interrupt();
+	if (irq < 1022U) {
+		plat_ic_end_of_interrupt(irq);
+	}
+
+	/* set the WFE done status */
+	spin_lock(&dfs_lock);
+	core_count++;
+	dsb();
+	spin_unlock(&dfs_lock);
+
+	while (in_progress) {
+		wfe();
+	}
+
+	return 0;
+}
+
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+		u_register_t x1, u_register_t x2, u_register_t x3)
+{
+	unsigned int fsp_index = x1;
+	uint32_t online_cpus = x2 - 1;
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+	/* Get the number of FSPs */
+	if (x1 == DDR_DFS_GET_FSP_COUNT) {
+		SMC_RET2(handle, num_fsp, info->fsp_table[1]);
+	}
+
+	/* start lpddr frequency scaling */
+	in_progress = true;
+	sys_dvfs = x3 ? true : false;
+	dsb();
+
+	/* notify other core wait for scaling done */
+	for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++)
+		/* Skip raise SGI for current CPU */
+		if (i != cpu_id) {
+			plat_ic_raise_el3_sgi(0x8, i);
+		}
+
+	/* Make sure all the cpu in WFE */
+	while (online_cpus != core_count) {
+		;
+	}
+
+	/* Flush the L1/L2 cache */
+	dcsw_op_all(DCCSW);
+
+	lpddr4_dfs(fsp_index);
+
+	in_progress = false;
+	core_count = 0;
+	dsb();
+	sev();
+	isb();
+
+	SMC_RET1(handle, 0);
+}
+
+void dram_init(void)
+{
+	uint32_t flags = 0;
+	uint32_t rc;
+	unsigned int i;
+
+	/* Register the EL3 handler for DDR DVFS */
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3, waiting_dvfs, flags);
+	if (rc) {
+		panic();
+	}
+
+	info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
+
+	/* Get the num of the supported Fsp */
+	for (i = 0; i < MAX_FSP_NUM; i++) {
+		if (!info->fsp_table[i]) {
+			break;
+		}
+	}
+
+	num_fsp = (i > MAX_FSP_NUM) ? MAX_FSP_NUM : i;
+}
diff --git a/plat/imx/imx8ulp/imx8ulp_bl31_setup.c b/plat/imx/imx8ulp/imx8ulp_bl31_setup.c
new file mode 100644
index 0000000..696f4b6
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_bl31_setup.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <dram.h>
+#include <imx8_lpuart.h>
+#include <imx8ulp_caam.h>
+#include <imx_plat_common.h>
+#include <plat_imx8.h>
+#include <upower_api.h>
+#include <xrdc.h>
+
+#define MAP_BL31_TOTAL										   \
+	MAP_REGION_FLAT(BL31_BASE, BL31_LIMIT - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO										   \
+	MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+#define MAP_BL32_TOTAL MAP_REGION_FLAT(BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW)
+#define MAP_COHERENT_MEM									\
+	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),	\
+			 MT_DEVICE | MT_RW | MT_SECURE)
+
+#define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
+
+static const mmap_region_t imx_mmap[] = {
+	DEVICE0_MAP, DEVICE1_MAP, DEVICE2_MAP,
+	ELE_MAP, SEC_SIM_MAP, SRAM0_MAP,
+	{0}
+};
+
+extern uint32_t upower_init(void);
+extern void imx8ulp_init_scmi_server(void);
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+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;
+
+	/* config the TPM5 clock */
+	mmio_write_32(IMX_PCC3_BASE + 0xd0, 0x92000000);
+	mmio_write_32(IMX_PCC3_BASE + 0xd0, 0xd2000000);
+
+	/* enable the GPIO D,E,F non-secure access by default */
+	mmio_write_32(IMX_PCC4_BASE + 0x78, 0xc0000000);
+	mmio_write_32(IMX_PCC4_BASE + 0x7c, 0xc0000000);
+	mmio_write_32(IMX_PCC5_BASE + 0x114, 0xc0000000);
+
+	mmio_write_32(IMX_GPIOE_BASE + 0x10, 0xffffffff);
+	mmio_write_32(IMX_GPIOE_BASE + 0x14, 0x3);
+	mmio_write_32(IMX_GPIOE_BASE + 0x18, 0xffffffff);
+	mmio_write_32(IMX_GPIOE_BASE + 0x1c, 0x3);
+
+	mmio_write_32(IMX_GPIOF_BASE + 0x10, 0xffffffff);
+	mmio_write_32(IMX_GPIOF_BASE + 0x14, 0x3);
+	mmio_write_32(IMX_GPIOF_BASE + 0x18, 0xffffffff);
+	mmio_write_32(IMX_GPIOF_BASE + 0x1c, 0x3);
+
+	mmio_write_32(IMX_GPIOD_BASE + 0x10, 0xffffffff);
+	mmio_write_32(IMX_GPIOD_BASE + 0x14, 0x3);
+	mmio_write_32(IMX_GPIOD_BASE + 0x18, 0xffffffff);
+	mmio_write_32(IMX_GPIOD_BASE + 0x1c, 0x3);
+
+	console_lpuart_register(IMX_LPUART_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 | CONSOLE_FLAG_RUNTIME);
+
+	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+	bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#if defined(SPD_opteed) || defined(SPD_trusty)
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = 0;
+
+	/* Pass TEE base and size to bl33 */
+	bl33_image_ep_info.args.arg1 = BL32_BASE;
+	bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+#ifdef SPD_trusty
+	bl32_image_ep_info.args.arg0 = BL32_SIZE;
+	bl32_image_ep_info.args.arg1 = BL32_BASE;
+#else
+	/* Make sure memory is clean */
+	mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+	bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
+#endif
+}
+
+void bl31_plat_arch_setup(void)
+{
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
+#if USE_COHERENT_MEM
+		MAP_COHERENT_MEM,
+#endif
+#if defined(SPD_opteed) || defined(SPD_trusty)
+		MAP_BL32_TOTAL,
+#endif
+		{0},
+	};
+
+	setup_page_tables(bl_regions, imx_mmap);
+	enable_mmu_el3(0);
+
+	/* TODO: Hack, refine this piece, scmi channel free */
+	mmio_write_32(SRAM0_BASE + 0x4, 1);
+
+	/* Allow M core to reset A core */
+	mmio_clrbits_32(IMX_MU0B_BASE + 0x10, BIT(2));
+}
+
+void bl31_platform_setup(void)
+{
+	/* select the arch timer source */
+	mmio_setbits_32(IMX_SIM1_BASE + 0x30, 0x8000000);
+
+	generic_delay_timer_init();
+
+	plat_gic_driver_init();
+	plat_gic_init();
+
+	imx8ulp_init_scmi_server();
+	upower_init();
+
+	xrdc_apply_apd_config();
+	xrdc_apply_lpav_config();
+	xrdc_enable();
+
+	imx8ulp_caam_init();
+
+	dram_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	} else {
+		return &bl32_image_ep_info;
+	}
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return COUNTER_FREQUENCY;
+}
+
+void bl31_plat_runtime_setup(void)
+{
+}
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+	args->arg0 = BL32_SIZE;
+	args->arg1 = BL32_BASE;
+	args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8ulp/imx8ulp_caam.c b/plat/imx/imx8ulp/imx8ulp_caam.c
new file mode 100644
index 0000000..d150fe2
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_caam.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2021-2024 NXP.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <imx8ulp_caam.h>
+
+void imx8ulp_caam_init(void)
+{
+	/* config CAAM JRaMID set MID to Cortex A */
+	mmio_write_32(CAAM_JR0MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR1MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR2MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR3MID, CAAM_NS_MID);
+}
diff --git a/plat/imx/imx8ulp/imx8ulp_psci.c b/plat/imx/imx8ulp/imx8ulp_psci.c
new file mode 100644
index 0000000..628acea
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_psci.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <plat_imx8.h>
+#include <upower_api.h>
+
+extern void cgc1_save(void);
+extern void cgc1_restore(void);
+extern void imx_apd_ctx_save(unsigned int cpu);
+extern void imx_apd_ctx_restore(unsigned int cpu);
+extern void usb_wakeup_enable(bool enable);
+extern void upower_wait_resp(void);
+extern bool is_lpav_owned_by_apd(void);
+extern void apd_io_pad_off(void);
+extern int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val);
+extern void imx8ulp_init_scmi_server(void);
+
+static uintptr_t secure_entrypoint;
+
+#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
+#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
+
+#define RVBARADDRx(c)		(IMX_SIM1_BASE + 0x5c + 0x4 * (c))
+#define WKPUx(c)		(IMX_SIM1_BASE + 0x3c + 0x4 * (c))
+#define AD_COREx_LPMODE(c)	(IMX_CMC1_BASE + 0x50 + 0x4 * (c))
+
+#define PMIC_CFG(v, m, msk)		\
+	{				\
+		.volt = (v),		\
+		.mode = (m),		\
+		.mode_msk = (msk),	\
+	}
+
+#define PAD_CFG(c, r, t)		\
+	{				\
+		.pad_close = (c),	\
+		.pad_reset = (r),	\
+		.pad_tqsleep = (t)	\
+	}
+
+#define BIAS_CFG(m, n, p, mbias)	\
+	{				\
+		.dombias_cfg = {	\
+			.mode = (m),	\
+			.rbbn = (n),	\
+			.rbbp = (p),	\
+		},			\
+		.membias_cfg = {mbias},	\
+	}
+
+#define SWT_BOARD(swt_on, msk)	\
+	{			\
+		.on = (swt_on),	\
+		.mask = (msk),	\
+	}
+
+#define SWT_MEM(a, p, m)	\
+	{			\
+		.array = (a),	\
+		.perif = (p),	\
+		.mask = (m),	\
+	}
+
+static int imx_pwr_set_cpu_entry(unsigned int cpu, unsigned int entry)
+{
+	mmio_write_32(RVBARADDRx(cpu), entry);
+
+	/* set update bit */
+	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(24 + cpu));
+	/* wait for ack */
+	while (!(mmio_read_32(IMX_SIM1_BASE + 0x8) & BIT_32(26 + cpu))) {
+	}
+
+	/* clear update bit */
+	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) & ~BIT_32(24 + cpu));
+	/* clear ack bit */
+	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(26 + cpu));
+
+	return 0;
+}
+
+static volatile uint32_t cgc1_nicclk;
+int imx_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr);
+
+	imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
+
+	/* slow down the APD NIC bus clock */
+	cgc1_nicclk = mmio_read_32(IMX_CGC1_BASE + 0x34);
+	mmio_clrbits_32(IMX_CGC1_BASE + 0x34, GENMASK_32(29, 28));
+
+	mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
+	mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0);
+
+	/* enable wku wakeup for idle */
+	mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0xffffffff);
+
+	return PSCI_E_SUCCESS;
+}
+
+void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
+	plat_gic_pcpu_init();
+	plat_gic_cpuif_enable();
+
+	/* set APD NIC back to orignally setting */
+	mmio_write_32(IMX_CGC1_BASE + 0x34, cgc1_nicclk);
+}
+
+int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
+{
+	return PSCI_E_SUCCESS;
+}
+
+void imx_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
+
+	plat_gic_cpuif_disable();
+
+	/* disable wakeup */
+	mmio_write_32(WKPUx(cpu), 0);
+
+	/* set core power mode to PD */
+	mmio_write_32(AD_COREx_LPMODE(cpu), 0x3);
+}
+
+/* APD power mode config */
+ps_apd_pwr_mode_cfgs_t apd_pwr_mode_cfgs = {
+	[DPD_PWR_MODE] = {
+		.swt_board_offs = 0x180,
+		.swt_mem_offs = 0x188,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a02),
+		.bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0),
+	},
+
+	/* PD */
+	[PD_PWR_MODE] = {
+		.swt_board_offs = 0x170,
+		.swt_mem_offs = 0x178,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a00),
+		.bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0),
+	},
+
+	[ADMA_PWR_MODE] = {
+		.swt_board_offs = 0x120,
+		.swt_mem_offs = 0x128,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00),
+		.bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0),
+	},
+
+	[ACT_PWR_MODE] = {
+		.swt_board_offs = 0x110,
+		.swt_mem_offs = 0x118,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00),
+		.bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0),
+	},
+};
+
+/* APD power switch config */
+ps_apd_swt_cfgs_t apd_swt_cfgs = {
+	[DPD_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x0, 0x1fffc),
+		.swt_mem[0] = SWT_MEM(0x0, 0x0, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
+	},
+
+	[PD_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x0, 0x00001fffc),
+		.swt_mem[0] = SWT_MEM(0x00010c00, 0x0, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003f0000, 0x0),
+	},
+
+	[ADMA_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x15f74, 0x15f74),
+		.swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
+	},
+
+	[ACT_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x15f74, 0x15f74),
+		.swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
+	},
+};
+
+/* PMIC config for power down, LDO1 should be OFF */
+ps_apd_pmic_reg_data_cfgs_t pd_pmic_reg_cfgs = {
+	[0] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = PD_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9c,
+	},
+	[1] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = PD_PWR_MODE,
+		.i2c_addr = 0x22,
+		.i2c_data = 0xb,
+	},
+	[2] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9d,
+	},
+	[3] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x22,
+		.i2c_data = 0x28,
+	},
+};
+
+/* PMIC config for deep power down, BUCK3 should be OFF */
+ps_apd_pmic_reg_data_cfgs_t dpd_pmic_reg_cfgs = {
+	[0] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = DPD_PWR_MODE,
+		.i2c_addr = 0x21,
+		.i2c_data = 0x78,
+	},
+	[1] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = DPD_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9c,
+	},
+	[2] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x21,
+		.i2c_data = 0x79,
+	},
+	[3] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9d,
+	},
+};
+
+struct ps_pwr_mode_cfg_t *pwr_sys_cfg = (struct ps_pwr_mode_cfg_t *)UPWR_DRAM_SHARED_BASE_ADDR;
+
+void imx_set_pwr_mode_cfg(abs_pwr_mode_t mode)
+{
+	uint32_t volt;
+
+	if (mode >= NUM_PWR_MODES) {
+		return;
+	}
+
+	/* apd power mode config */
+	memcpy(&pwr_sys_cfg->ps_apd_pwr_mode_cfg[mode], &apd_pwr_mode_cfgs[mode],
+		 sizeof(struct ps_apd_pwr_mode_cfg_t));
+
+	/* apd power switch config */
+	memcpy(&pwr_sys_cfg->ps_apd_swt_cfg[mode], &apd_swt_cfgs[mode], sizeof(swt_config_t));
+
+	/*
+	 * BUCK3 & LDO1 can only be shutdown when LPAV is owned by APD side
+	 * otherwise RTD side is responsible to control them in low power mode.
+	 */
+	if (is_lpav_owned_by_apd()) {
+		/* power off the BUCK3 in DPD mode */
+		if (mode == DPD_PWR_MODE) {
+			memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &dpd_pmic_reg_cfgs,
+				 sizeof(ps_apd_pmic_reg_data_cfgs_t));
+		/* LDO1 should be power off in PD mode */
+		} else if (mode == PD_PWR_MODE) {
+			/* overwrite the buck3 voltage setting in active mode */
+			upower_pmic_i2c_read(0x22, &volt);
+			pd_pmic_reg_cfgs[3].i2c_data = volt;
+			memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &pd_pmic_reg_cfgs,
+				 sizeof(ps_apd_pmic_reg_data_cfgs_t));
+		}
+	}
+}
+
+void imx_domain_suspend(const psci_power_state_t *target_state)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
+
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		plat_gic_cpuif_disable();
+		imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
+		/* core put into power down */
+		mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x3);
+		/* FIXME config wakeup interrupt in WKPU */
+		mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3);
+	} else {
+		/* for core standby/retention mode */
+		mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x1);
+		mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3);
+		dsb();
+		write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+		isb();
+	}
+
+	if (is_local_state_retn(CLUSTER_PWR_STATE(target_state))) {
+		/*
+		 * just for sleep mode for now, need to update to
+		 * support more modes, same for suspend finish call back.
+		 */
+		mmio_write_32(IMX_CMC1_BASE + 0x10, 0x1);
+		mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1);
+
+	} else if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+		/*
+		 * for cluster off state, put cluster into power down mode,
+		 * config the cluster clock to be off.
+		 */
+		mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7);
+		mmio_write_32(IMX_CMC1_BASE + 0x20, 0xf);
+	}
+
+	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+		/*
+		 * low power mode config info used by upower
+		 * to do low power mode transition.
+		 */
+		imx_set_pwr_mode_cfg(ADMA_PWR_MODE);
+		imx_set_pwr_mode_cfg(ACT_PWR_MODE);
+		imx_set_pwr_mode_cfg(PD_PWR_MODE);
+
+		/* clear the upower wakeup */
+		upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
+		upower_wait_resp();
+
+		/* enable the USB wakeup */
+		usb_wakeup_enable(true);
+
+		/* config the WUU to enabled the wakeup source */
+		mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000);
+
+		/* !!! clear all the pad wakeup pending event */
+		mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
+
+		/* enable upower usb phy wakeup by default */
+		mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4) | BIT(1) | BIT(0));
+
+		/* enabled all pad wakeup by default */
+		mmio_write_32(IMX_WUU1_BASE + 0x8, 0xffffffff);
+
+		/* save the AD domain context before entering PD mode */
+		imx_apd_ctx_save(cpu);
+	}
+}
+
+#define DRAM_LPM_STATUS		U(0x2802b004)
+void imx_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
+
+	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+		/* restore the ap domain context */
+		imx_apd_ctx_restore(cpu);
+
+		/* clear the upower wakeup */
+		upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
+		upower_wait_resp();
+
+		/* disable all pad wakeup */
+		mmio_write_32(IMX_WUU1_BASE + 0x8, 0x0);
+
+		/* clear all the pad wakeup pending event */
+		mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
+
+		/*
+		 * disable the usb wakeup after resume to make sure the pending
+		 * usb wakeup in WUU can be cleared successfully, otherwise,
+		 * APD will resume failed in next PD mode.
+		 */
+		usb_wakeup_enable(false);
+
+		/* re-init the SCMI channel */
+		imx8ulp_init_scmi_server();
+	}
+
+	/*
+	 * wait for DDR is ready when DDR is under the RTD
+	 * side control for power saving
+	 */
+	while (mmio_read_32(DRAM_LPM_STATUS) != 0) {
+		;
+	}
+
+	/*
+	 * when resume from low power mode, need to delay for a while
+	 * before access the CMC register.
+	 */
+	udelay(5);
+
+	/* clear cluster's LPM setting. */
+	mmio_write_32(IMX_CMC1_BASE + 0x20, 0x0);
+	mmio_write_32(IMX_CMC1_BASE + 0x10, 0x0);
+
+	/* clear core's LPM setting */
+	mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x0);
+	mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x0);
+
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
+		plat_gic_cpuif_enable();
+	} else {
+		dsb();
+		write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+		isb();
+	}
+}
+
+void __dead2 imx8ulp_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+	while (1) {
+		wfi();
+	}
+}
+
+void __dead2 imx8ulp_system_reset(void)
+{
+	imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
+
+	/* Write invalid command to WDOG CNT to trigger reset */
+	mmio_write_32(IMX_WDOG3_BASE + 0x4, 0x12345678);
+
+	while (true) {
+		wfi();
+	}
+}
+
+int imx_validate_power_state(unsigned int power_state,
+			 psci_power_state_t *req_state)
+{
+	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	int pwr_type = psci_get_pstate_type(power_state);
+
+	if (pwr_lvl > PLAT_MAX_PWR_LVL) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (pwr_type == PSTATE_TYPE_STANDBY) {
+		CORE_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+		CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+	}
+
+	/* No power down state support */
+	if (pwr_type == PSTATE_TYPE_POWERDOWN) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+
+	for (i = IMX_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = PLAT_POWER_DOWN_OFF_STATE;
+	}
+}
+
+void __dead2 imx_system_off(void)
+{
+	unsigned int i;
+
+	/* config the all the core into OFF mode and IRQ masked. */
+	for (i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		/* disable wakeup from wkpu */
+		mmio_write_32(WKPUx(i), 0x0);
+
+		/* reset the core reset entry to 0x1000 */
+		imx_pwr_set_cpu_entry(i, 0x1000);
+
+		/* config the core power mode to off */
+		mmio_write_32(AD_COREx_LPMODE(i), 0x3);
+	}
+
+	plat_gic_cpuif_disable();
+
+	/* power off all the pad */
+	apd_io_pad_off();
+
+	/* Config the power mode info for entering DPD mode and ACT mode */
+	imx_set_pwr_mode_cfg(ADMA_PWR_MODE);
+	imx_set_pwr_mode_cfg(ACT_PWR_MODE);
+	imx_set_pwr_mode_cfg(DPD_PWR_MODE);
+
+	/* Set the APD domain into DPD mode */
+	mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7);
+	mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1f);
+
+	/* make sure no pending upower wakeup */
+	upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
+	upower_wait_resp();
+
+	/* enable the upower wakeup from wuu, act as APD boot up method  */
+	mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000);
+	mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4));
+
+	/* make sure no pad wakeup event is pending */
+	mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
+
+	wfi();
+
+	ERROR("power off failed.\n");
+	panic();
+}
+
+static const plat_psci_ops_t imx_plat_psci_ops = {
+	.pwr_domain_on = imx_pwr_domain_on,
+	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
+	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
+	.system_off = imx_system_off,
+	.system_reset = imx8ulp_system_reset,
+	.pwr_domain_off = imx_pwr_domain_off,
+	.pwr_domain_suspend = imx_domain_suspend,
+	.pwr_domain_suspend_finish = imx_domain_suspend_finish,
+	.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+	.validate_power_state = imx_validate_power_state,
+	.pwr_domain_pwr_down_wfi = imx8ulp_pwr_domain_pwr_down_wfi,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	secure_entrypoint = sec_entrypoint;
+	imx_pwr_set_cpu_entry(0, sec_entrypoint);
+	*psci_ops = &imx_plat_psci_ops;
+
+	mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
+	mmio_write_32(IMX_SIM1_BASE + 0x3c, 0xffffffff);
+
+	return 0;
+}
diff --git a/plat/imx/imx8ulp/include/dram.h b/plat/imx/imx8ulp/include/dram.h
new file mode 100644
index 0000000..9ed8969
--- /dev/null
+++ b/plat/imx/imx8ulp/include/dram.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRAM_H
+#define DRAM_H
+
+void dram_init(void);
+
+#endif /* DRAM_H */
+
diff --git a/plat/imx/imx8ulp/include/imx8ulp_caam.h b/plat/imx/imx8ulp/include/imx8ulp_caam.h
new file mode 100644
index 0000000..1b93d7d
--- /dev/null
+++ b/plat/imx/imx8ulp/include/imx8ulp_caam.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021-2024 NXP.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8ULP_CAAM_H
+#define IMX8ULP_CAAM_H
+
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+#define CAAM_JR0MID		(IMX_CAAM_BASE + 0x10)
+#define CAAM_JR1MID		(IMX_CAAM_BASE + 0x18)
+#define CAAM_JR2MID		(IMX_CAAM_BASE + 0x20)
+#define CAAM_JR3MID		(IMX_CAAM_BASE + 0x28)
+#define CAAM_NS_MID		(0x7)
+
+#define JR0_BASE		(IMX_CAAM_BASE + 0x1000)
+
+void imx8ulp_caam_init(void);
+
+#endif /* IMX8ULP_CAAM_H */
diff --git a/plat/imx/imx8ulp/include/platform_def.h b/plat/imx/imx8ulp/include/platform_def.h
new file mode 100644
index 0000000..20c5851
--- /dev/null
+++ b/plat/imx/imx8ulp/include/platform_def.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define PLATFORM_STACK_SIZE		0x400
+#define CACHE_WRITEBACK_GRANULE		64
+
+#define PLAT_PRIMARY_CPU		0x0
+#define PLATFORM_MAX_CPU_PER_CLUSTER	2
+#define PLATFORM_CLUSTER_COUNT		1
+#define PLATFORM_CORE_COUNT		2
+#define PLATFORM_CLUSTER0_CORE_COUNT	2
+#define PLATFORM_CLUSTER1_CORE_COUNT	0
+
+#define IMX_PWR_LVL0			MPIDR_AFFLVL0
+#define IMX_PWR_LVL1			MPIDR_AFFLVL1
+#define IMX_PWR_LVL2			MPIDR_AFFLVL2
+
+#define PWR_DOMAIN_AT_MAX_LVL		U(1)
+#define PLAT_MAX_PWR_LVL		U(2)
+
+#define PLAT_SLEEP_RET_STATE		U(1)
+#define PLAT_DEEP_SLEEP_RET_STATE	U(2)
+#define PLAT_MAX_RET_STATE		U(3)
+
+#define PLAT_POWER_DOWN_OFF_STATE	U(4)
+#define PLAT_DEEP_POWER_DOWN_STATE	U(5)
+#define PLAT_MAX_OFF_STATE		U(6)
+
+#define BL31_BASE			0x20040000
+#define BL31_LIMIT			0x20070000
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
+
+#ifdef SPD_trusty
+#define MAX_XLAT_TABLES			11
+#define MAX_MMAP_REGIONS		12
+#else
+#define MAX_XLAT_TABLES			10
+#define MAX_MMAP_REGIONS		11
+#endif
+
+#define PLAT_GICD_BASE			U(0x2d400000)
+#define PLAT_GICR_BASE			U(0x2d440000)
+#define DEVICE0_BASE			U(0x20000000)
+#define DEVICE0_SIZE			U(0x10000000)
+#define DEVICE1_BASE			U(0x30000000)
+#define DEVICE1_SIZE			U(0x10000000)
+#define DEVICE2_BASE			U(0x8ff00000)
+#define DEVICE2_SIZE			U(0x00001000)
+#define IMX_LPUART4_BASE		U(0x29390000)
+#define IMX_LPUART5_BASE		U(0x293a0000)
+#define IMX_LPUART_BASE			IMX_LPUART5_BASE
+#define IMX_CAAM_BASE			U(0x292e0000)
+#define IMX_BOOT_UART_CLK_IN_HZ		24000000
+#define IMX_CONSOLE_BAUDRATE		115200
+
+#define IMX_CGC1_BASE			U(0x292c0000)
+#define IMX_PCC3_BASE			U(0x292d0000)
+#define IMX_PCC4_BASE			U(0x29800000)
+#define IMX_SIM2_BASE			U(0x2da50000)
+#define IMX_CGC2_BASE			U(0x2da60000)
+#define IMX_PCC5_BASE			U(0x2da70000)
+#define IMX_MU0B_BASE			U(0x29220000)
+#define IMX_CMC1_BASE			U(0x29240000)
+#define IMX_WUU1_BASE			U(0x29260000)
+#define IMX_SIM1_BASE			U(0x29290000)
+#define IMX_GPIOD_BASE			U(0x2e200000)
+#define IMX_GPIOE_BASE			U(0x2d000000)
+#define IMX_GPIOF_BASE			U(0x2d010000)
+#define IMX_WDOG3_BASE			U(0x292a0000)
+#define IMX_TPM5_BASE			U(0x29340000)
+
+#define SRAM0_BASE			U(0x2201F000)
+
+#define IOMUXC_PTD_PCR_BASE		U(0x298c0000)
+#define IOMUXC_PTE_PCR_BASE		U(0x298c0080)
+#define IOMUXC_PTF_PCR_BASE		U(0x298c0100)
+#define IOMUXC_PSMI_BASE0		U(0x298c0800)
+#define IOMUXC_PSMI_BASE1		U(0x298c0838)
+#define IOMUXC_PSMI_BASE2		U(0x298c0954)
+#define IOMUXC_PSMI_BASE3		U(0x298c0994)
+#define IOMUXC_PSMI_BASE4		U(0x298c0a58)
+
+#define IMX_ROM_ENTRY			U(0x1000)
+#define COUNTER_FREQUENCY		1000000
+
+#define PLAT_NS_IMAGE_OFFSET		0x80200000
+
+#define BL31_NOBITS_BASE    0x20058000
+#define BL31_NOBITS_LIMIT   0x2006d000
+
+#define BL31_RWDATA_BASE    0x2006d000
+#define BL31_RWDATA_LIMIT   0x20070000
+
+#define BL32_FDT_OVERLAY_ADDR		0x9d000000
+
+#ifdef SPD_trusty
+#define IMX_TRUSTY_STACK_SIZE 0x100
+#endif
+
+/* system memory map define */
+#define DEVICE0_MAP	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW)
+#define DEVICE1_MAP	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW)
+/* Map partial DRAM space for DRAM low-power mode control */
+#define DEVICE2_MAP	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW)
+ /* MU and FSB */
+#define ELE_MAP		MAP_REGION_FLAT(0x27010000, 0x20000, MT_DEVICE | MT_RW | MT_NS)
+#define SEC_SIM_MAP	MAP_REGION_FLAT(0x2802B000, 0x1000, MT_DEVICE | MT_RW | MT_NS) /* SEC SIM */
+/* For SCMI shared memory region */
+#define SRAM0_MAP	MAP_REGION_FLAT(SRAM0_BASE, 0x1000, MT_RW | MT_DEVICE)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8ulp/include/scmi.h b/plat/imx/imx8ulp/include/scmi.h
new file mode 100644
index 0000000..03e16f5
--- /dev/null
+++ b/plat/imx/imx8ulp/include/scmi.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8_SCMI_H
+#define IMX8_SCMI_H
+
+#include <stdint.h>
+
+#define SCMI_SHMEM_CHANNEL_ERROR	BIT_32(1)
+#define SCMI_SHMEM_CHANNEL_FREE		BIT_32(0)
+
+#define SCMI_SHMEM_FLAG_INTR_ENABLED	BIT_32(0)
+
+enum scmi_std_protocol {
+	SCMI_PROTOCOL_BASE = 0x10,
+	SCMI_PROTOCOL_POWER_DOMAIN = 0x11,
+	SCMI_PROTOCOL_SYS_POWER = 0x12,
+	SCMI_PROTOCOL_PERF_DOMAIN = 0x13,
+	SCMI_PROTOCOL_CLK = 0x14,
+	SCMI_PROTOCOL_SENSOR = 0x15,
+	SCMI_PROTOCOL_RESET_DOMAIN = 0x16,
+};
+
+#define MSG_ID(m)	((m) & 0xff)
+#define MSG_TYPE(m)	(((m) >> 8) & 0x3)
+#define MSG_PRO_ID(m)	(((m) >> 10) & 0xff)
+#define MSG_TOKEN(m)	(((m) >> 18) & 0x3ff)
+
+enum {
+	SCMI_POWER_DOMAIN_PROTOCOL	= 0x11,
+	SCMI_SYS_PWR_DOMAIN_PROTOCOL	= 0x12,
+	SCMI_PER_DOMAIN_PROTOCOL	= 0x13,
+	SCMI_CLK_DOMAIN_PROTOCOL	= 0x14,
+	SCMI_SENSOR_PROTOCOL		= 0x15,
+};
+
+#define PROTOCOL_VERSION			0
+#define PROTOCOL_ATTRIBUTES			1
+#define PROTOCOL_MESSAGE_ATTRIBUTES		2
+#define BASE_DISCOVER_VENDOR			3
+#define BASE_DISCOVER_SUB_VENDOR		4
+#define BASE_DISCOVER_IMPLEMENTATION_VERSION	5
+#define BASE_DISCOVER_LIST_PROTOCOLS		6
+#define BASE_DISCOVER_AGENT			7
+#define BASE_NOTIFY_ERRORS			8
+#define BASE_SET_DEVICE_PERMISSIONS		9
+#define BASE_SET_PROTOCOL_PERMISSIONS		0xA
+#define BASE_RESET_AGENT_CONFIGURATION		0xB
+
+enum {
+	SCMI_RET_SUCCESS = 0,
+	SCMI_RET_NOT_SUPPORTED = -1,
+	SCMI_RET_INVALID_PARAMETERS = -2,
+	SCMI_RET_DENIED = -3,
+	SCMI_RET_NOT_FOUND = -4,
+	SCMI_RET_OUT_OF_RANGE = -5,
+	SCMI_RET_BUSY = -6,
+	SCMI_RET_COMMS_ERROR = -7,
+	SCMI_RET_GENERIC_ERROR = -8,
+	SCMI_RET_HARDWARE_ERROR = -9,
+	SCMI_RET_PROTOCOL_ERROR = -10,
+};
+
+#define POWER_DOMAIN_ATTRIBUTES			3
+#define POWER_DOMAIN_SUPPORT_NOTIFICATION	BIT(31)
+#define POWER_DOMAIN_SUPPORT_ASYNCHRONOUS	BIT(30)
+#define POWER_DOMAIN_SUPPORT_SYNCHRONOUS	BIT(29)
+
+#define POWER_STATE_SET			4
+#define POWER_STATE_GET			5
+#define POWER_STATE_NOTIFY		6
+#define	POWER_STATE_CHANGE_REQUESTED_NOTIFY	7
+
+int scmi_power_domain_handler(uint32_t msg_id, void *shmem);
+
+#define PERFORMANCE_DOMAIN_ATTRIBUTES		3
+#define PERFORMANCE_DESCRIBE_LEVELS		4
+#define PERFORMANCE_LIMITS_SET			5
+#define PERFORMANCE_LIMITS_GET			6
+#define PERFORMANCE_LEVEL_SET			7
+#define PERFORMANCE_LEVEL_GET			8
+#define PERFORMANCE_NOTIFY_LIMITS		9
+#define PERFORMANCE_NOTIFY_LEVEL		0xA
+#define PERFORMANCE_DESCRIBE_FAST_CHANNEL	0xB
+
+int scmi_perf_domain_handler(uint32_t msg_id, void *shmem);
+
+#define SENSOR_DESCRIPTION_GET			0x003
+#define SENSOR_CONFIG_SET			0x004
+#define SENSOR_TRIP_POINT_SET			0x005
+#define SENSOR_READING_GET			0x006
+
+int scmi_sensor_handler(uint32_t msg_id, void *shmem);
+
+#define SMC_SHMEM_BASE	0x2201f000
+
+#endif /* IMX8_SCMI_H */
diff --git a/plat/imx/imx8ulp/include/scmi_sensor.h b/plat/imx/imx8ulp/include/scmi_sensor.h
new file mode 100644
index 0000000..5dab898
--- /dev/null
+++ b/plat/imx/imx8ulp/include/scmi_sensor.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ *      System Control and Management Interface (SCMI) support.
+ */
+
+#ifndef INTERNAL_SCMI_SENSOR_H
+#define INTERNAL_SCMI_SENSOR_H
+
+#include <stdint.h>
+
+#define SCMI_PROTOCOL_VERSION_SENSOR UINT32_C(0x10000)
+
+/*
+ * PROTOCOL_ATTRIBUTES
+ */
+struct scmi_sensor_protocol_attributes_p2a {
+	int32_t status;
+	uint32_t attributes;
+	uint32_t sensor_reg_address_low;
+	uint32_t sensor_reg_address_high;
+	uint32_t sensor_reg_len;
+};
+
+/*
+ * SENSOR_READING_GET
+ */
+#define SCMI_SENSOR_PROTOCOL_READING_GET_ASYNC_FLAG_MASK    (1 << 0)
+
+struct scmi_sensor_protocol_reading_get_a2p {
+	uint32_t sensor_id;
+	uint32_t flags;
+};
+
+struct scmi_sensor_protocol_reading_get_p2a {
+	int32_t status;
+	uint32_t sensor_value_low;
+	uint32_t sensor_value_high;
+};
+
+/*
+ * SENSOR_DESCRIPTION_GET
+ */
+ #define SCMI_SENSOR_DESCS_MAX(MAILBOX_SIZE) \
+	((sizeof(struct scmi_sensor_protocol_description_get_p2a) < MAILBOX_SIZE) \
+	? ((MAILBOX_SIZE - \
+	   sizeof(struct scmi_sensor_protocol_description_get_p2a)) \
+	   / sizeof(struct scmi_sensor_desc)) \
+	: 0)
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS              0
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS   11
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS 22
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS   27
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK \
+	(UINT32_C(0xFF) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK \
+	(UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK \
+	(UINT32_C(0x1F) << \
+	SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK \
+	(UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS)
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX \
+	(int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK >> 1)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MIN \
+	(-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX + 1))
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX \
+	(int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK >> 1)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MIN \
+	(-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX + 1))
+
+#define SCMI_SENSOR_DESC_ATTRIBUTES_HIGH(SENSOR_TYPE, UNIT_MULTIPLIER, \
+					 UPDATE_MULTIPLIER, UPDATE_INTERVAL) \
+	( \
+	(((SENSOR_TYPE) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK) | \
+	   (((UNIT_MULTIPLIER) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK) | \
+	   (((UPDATE_MULTIPLIER) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK) | \
+	   (((UPDATE_INTERVAL) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK) \
+	)
+
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS              0
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS   16
+
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK \
+	(UINT32_C(0xFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS)
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK \
+	(UINT32_C(0xFFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS)
+
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS(NUM_DESCS, NUM_REMAINING_DESCS) \
+	( \
+	(((NUM_DESCS) << \
+	  SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS) & \
+	  SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK) | \
+	  (((NUM_REMAINING_DESCS) << \
+	    SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS) & \
+	    SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK) \
+	)
+
+#define SCMI_SENSOR_NAME_LEN    16
+
+struct scmi_sensor_desc {
+	uint32_t sensor_id;
+	uint32_t sensor_attributes_low;
+	uint32_t sensor_attributes_high;
+	char sensor_name[SCMI_SENSOR_NAME_LEN];
+};
+
+struct scmi_sensor_protocol_description_get_a2p {
+	uint32_t desc_index;
+};
+
+struct scmi_sensor_protocol_description_get_p2a {
+	int32_t status;
+	uint32_t num_sensor_flags;
+	struct scmi_sensor_desc sensor_desc[];
+};
+
+/* Event indices */
+enum scmi_sensor_api_idx {
+	SCMI_SENSOR_EVENT_IDX_REQUEST,
+	SCMI_SENSOR_EVENT_IDX_COUNT,
+};
+
+#endif /* INTERNAL_SCMI_SENSOR_H */
diff --git a/plat/imx/imx8ulp/include/xrdc.h b/plat/imx/imx8ulp/include/xrdc.h
new file mode 100644
index 0000000..15250f0
--- /dev/null
+++ b/plat/imx/imx8ulp/include/xrdc.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8ULP_XRDC_H
+#define IMX8ULP_XRDC_H
+
+#define DID_MAX 8
+#define PAC_SLOT_ALL 128
+#define MSC_SLOT_ALL 8
+
+enum xrdc_mda_sa {
+	MDA_SA_S,
+	MDA_SA_NS,
+	MDA_SA_PT, /* pass through master's secure/nonsecure attribute */
+};
+
+struct xrdc_mda_config {
+	uint16_t mda_id;
+	uint16_t did;
+	enum xrdc_mda_sa sa;
+};
+
+struct xrdc_pac_msc_config {
+	uint16_t pac_msc_id;
+	uint16_t slot_id;
+	uint8_t dsel[DID_MAX];
+};
+
+struct xrdc_mrc_config {
+	uint16_t mrc_id;
+	uint16_t region_id;
+	uint32_t region_start;
+	uint32_t region_size;
+	uint8_t dsel[DID_MAX];
+	uint16_t accset[2];
+};
+
+/* APIs to apply and enable XRDC */
+int xrdc_apply_lpav_config(void);
+int xrdc_apply_hifi_config(void);
+int xrdc_apply_apd_config(void);
+void xrdc_enable(void);
+
+#endif
diff --git a/plat/imx/imx8ulp/platform.mk b/plat/imx/imx8ulp/platform.mk
new file mode 100644
index 0000000..f1e53ca
--- /dev/null
+++ b/plat/imx/imx8ulp/platform.mk
@@ -0,0 +1,69 @@
+#
+# Copyright 2021-2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iplat/imx/imx8ulp/include		\
+				-Iplat/imx/common/include		\
+				-Iplat/imx/imx8ulp/upower
+
+IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
+				plat/common/plat_gicv3.c		\
+				plat/common/plat_psci_common.c		\
+				plat/imx/common/plat_imx8_gic.c
+
+BL31_SOURCES		+=	plat/imx/common/lpuart_console.S	\
+				plat/imx/common/imx8_helpers.S		\
+				plat/imx/imx8ulp/imx8ulp_bl31_setup.c	\
+				plat/imx/imx8ulp/imx8ulp_psci.c		\
+				plat/imx/imx8ulp/apd_context.c		\
+				plat/imx/common/imx8_topology.c		\
+				plat/imx/common/imx_sip_svc.c		\
+				plat/imx/common/imx_sip_handler.c	\
+				plat/imx/common/imx_bl31_common.c	\
+				plat/common/plat_psci_common.c		\
+				lib/cpus/aarch64/cortex_a35.S		\
+				drivers/delay_timer/delay_timer.c	\
+				drivers/delay_timer/generic_delay_timer.c \
+				plat/imx/imx8ulp/xrdc/xrdc_core.c		\
+				plat/imx/imx8ulp/imx8ulp_caam.c         \
+				plat/imx/imx8ulp/dram.c 	        \
+				drivers/scmi-msg/base.c			\
+				drivers/scmi-msg/entry.c		\
+				drivers/scmi-msg/smt.c			\
+				drivers/scmi-msg/power_domain.c		\
+				drivers/scmi-msg/sensor.c		\
+				plat/imx/imx8ulp/scmi/scmi.c		\
+				plat/imx/imx8ulp/scmi/scmi_pd.c		\
+				plat/imx/imx8ulp/scmi/scmi_sensor.c	\
+				plat/imx/imx8ulp/upower/upower_api.c	\
+				plat/imx/imx8ulp/upower/upower_hal.c	\
+				${XLAT_TABLES_LIB_SRCS}			\
+				${IMX_GIC_SOURCES}
+
+ifeq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-fno-strict-aliasing
+endif
+
+USE_COHERENT_MEM	:=	1
+RESET_TO_BL31		:=	1
+SEPARATE_NOBITS_REGION	:=	1
+SEPARATE_RWDATA_REGION	:=	1
+PROGRAMMABLE_RESET_ADDRESS	:=	1
+COLD_BOOT_SINGLE_CPU := 1
+WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
+BL32_BASE		?=	0xa6000000
+BL32_SIZE		?=	0x2000000
+$(eval $(call add_define,BL32_BASE))
+$(eval $(call add_define,BL32_SIZE))
+
+ifeq (${SPD},trusty)
+	BL31_CFLAGS    +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
diff --git a/plat/imx/imx8ulp/scmi/scmi.c b/plat/imx/imx8ulp/scmi/scmi.c
new file mode 100644
index 0000000..5d3e7d7
--- /dev/null
+++ b/plat/imx/imx8ulp/scmi/scmi.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdint.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+
+#include <platform_def.h>
+
+#define SMT_BUFFER_BASE		0x2201f000
+#define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
+#define SMT_BUFFER1_BASE	(SMT_BUFFER_BASE + 0x200)
+
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER0_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	return &scmi_channel[agent_id];
+}
+
+static const char vendor[] = "NXP";
+static const char sub_vendor[] = "";
+
+const char *plat_scmi_vendor_name(void)
+{
+	return vendor;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return sub_vendor;
+}
+
+/* Currently supporting Clocks and Reset Domains */
+static const uint8_t plat_protocol_list[] = {
+	SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	SCMI_PROTOCOL_ID_SENSOR,
+	0U /* Null termination */
+};
+
+size_t plat_scmi_protocol_count(void)
+{
+	return ARRAY_SIZE(plat_protocol_list) - 1U;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
+{
+	return plat_protocol_list;
+}
+
+void imx8ulp_init_scmi_server(void)
+{
+	size_t i;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+	}
+}
diff --git a/plat/imx/imx8ulp/scmi/scmi_pd.c b/plat/imx/imx8ulp/scmi/scmi_pd.c
new file mode 100644
index 0000000..8e7e5d6
--- /dev/null
+++ b/plat/imx/imx8ulp/scmi/scmi_pd.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <inttypes.h>
+#include <lib/libc/errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+#include <scmi.h>
+
+#include <upower_api.h>
+
+#define POWER_STATE_ON	(0 << 30)
+#define POWER_STATE_OFF	(1 << 30)
+
+extern bool is_lpav_owned_by_apd(void);
+
+enum {
+	PS0 = 0,
+	PS1 = 1,
+	PS2 = 2,
+	PS3 = 3,
+	PS4 = 4,
+	PS5 = 5,
+	PS6 = 6,
+	PS7 = 7,
+	PS8 = 8,
+	PS9 = 9,
+	PS10 = 10,
+	PS11 = 11,
+	PS12 = 12,
+	PS13 = 13,
+	PS14 = 14,
+	PS15 = 15,
+	PS16 = 16,
+	PS17 = 17,
+	PS18 = 18,
+	PS19 = 19,
+};
+
+#define SRAM_DMA1		BIT(6)
+#define SRAM_FLEXSPI2		BIT(7)
+#define SRAM_USB0		BIT(10)
+#define SRAM_USDHC0		BIT(11)
+#define SRAM_USDHC1		BIT(12)
+#define SRAM_USDHC2_USB1	BIT(13)
+#define SRAM_DCNANO		GENMASK_32(18, 17)
+#define SRAM_EPDC		GENMASK_32(20, 19)
+#define SRAM_DMA2		BIT(21)
+#define SRAM_GPU2D		GENMASK_32(23, 22)
+#define SRAM_GPU3D		GENMASK_32(25, 24)
+#define SRAM_HIFI4		BIT(26)
+#define SRAM_ISI_BUFFER		BIT(27)
+#define SRAM_MIPI_CSI_FIFO	BIT(28)
+#define SRAM_MIPI_DSI_FIFO	BIT(29)
+#define SRAM_PXP		BIT(30)
+
+#define SRAM_DMA0		BIT_64(33)
+#define SRAM_FLEXCAN		BIT_64(34)
+#define SRAM_FLEXSPI0		BIT_64(35)
+#define SRAM_FLEXSPI1		BIT_64(36)
+
+struct psw {
+	char *name;
+	uint32_t reg;
+	int power_state;
+	uint32_t count;
+	int flags;
+};
+
+#define ALWAYS_ON BIT(0)
+
+static struct psw imx8ulp_psw[] = {
+	[PS6] = { .name = "PS6", .reg = PS6, .flags = ALWAYS_ON, .power_state = POWER_STATE_ON },
+	[PS7] = { .name = "PS7", .reg = PS7, .power_state = POWER_STATE_OFF },
+	[PS8] = { .name = "PS8", .reg = PS8, .power_state = POWER_STATE_OFF },
+	[PS13] = { .name = "PS13", .reg = PS13, .power_state = POWER_STATE_OFF },
+	[PS14] = { .name = "PS14", .reg = PS14, .flags = ALWAYS_ON, .power_state = POWER_STATE_OFF },
+	[PS15] = { .name = "PS15", .reg = PS15, .power_state = POWER_STATE_OFF },
+	[PS16] = { .name = "PS16", .reg = PS16, .flags = ALWAYS_ON, .power_state = POWER_STATE_ON },
+};
+
+struct power_domain {
+	char *name;
+	uint32_t reg;
+	uint32_t psw_parent;
+	uint32_t sram_parent;
+	uint64_t bits;
+	uint32_t power_state;
+	bool lpav; /* belong to lpav domain */
+	uint32_t sw_rst_reg; /* pcc sw reset reg offset */
+};
+
+/* The Rich OS need flow the macro */
+#define IMX8ULP_PD_DMA1		0
+#define IMX8ULP_PD_FLEXSPI2	1
+#define IMX8ULP_PD_USB0		2
+#define IMX8ULP_PD_USDHC0	3
+#define IMX8ULP_PD_USDHC1	4
+#define IMX8ULP_PD_USDHC2_USB1	5
+#define IMX8ULP_PD_DCNANO	6
+#define IMX8ULP_PD_EPDC		7
+#define IMX8ULP_PD_DMA2		8
+#define IMX8ULP_PD_GPU2D	9
+#define IMX8ULP_PD_GPU3D	10
+#define IMX8ULP_PD_HIFI4	11
+#define IMX8ULP_PD_ISI		12
+#define IMX8ULP_PD_MIPI_CSI	13
+#define IMX8ULP_PD_MIPI_DSI	14
+#define IMX8ULP_PD_PXP		15
+
+#define IMX8ULP_PD_PS6		16
+#define IMX8ULP_PD_PS7		17
+#define IMX8ULP_PD_PS8		18
+#define IMX8ULP_PD_PS13		19
+#define IMX8ULP_PD_PS14		20
+#define IMX8ULP_PD_PS15		21
+#define IMX8ULP_PD_PS16		22
+#define IMX8ULP_PD_MAX		23
+
+/* LPAV peripheral PCC */
+#define PCC_GPU2D	(IMX_PCC5_BASE + 0xf0)
+#define PCC_GPU3D	(IMX_PCC5_BASE + 0xf4)
+#define PCC_EPDC	(IMX_PCC5_BASE + 0xcc)
+#define PCC_CSI		(IMX_PCC5_BASE + 0xbc)
+#define PCC_PXP		(IMX_PCC5_BASE + 0xd0)
+
+#define PCC_SW_RST	BIT(28)
+
+#define PWR_DOMAIN(_name, _reg, _psw_parent, _sram_parent, \
+		   _bits, _state, _lpav, _rst_reg) \
+	{ \
+		.name = _name, \
+		.reg = _reg, \
+		.psw_parent = _psw_parent, \
+		.sram_parent = _sram_parent, \
+		.bits = _bits, \
+		.power_state = _state, \
+		.lpav = _lpav, \
+		.sw_rst_reg = _rst_reg, \
+	}
+
+static struct power_domain scmi_power_domains[] = {
+	PWR_DOMAIN("DMA1", IMX8ULP_PD_DMA1, PS6, PS6, SRAM_DMA1, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("FLEXSPI2", IMX8ULP_PD_FLEXSPI2, PS6, PS6, SRAM_FLEXSPI2, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USB0", IMX8ULP_PD_USB0, PS6, PS6, SRAM_USB0, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USDHC0", IMX8ULP_PD_USDHC0, PS6, PS6, SRAM_USDHC0, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USDHC1", IMX8ULP_PD_USDHC1, PS6, PS6, SRAM_USDHC1, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USDHC2_USB1", IMX8ULP_PD_USDHC2_USB1, PS6, PS6, SRAM_USDHC2_USB1, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("DCNano", IMX8ULP_PD_DCNANO, PS16, PS16, SRAM_DCNANO, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("EPDC", IMX8ULP_PD_EPDC, PS13, PS13, SRAM_EPDC, POWER_STATE_OFF, true, PCC_EPDC),
+	PWR_DOMAIN("DMA2", IMX8ULP_PD_DMA2, PS16, PS16, SRAM_DMA2, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("GPU2D", IMX8ULP_PD_GPU2D, PS16, PS16, SRAM_GPU2D, POWER_STATE_OFF, true, PCC_GPU2D),
+	PWR_DOMAIN("GPU3D", IMX8ULP_PD_GPU3D, PS7, PS7, SRAM_GPU3D, POWER_STATE_OFF, true, PCC_GPU3D),
+	PWR_DOMAIN("HIFI4", IMX8ULP_PD_HIFI4, PS8, PS8, SRAM_HIFI4, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("ISI", IMX8ULP_PD_ISI, PS16, PS16, SRAM_ISI_BUFFER, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("MIPI_CSI", IMX8ULP_PD_MIPI_CSI, PS15, PS16, SRAM_MIPI_CSI_FIFO, POWER_STATE_OFF, true, PCC_CSI),
+	PWR_DOMAIN("MIPI_DSI", IMX8ULP_PD_MIPI_DSI, PS14, PS16, SRAM_MIPI_DSI_FIFO, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("PXP", IMX8ULP_PD_PXP, PS13, PS13, SRAM_PXP | SRAM_EPDC, POWER_STATE_OFF, true, PCC_PXP)
+};
+
+size_t plat_scmi_pd_count(unsigned int agent_id __unused)
+{
+	return ARRAY_SIZE(scmi_power_domains);
+}
+
+const char *plat_scmi_pd_get_name(unsigned int agent_id __unused,
+				  unsigned int pd_id)
+{
+	if (pd_id >= IMX8ULP_PD_PS6) {
+		return imx8ulp_psw[pd_id - IMX8ULP_PD_PS6].name;
+	}
+
+	return scmi_power_domains[pd_id].name;
+}
+
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id __unused,
+				    unsigned int pd_id __unused)
+{
+	if (pd_id >= IMX8ULP_PD_PS6) {
+		return imx8ulp_psw[pd_id - IMX8ULP_PD_PS6].power_state;
+	}
+
+	return scmi_power_domains[pd_id].power_state;
+}
+
+extern void upower_wait_resp(void);
+int upwr_pwm_power(const uint32_t swton[], const uint32_t memon[], bool on)
+{
+	int ret_val;
+	int ret;
+
+	if (on == true) {
+		ret = upwr_pwm_power_on(swton, memon, NULL);
+	} else {
+		ret = upwr_pwm_power_off(swton, memon, NULL);
+	}
+
+	if (ret != 0U) {
+		WARN("%s failed: ret: %d, state: %x\n", __func__, ret, on);
+		return ret;
+	}
+
+	upower_wait_resp();
+
+	ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		WARN("Failure %d, %s\n", ret, __func__);
+		if (ret == UPWR_REQ_BUSY) {
+			return -EBUSY;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int32_t plat_scmi_pd_psw(unsigned int index, unsigned int state)
+{
+	uint32_t psw_parent = scmi_power_domains[index].psw_parent;
+	uint32_t sram_parent = scmi_power_domains[index].sram_parent;
+	uint64_t swt;
+	bool on;
+	int ret = 0;
+
+	if ((imx8ulp_psw[psw_parent].flags & ALWAYS_ON) != 0U &&
+	    (imx8ulp_psw[sram_parent].flags & ALWAYS_ON) != 0U) {
+		return 0;
+	}
+
+	on = (state == POWER_STATE_ON) ? true : false;
+
+	if ((imx8ulp_psw[psw_parent].flags & ALWAYS_ON) == 0U) {
+		swt = 1 << imx8ulp_psw[psw_parent].reg;
+		if (imx8ulp_psw[psw_parent].count == 0U) {
+			if (on == false) {
+				WARN("off PSW[%d] that already in off state\n", psw_parent);
+				ret = -EACCES;
+			} else {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+				imx8ulp_psw[psw_parent].count++;
+			}
+		} else {
+			if (on == true) {
+				imx8ulp_psw[psw_parent].count++;
+			} else {
+				imx8ulp_psw[psw_parent].count--;
+			}
+
+			if (imx8ulp_psw[psw_parent].count == 0U) {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+			}
+		}
+	}
+
+	if (!(imx8ulp_psw[sram_parent].flags & ALWAYS_ON) && (psw_parent != sram_parent)) {
+		swt = 1 << imx8ulp_psw[sram_parent].reg;
+		if (imx8ulp_psw[sram_parent].count == 0U) {
+			if (on == false) {
+				WARN("off PSW[%d] that already in off state\n", sram_parent);
+				ret = -EACCES;
+			} else {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+				imx8ulp_psw[sram_parent].count++;
+			}
+		} else {
+			if (on == true) {
+				imx8ulp_psw[sram_parent].count++;
+			} else {
+				imx8ulp_psw[sram_parent].count--;
+			}
+
+			if (imx8ulp_psw[sram_parent].count == 0U) {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+			}
+		}
+	}
+
+	return ret;
+}
+
+bool pd_allow_power_off(unsigned int pd_id)
+{
+	if (scmi_power_domains[pd_id].lpav) {
+		if (!is_lpav_owned_by_apd()) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void assert_pcc_reset(unsigned int pcc)
+{
+	/* if sw_rst_reg is valid, assert the pcc reset */
+	if (pcc != 0U) {
+		mmio_clrbits_32(pcc, PCC_SW_RST);
+	}
+}
+
+int32_t plat_scmi_pd_set_state(unsigned int agent_id __unused,
+			       unsigned int flags,
+			       unsigned int pd_id,
+			       unsigned int state)
+{
+	unsigned int ps_idx;
+	uint64_t mem;
+	bool on;
+	int ret;
+
+	if (flags != 0U || pd_id >= IMX8ULP_PD_PS6) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	ps_idx = 0;
+	while (ps_idx < IMX8ULP_PD_PS6 && scmi_power_domains[ps_idx].reg != pd_id) {
+		ps_idx++;
+	}
+
+	if (ps_idx == IMX8ULP_PD_PS6) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (state == scmi_power_domains[ps_idx].power_state) {
+		return SCMI_SUCCESS;
+	}
+
+	mem = scmi_power_domains[ps_idx].bits;
+	on = (state == POWER_STATE_ON ? true : false);
+	if (on == true) {
+		/* Assert pcc sw reset if necessary */
+		assert_pcc_reset(scmi_power_domains[ps_idx].sw_rst_reg);
+
+		ret = plat_scmi_pd_psw(ps_idx, state);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+
+		ret = upwr_pwm_power(NULL, (const uint32_t *)&mem, on);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+	} else {
+		if (!pd_allow_power_off(ps_idx)) {
+			return SCMI_DENIED;
+		}
+
+		ret = upwr_pwm_power(NULL, (const uint32_t *)&mem, on);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+
+		ret = plat_scmi_pd_psw(ps_idx, state);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+	}
+
+	scmi_power_domains[pd_id].power_state = state;
+
+	return SCMI_SUCCESS;
+}
diff --git a/plat/imx/imx8ulp/scmi/scmi_sensor.c b/plat/imx/imx8ulp/scmi/scmi_sensor.c
new file mode 100644
index 0000000..6976b2e
--- /dev/null
+++ b/plat/imx/imx8ulp/scmi/scmi_sensor.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/libc/errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../../drivers/scmi-msg/sensor.h"
+
+#include <common/debug.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <scmi.h>
+
+#include <upower_api.h>
+
+/* Only Temperature now */
+static uint16_t imx_scmi_sensor_count(unsigned int agent_id __unused)
+{
+	return 1U;
+}
+
+uint8_t imx_scmi_sensor_max_requests(unsigned int agent_id __unused)
+{
+	return 1U;
+}
+
+extern int upower_read_temperature(uint32_t sensor_id, int32_t *temperature);
+int imx_scmi_sensor_reading_get(uint32_t agent_id __unused, uint16_t sensor_id __unused,
+				 uint32_t *val)
+{
+	int32_t temperature;
+	int ret;
+
+	ret = upower_read_temperature(1, &temperature);
+	if (ret != 0U) {
+		val[0] = 0xFFFFFFFF;
+	} else {
+		val[0] = temperature;
+	}
+
+	val[1] = 0;
+	val[2] = 0;
+	val[3] = 0;
+
+	return ret;
+}
+
+#define SCMI_SENSOR_NAME_LENGTH_MAX	16U
+
+uint32_t imx_scmi_sensor_state(uint32_t agent_id __unused, uint16_t sensor_id __unused)
+{
+	return 1U;
+}
+
+uint32_t imx_scmi_sensor_description_get(uint32_t agent_id __unused, uint16_t desc_index __unused,
+					  struct scmi_sensor_desc *desc __unused)
+{
+	desc->id = 0;
+	desc->attr_low = 0;
+	desc->attr_high = 2;
+	strlcpy((char *)desc->name, "UPOWER-TEMP", 12);
+	desc->power = 0;
+	desc->resolution = 0;
+	desc->min_range_low = 0;
+	desc->min_range_high = 0x80000000;
+	desc->max_range_low = 0xffffffff;
+	desc->max_range_high = 0x7fffffff;
+
+	return 1U;
+}
+
+REGISTER_SCMI_SENSOR_OPS(imx_scmi_sensor_count,
+			 imx_scmi_sensor_max_requests,
+			 NULL,
+			 imx_scmi_sensor_reading_get,
+			 imx_scmi_sensor_description_get,
+			 NULL,
+			 imx_scmi_sensor_state,
+			 NULL);
diff --git a/plat/imx/imx8ulp/upower/upmu.h b/plat/imx/imx8ulp/upower/upmu.h
new file mode 100644
index 0000000..ce4f47e
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upmu.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MU_H
+#define MU_H
+
+#include <stdint.h>
+
+typedef volatile unsigned int vuint32_t;
+
+/****************************************************************************/
+/*				MODULE: Message Unit			    */
+/****************************************************************************/
+/* VER Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t FEATURE : 16;
+		vuint32_t MINOR : 8;
+		vuint32_t MAJOR : 8;
+	} B;
+} MU_VER_t;
+
+/* PAR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TR_NUM : 8;
+		vuint32_t RR_NUM : 8;
+		vuint32_t GIR_NUM : 8;
+		vuint32_t FLAG_WIDTH : 8;
+	} B;
+} MU_PAR_t;
+
+/* CR Register */
+typedef union  {
+	vuint32_t R;
+	struct {
+		vuint32_t MUR : 1;
+		vuint32_t MURIE : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_CR_t;
+
+/* SR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t MURS : 1;
+		vuint32_t MURIP : 1;
+		vuint32_t EP : 1;
+		vuint32_t FUP : 1;
+		vuint32_t GIRP : 1;
+		vuint32_t TEP : 1;
+		vuint32_t RFP : 1;
+		vuint32_t CEP : 1;
+		vuint32_t rsrv_1 : 24;
+
+	} B;
+} MU_SR_t;
+
+/* CCR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t NMI : 1;
+		vuint32_t HR  : 1;
+		vuint32_t HRM : 1;
+		vuint32_t CLKE : 1;
+		vuint32_t RSTH : 1;
+		vuint32_t BOOT : 2;
+		vuint32_t rsrv_1 : 25;
+
+	} B;
+} MU_CCR0_t;
+
+/* CIER0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t rsrv_1 : 1;
+		vuint32_t HRIE : 1;
+		vuint32_t RUNIE : 1;
+		vuint32_t RAIE : 1;
+		vuint32_t HALTIE : 1;
+		vuint32_t WAITIE : 1;
+		vuint32_t STOPIE : 1;
+		vuint32_t PDIE : 1;
+		vuint32_t rsrv_2 : 24;
+	} B;
+} MU_CIER0_t;
+
+/* CSSR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t NMIC : 1;
+		vuint32_t HRIP : 1;
+		vuint32_t RUN  : 1;
+		vuint32_t RAIP : 1;
+		vuint32_t HALT : 1;
+		vuint32_t WAIT : 1;
+		vuint32_t STOP : 1;
+		vuint32_t PD : 1;
+		vuint32_t rsrv_1 : 24;
+	} B;
+} MU_CSSR0_t;
+
+/* CSR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t rsrv_1 : 1;
+		vuint32_t HRIP : 1;
+		vuint32_t RUN : 1;
+		vuint32_t RAIP : 1;
+		vuint32_t HALT : 1;
+		vuint32_t WAIT : 1;
+		vuint32_t STOP : 1;
+		vuint32_t PD : 1;
+		vuint32_t rsrv_2 : 24;
+	} B;
+} MU_CSR0_t;
+
+/* FCR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t F0 : 1;
+		vuint32_t F1 : 1;
+		vuint32_t F2 : 1;
+		vuint32_t rsrv_1 : 29;
+	} B;
+} MU_FCR_t;
+
+/* FSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t F0 : 1;
+		vuint32_t F1 : 1;
+		vuint32_t F2 : 1;
+		vuint32_t rsrv_1 : 29;
+	} B;
+} MU_FSR_t;
+
+/* GIER Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t GIE0 : 1;
+		vuint32_t GIE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_GIER_t;
+
+/* GCR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t GIR0 : 1;
+		vuint32_t GIR1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_GCR_t;
+
+/* GSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t GIP0 : 1;
+		vuint32_t GIP1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_GSR_t;
+
+/* TCR Register */
+typedef union{
+	vuint32_t R;
+	struct {
+		vuint32_t TIE0 : 1;
+		vuint32_t TIE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_TCR_t;
+
+/* TSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TE0 : 1;
+		vuint32_t TE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_TSR_t;
+
+/* RCR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RIE0 : 1;
+		vuint32_t RIE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_RCR_t;
+
+/* RSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RF0 : 1;
+		vuint32_t RF1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_RSR_t;
+
+/* TR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TR_DATA : 32;
+	} B;
+} MU_TR0_t;
+
+/* TR1 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TR_DATA : 32;
+	} B;
+} MU_TR1_t;
+
+/* RR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RR_DATA : 32;
+	} B;
+} MU_RR0_t;
+
+/* RR1 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RR_DATA : 32;
+	} B;
+} MU_RR1_t;
+
+struct MU_t {
+	MU_VER_t VER;
+	MU_PAR_t PAR;
+	MU_CR_t CR;
+	MU_SR_t SR;
+	MU_CCR0_t CCR0;
+	MU_CIER0_t CIER0;
+	MU_CSSR0_t CSSR0;
+	MU_CSR0_t CSR0;
+	uint8_t MU_reserved0[224];
+	MU_FCR_t FCR;
+	MU_FSR_t FSR;
+	uint8_t MU_reserved1[8];
+	MU_GIER_t GIER;
+	MU_GCR_t GCR;
+	MU_GSR_t GSR;
+	uint8_t MU_reserved2[4];
+	MU_TCR_t TCR;
+	MU_TSR_t TSR;
+	MU_RCR_t RCR;
+	MU_RSR_t RSR;
+	uint8_t MU_reserved3[208];
+	MU_TR0_t TR[2];
+	uint8_t MU_reserved4[120];
+	MU_RR0_t RR[2];
+};
+
+#endif /* MU_H */
diff --git a/plat/imx/imx8ulp/upower/upower_api.c b/plat/imx/imx8ulp/upower/upower_api.c
new file mode 100644
index 0000000..ce8c1c8
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_api.c
@@ -0,0 +1,3095 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ */
+
+#include <string.h>
+
+#include "upower_api.h"
+#include "upower_soc_defs.h"
+
+/* ---------------------------------------------------------------
+ * Common Macros
+ * ---------------------------------------------------------------
+ */
+
+/* tests Service Group busy */
+#define UPWR_SG_BUSY(sg) ((sg_busy & (1U << (sg))) == 1U)
+
+/* install user callback for the Service Group */
+#define UPWR_USR_CALLB(sg, cb) { user_callback[(sg)] = (cb); }
+
+/* fills up common message header info */
+#define UPWR_MSG_HDR(hdr, sg, fn)   {		\
+	(hdr).domain   = (uint32_t)pwr_domain;	\
+	(hdr).srvgrp   = (sg);			\
+	(hdr).function = (fn); }
+
+/* ---------------------------------------------------------------
+ * Common Data Structures
+ * ---------------------------------------------------------------
+ */
+static soc_domain_t pwr_domain;
+
+static upwr_code_vers_t fw_rom_version;
+static upwr_code_vers_t fw_ram_version;
+static uint32_t fw_launch_option;
+
+/* shared memory buffers */
+#define UPWR_API_BUFFER_SIZE	(MAX_SG_EXCEPT_MEM_SIZE + \
+				 MAX_SG_PWRMGMT_MEM_SIZE + MAX_SG_VOLTM_MEM_SIZE)
+
+/* service group shared mem buffer pointers */
+static void *sh_buffer[UPWR_SG_COUNT];
+
+/* Callbacks registered for each service group :
+ *
+ * NULL means no callback is registered;
+ * for sgrp_callback, it also means the service group is
+ * free to receive a new request.
+ */
+static upwr_callb user_callback[UPWR_SG_COUNT];
+static UPWR_RX_CALLB_FUNC_T sgrp_callback[UPWR_SG_COUNT];
+
+/* request data structures for each service group */
+/* message waiting for TX */
+static upwr_down_max_msg  sg_req_msg[UPWR_SG_COUNT];
+/* waiting message size */
+static unsigned int sg_req_siz[UPWR_SG_COUNT];
+/* response msg  */
+static upwr_up_max_msg sg_rsp_msg[UPWR_SG_COUNT];
+/* response msg size */
+static unsigned int sg_rsp_siz[UPWR_SG_COUNT];
+
+/* tx pending status for each (1 bit per service group) */
+static volatile uint32_t sg_tx_pend;
+/* serv.group of current ongoing Tx, if any */
+static volatile upwr_sg_t  sg_tx_curr;
+
+/* service group busy status, only for this domain (MU index 0) */
+/* SG bit = 1 if group is busy with a request */
+static volatile uint32_t sg_busy;
+
+/* OS-dependent memory allocation function */
+static upwr_malloc_ptr_t os_malloc;
+/* OS-dependent pointer->physical address conversion function */
+static upwr_phyadr_ptr_t os_ptr2phy;
+/* OS-dependent function to lock critical code */
+static upwr_lock_ptr_t os_lock;
+
+/* pointer to MU structure */
+static struct MU_t *mu;
+
+/*
+ * indicates that a transmission was done and is pending; this
+ * bit is necessary because the Tx and Rx interrupts are ORed
+ * together, and there is no way of telling if only Rx interrupt
+ * or both occurred just by looking at the MU status registers
+ */
+static uint32_t  mu_tx_pend;
+
+static UPWR_TX_CALLB_FUNC_T  mu_tx_callb;
+static UPWR_RX_CALLB_FUNC_T  mu_rx_callb;
+
+#define	UPWR_API_INIT_WAIT           (0U) /* waiting for ROM firmware initialization */
+#define	UPWR_API_INITLZED            (1U) /* ROM firmware initialized */
+#define	UPWR_API_START_WAIT          (2U) /* waiting for start services */
+#define	UPWR_API_SHUTDOWN_WAIT       (3U) /* waiting for shutdown */
+#define	UPWR_API_READY               (4U) /* ready to receive service requests */
+
+volatile upwr_api_state_t api_state;
+
+/* default pointer->physical address conversion, returns the same address */
+static void *ptr2phys(const void *ptr)
+{
+	return (void *)ptr;
+}
+
+/* ---------------------------------------------------------------
+ * SHARED MEMORY MANAGEMENT
+ * --------------------------------------------------------------
+ */
+
+/*
+ * upwr_ptr2offset() - converts a pointer (casted to uint64_t) to an
+ * address offset from the  shared memory start. If it does not point
+ * to a shared memory location, the structure pointed is copied to a
+ * buffer in the shared memory,  and the buffer offset is returned.
+ * The 2nd argument is the service group to which the buffer belongs;
+ * The 3rd argument is the size of structure to be copied. The 4th argument
+ * is an offset to apply to the copy destination address. The 5th argument
+ * is ptr before the conversion to physical address. 2nd, 3rd. 4th and 5th
+ * arguments are not used if the 1st one points to a location inside the
+ *  shared memory.
+ */
+
+static uint32_t upwr_ptr2offset(unsigned long ptr,
+				upwr_sg_t sg,
+				size_t siz,
+				size_t offset,
+				const void *vptr)
+{
+	if ((ptr >= UPWR_DRAM_SHARED_BASE_ADDR) &&
+	    ((ptr - UPWR_DRAM_SHARED_BASE_ADDR) < UPWR_DRAM_SHARED_SIZE)) {
+		return (uint32_t)(ptr - UPWR_DRAM_SHARED_BASE_ADDR);
+	}
+
+	/* pointer is outside the shared memory, copy the struct to buffer */
+	(void)memcpy((void *)(offset + (char *)sh_buffer[sg]), (void *)vptr, siz);
+	return (uint32_t)((unsigned long)sh_buffer[sg] + offset - UPWR_DRAM_SHARED_BASE_ADDR);
+}
+
+/*
+ * ---------------------------------------------------------------
+ * INTERRUPTS AND CALLBACKS
+ * Service-group specific callbacks are in their own sections
+ * --------------------------------------------------------------
+ */
+
+/*
+ * upwr_lock()- locks (lock=1) or unlocks (lock=0) a critical code section;
+ * for now it only needs to protect a portion of the code from being
+ * interrupted by the MU.
+ */
+static void upwr_lock(int lock)
+{
+	if (os_lock != NULL) {
+		os_lock(lock);
+	}
+}
+
+/* upwr_exp_isr()- handles the exception interrupt from uPower */
+static void upwr_exp_isr(void)
+{
+}
+
+/* upwr_copy2tr prototype; function definition in auxiliary function section */
+void upwr_copy2tr(struct MU_t *local_mu, const uint32_t *msg, unsigned int size);
+
+#define UPWR_MU_TSR_EMPTY ((uint32_t)((1UL << UPWR_MU_MSG_SIZE) - 1UL))
+
+/* upwr_txrx_isr()- handles both the Tx and Rx MU interrupts */
+void upwr_txrx_isr(void)
+{
+	/* Tx pending and TX register empty */
+	if ((mu_tx_pend != 0UL) && (mu->TSR.R == UPWR_MU_TSR_EMPTY)) {
+		mu_tx_pend = 0UL;
+		/* disable the tx interrupts */
+		mu->TCR.R = 0U;
+		/* urgency flag off, in case it was set */
+		mu->FCR.B.F0 = 0U;
+
+		if (mu_tx_callb != NULL) {
+			mu_tx_callb();
+		}
+	}
+
+	/* RX ISR occurred */
+	if (mu->RSR.R != 0UL) {
+		/* disable the interrupt until data is read */
+		mu->RCR.R = 0U;
+
+		if (mu_rx_callb != NULL) {
+			mu_rx_callb();
+		}
+	}
+}
+
+/**
+ * upwr_next_req() - sends the next pending service request message, if any.
+ *
+ * Called upon MU Tx interrupts, it checks if there is any service request
+ * pending amongst the service groups, and sends the request if needed.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void).
+ */
+static void upwr_next_req(void)
+{
+	upwr_sg_t sg = (upwr_sg_t)0U;
+
+	/* no lock needed here, this is called from an MU ISR */
+	sg_tx_pend &= ~((uint32_t)1UL << sg_tx_curr); /* no longer pending */
+
+	if (sg_tx_pend == 0U) {
+		return; /* no other pending */
+	}
+
+	/* find the next one pending */
+	for (uint32_t mask = 1UL; mask < (1UL << UPWR_SG_COUNT); mask = mask << 1UL) {
+		if ((sg_tx_pend & mask) != 0U) {
+			break;
+		}
+
+		sg = (upwr_sg_t)(sg + 1U);
+	}
+
+	sg_tx_curr = sg;
+	if (upwr_tx((uint32_t *)&sg_req_msg[sg], sg_req_siz[sg], upwr_next_req) < 0) {
+		return; /* leave the Tx pending */
+	}
+}
+
+/**
+ * upwr_mu_int_callback() - general MU interrupt callback.
+ *
+ * Called upon MU Rx interrupts, it calls the Service Group-specific callback,
+ * if any registered, based on the service group field in the received message.
+ * Otherwise, calls the user callback, if any registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void).
+ */
+static void upwr_mu_int_callback(void)
+{
+	upwr_sg_t sg;       /* service group number */
+	UPWR_RX_CALLB_FUNC_T sg_callb; /* service group callback */
+	upwr_up_max_msg rxmsg = {0};
+	unsigned int size; /* in words */
+
+	if (upwr_rx((char *)&rxmsg, &size) < 0) {
+		return;
+	}
+
+	sg = (upwr_sg_t)rxmsg.hdr.srvgrp;
+
+	/* copy msg to the service group buffer */
+	msg_copy((char *)&sg_rsp_msg[sg], (char *)&rxmsg, size);
+	sg_rsp_siz[sg] = size;
+
+	/* clear the service group busy status */
+	sg_busy &= ~(1UL << sg); /* no lock needed here, we're in the MU ISR */
+
+	sg_callb = sgrp_callback[sg];
+	if (sg_callb == NULL) {
+		upwr_callb user_callb = user_callback[sg];
+		/* no service group callback; call the user callback if any */
+		if (user_callb == NULL) {
+			goto done; /* no user callback */
+		}
+
+		/* make the user callback */
+		user_callb(sg, rxmsg.hdr.function,
+			   (upwr_resp_t)rxmsg.hdr.errcode,
+			   (size == 2U) ? rxmsg.word2 : rxmsg.hdr.ret);
+		goto done;
+	}
+
+	/*
+	 * finally make the group callback. don't uninstall the group
+	 * callback, it is permanent.
+	 */
+	sg_callb();
+done:
+	if (rxmsg.hdr.errcode == UPWR_RESP_SHUTDOWN) { /* shutdown error: */
+		/*
+		 * change the API state automatically. so new requests
+		 * are rejected by the API immediately
+		 */
+		api_state = UPWR_API_INITLZED;
+	}
+}
+
+/**
+ * upwr_srv_req() - sends a service request message.
+ * @sg: message service group.
+ * @msg: pointer to the message
+ * @size: message size in 32-bit words.
+ *
+ * The message is sent right away if possible, or gets pending to be sent later.
+ * If pending, the message is stored in sg_req_msg and will be sent when the
+ * MU transmission buffer is clear and there are no other pending messages
+ * from higher priority service groups.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+static void upwr_srv_req(upwr_sg_t sg,
+			 uint32_t *msg,
+			 unsigned int size)
+{
+	int rc;
+
+	upwr_lock(1);
+	sg_busy |= (uint32_t)1U << sg;
+	upwr_lock(0);
+
+	rc = upwr_tx(msg, size, upwr_next_req);
+	if (rc  < 0) {
+		/* queue full, make the transmission pending */
+		msg_copy((char *)&sg_req_msg[sg], (char *)msg, size);
+		sg_req_siz[sg] = size;
+
+		upwr_lock(1);
+		sg_tx_curr = sg;
+		sg_tx_pend |= (uint32_t)1U << sg;
+		upwr_lock(0);
+
+		return;
+	}
+}
+
+/**---------------------------------------------------------------
+ * INITIALIZATION, CONFIGURATION
+ *
+ * A reference uPower initialization sequence goes as follows:
+ *
+ * 1. host CPU calls upwr_init.
+ * 2. (optional) host checks the ROM version and SoC code calling upwr_vers(...)
+ *    and optionally performs any configuration or workaround accordingly.
+ * 3. host CPU calls upwr_start to start the uPower services, passing a
+ *    service option number.
+ *    If no RAM code is loaded or it has no service options, the launch option
+ *    number passed must be 0, which will start the services available in ROM.
+ *    upwr_start also receives a pointer to a callback called by the API
+ *    when the firmware is ready to receive service requests.
+ *    The callback may be replaced by polling, calling upwr_req_status in a loop
+ *    or upwr_poll_req_status; in this case the callback pointer may be NULL.
+ *    A host may call upwr_start even if the services were already started by
+ *    any host: if the launch option is the same, the response will be ok,
+ *    but will indicate error if the services were already started with a
+ *    different launch option.
+ * 4. host waits for the callback calling, or polling finishing;
+ *    if no error is returned, it can start making service calls using the API.
+ *
+ * Variations on that reference sequence are possible:
+ *  - the uPower services can be started using the ROM code only, which includes
+ *    the basic Power Management services, among others, with launch option
+ *    number = 0.
+ *    The code RAM can be loaded while these services are running and,
+ *    when the loading is done, the services can be re-started with these 2
+ *    requests executed in order: upwr_xcp_shutdown and upwr_start,
+ *    using the newly loaded RAM code (launch option > 0).
+ *
+ * NOTE: the initialization call upwr_init is not effective and
+ *       returns error when called after the uPower services are started.
+ */
+
+/**
+ * upwr_start_callb() - internal callback for the Rx message from uPower
+ * that indicates the firmware is ready to receive the start commands.
+ * It calls the user callbacks registered in the upwr_start_boot and upwr_start
+ * call.
+ */
+void upwr_start_callb(void)
+{
+	switch (api_state) {
+	case UPWR_API_START_WAIT: {
+		upwr_rdy_callb start_callb = (upwr_rdy_callb)user_callback[UPWR_SG_EXCEPT];
+		upwr_ready_msg *msg = (upwr_ready_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+		fw_ram_version.soc_id = fw_rom_version.soc_id;
+		fw_ram_version.vmajor = msg->args.vmajor;
+		fw_ram_version.vminor = msg->args.vminor;
+		fw_ram_version.vfixes = msg->args.vfixes;
+
+		/*
+		 * vmajor == vminor == vfixes == 0 indicates start error
+		 * in this case, go back to the INITLZED state
+		 */
+		if ((fw_ram_version.vmajor != 0U) ||
+		    (fw_ram_version.vminor != 0U) ||
+		    (fw_ram_version.vfixes != 0U)) {
+			api_state = UPWR_API_READY;
+
+			/*
+			 * initialization is over:
+			 * uninstall the user callback just in case
+			 */
+			UPWR_USR_CALLB(UPWR_SG_EXCEPT, NULL);
+
+			if (fw_launch_option == 0U) {
+				/*
+				 * launched ROM firmware:
+				 * RAM fw versions must be all 0s
+				 */
+				fw_ram_version.vmajor = 0U;
+				fw_ram_version.vminor = 0U;
+				fw_ram_version.vfixes = 0U;
+			}
+		} else {
+			api_state = UPWR_API_INITLZED;
+		}
+
+		start_callb(msg->args.vmajor, msg->args.vminor, msg->args.vfixes);
+	}
+	break;
+
+	case UPWR_API_SHUTDOWN_WAIT: {
+		upwr_callb user_callb = (upwr_callb)user_callback[UPWR_SG_EXCEPT];
+		upwr_shutdown_msg *msg = (upwr_shutdown_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+		if ((upwr_resp_t)msg->hdr.errcode == UPWR_RESP_OK) {
+			api_state = UPWR_API_INITLZED;
+		}
+
+		if (user_callb != NULL) {
+			user_callb(UPWR_SG_EXCEPT, UPWR_XCP_SHUTDOWN,
+				   (upwr_resp_t)msg->hdr.errcode, 0U);
+		}
+	}
+	break;
+
+	case UPWR_API_READY:
+	{
+		upwr_callb user_callb = (upwr_callb)user_callback[UPWR_SG_EXCEPT];
+		upwr_up_max_msg *msg = (upwr_up_max_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+		if (user_callb != NULL) {
+			user_callb(UPWR_SG_EXCEPT, msg->hdr.function,
+				   (upwr_resp_t)msg->hdr.errcode,
+				   (int)((sg_rsp_siz[UPWR_SG_EXCEPT] == 2U) ?
+					 msg->word2 : msg->hdr.ret));
+		}
+	}
+	break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * upwr_init() - API initialization; must be the first API call after reset.
+ * @domain: SoC-dependent CPU domain id; identifier used by the firmware in
+ * many services. Defined by SoC-dependent type soc_domain_t found in
+ * upower_soc_defs.h.
+ * @muptr: pointer to the MU instance.
+ * @mallocptr: pointer to the memory allocation function
+ * @physaddrptr: pointer to the function to convert pointers to
+ * physical addresses. If NULL, no conversion is made (pointer=physical address)
+ * @isrinstptr: pointer to the function to install the uPower ISR callbacks;
+ * the function receives the pointers to the MU tx/rx and Exception ISRs
+ * callbacks, which must be called from the actual system ISRs.
+ * The function pointed by isrinstptr must also enable the interrupt at the
+ * core/interrupt controller, but must not enable the interrupt at the MU IP.
+ * The system ISRs are responsible for dealing with the interrupt controller,
+ * performing any other context save/restore, and any other housekeeping.
+ * @lockptr: pointer to a function that prevents MU interrupts (if argrument=1)
+ * or allows it (if argument=0). The API calls this function to make small
+ * specific code portions thread safe. Only MU interrupts must be avoided,
+ * the code may be suspended for other reasons.
+ * If no MU interrupts can happen during the execution of an API call or
+ * callback, even if enabled, for some other reason (e.g. interrupt priority),
+ * then this argument may be NULL.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if failed to allocate memory, or use some other resource.
+ *        -2 if any argument is invalid.
+ *        -3 if failed to send the ping message.
+ *        -4 if failed to receive the initialization message, or was invalid
+ */
+int upwr_init(soc_domain_t domain, struct MU_t *muptr,
+	      const upwr_malloc_ptr_t mallocptr,
+	      const upwr_phyadr_ptr_t phyadrptr,
+	      const upwr_inst_isr_ptr_t isrinstptr,
+	      const upwr_lock_ptr_t lockptr)
+{
+	uint32_t j;
+
+	upwr_sg_t sg; /* service group number */
+	unsigned int size;
+	unsigned long dom_buffer_base = (domain == RTD_DOMAIN) ? UPWR_API_BUFFER_BASE :
+					((UPWR_API_BUFFER_ENDPLUS + UPWR_API_BUFFER_BASE) / 2U);
+
+	upwr_init_msg *msg = (upwr_init_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+	mu = muptr;
+	/*
+	 * Disable tx and rx interrupts in case not called
+	 * 1st time after reset
+	 */
+	mu->TCR.R = mu->RCR.R = 0U;
+
+	os_malloc = mallocptr;
+	os_ptr2phy = (phyadrptr == (upwr_phyadr_ptr_t)NULL) ? ptr2phys : phyadrptr;
+
+	os_lock = lockptr;
+	api_state = UPWR_API_INIT_WAIT;
+	sg_busy = 0UL;
+	pwr_domain = domain;
+
+	/* initialize the versions, in case they are polled */
+	fw_rom_version.soc_id = 0U;
+	fw_rom_version.vmajor = 0U;
+	fw_rom_version.vminor = 0U;
+	fw_rom_version.vfixes = 0U;
+
+	fw_ram_version.soc_id = 0U;
+	fw_ram_version.vmajor = 0U;
+	fw_ram_version.vminor = 0U;
+	fw_ram_version.vfixes = 0U;
+
+	mu_tx_pend = (uint32_t)0U;
+	sg_tx_pend = (uint32_t)0U;
+
+	sg_tx_curr = UPWR_SG_COUNT; /* means none here */
+
+	sh_buffer[UPWR_SG_EXCEPT] = (void *)(unsigned long)dom_buffer_base;
+	sh_buffer[UPWR_SG_PWRMGMT] = (void *)(unsigned long)(dom_buffer_base +
+					      MAX_SG_EXCEPT_MEM_SIZE);
+	sh_buffer[UPWR_SG_DELAYM] = NULL;
+	sh_buffer[UPWR_SG_VOLTM] = (void *)(unsigned long)(dom_buffer_base +
+					    MAX_SG_EXCEPT_MEM_SIZE + MAX_SG_PWRMGMT_MEM_SIZE);
+	sh_buffer[UPWR_SG_CURRM] = NULL;
+	sh_buffer[UPWR_SG_TEMPM] = NULL;
+	sh_buffer[UPWR_SG_DIAG] = NULL;
+
+	/* (no buffers service groups other than xcp and pwm for now) */
+	for (j = 0; j < UPWR_SG_COUNT; j++) {
+		user_callback[j] = NULL;
+		/* service group Exception gets the initialization callbacks */
+		sgrp_callback[j] = (j == UPWR_SG_EXCEPT) ? upwr_start_callb : NULL;
+		/* response messages with an initial consistent content */
+		sg_rsp_msg[j].hdr.errcode = UPWR_RESP_SHUTDOWN;
+	}
+
+	/* init message already received, assume takss are running on upower */
+	if (mu->FSR.B.F0 != 0U) {
+		/* send a ping message down to get the ROM version back */
+		upwr_xcp_ping_msg ping_msg = {0};
+
+		ping_msg.hdr.domain = pwr_domain;
+		ping_msg.hdr.srvgrp = UPWR_SG_EXCEPT;
+		ping_msg.hdr.function = UPWR_XCP_PING;
+
+		if (mu->RSR.B.RF0 != 0U) { /* first clean any Rx message left over */
+			(void)upwr_rx((char *)msg, &size);
+		}
+
+		/* wait any TX left over to be sent */
+		while (mu->TSR.R != UPWR_MU_TSR_EMPTY) {
+		}
+
+		/*
+		 * now send the ping message;
+		 * do not use upwr_tx, which needs API initialized;
+		 * just write to the MU TR register(s)
+		 */
+		mu->FCR.B.F0 = 1U; /* flag urgency status */
+		upwr_copy2tr(mu, (uint32_t *)&ping_msg, sizeof(ping_msg) / 4U);
+	}
+
+	do {
+		/*
+		 * poll for the MU Rx status: wait for an init message, either
+		 * 1st sent from uPower after reset or as a response to a ping
+		 */
+		while (mu->RSR.B.RF0 == 0U) {
+		}
+
+		/* urgency status off, in case it was set */
+		mu->FCR.B.F0 = 0U;
+
+		if (upwr_rx((char *)msg, &size) < 0) {
+			return -4;
+		}
+
+		if (size != (sizeof(upwr_init_msg) / 4U)) {
+			if (mu->FSR.B.F0 != 0U) {
+				continue; /* discard left over msg */
+			} else {
+				return -4;
+			}
+		}
+
+		sg = (upwr_sg_t)msg->hdr.srvgrp;
+		if (sg != UPWR_SG_EXCEPT) {
+			if (mu->FSR.B.F0 != 0U) {
+				continue; /* discard left over msg */
+			} else {
+				return -4;
+			}
+		}
+
+		if ((upwr_xcp_f_t)msg->hdr.function != UPWR_XCP_INIT) {
+			if (mu->FSR.B.F0 != 0U) {
+				continue; /* discard left over msg */
+			} else {
+				return -4;
+			}
+		}
+
+		break;
+	} while (true);
+
+	fw_rom_version.soc_id = msg->args.soc;
+	fw_rom_version.vmajor = msg->args.vmajor;
+	fw_rom_version.vminor = msg->args.vminor;
+	fw_rom_version.vfixes = msg->args.vfixes;
+
+	if (upwr_rx_callback(upwr_mu_int_callback) < 0) {
+		/* catastrophic error, but is it possible to happen? */
+		return -1;
+	}
+
+	mu_tx_callb = NULL; /* assigned on upwr_tx */
+
+	/* install the ISRs and enable the interrupts */
+	isrinstptr(upwr_txrx_isr, upwr_exp_isr);
+
+	/* enable only RR[0] receive interrupt */
+	mu->RCR.R = 1U;
+
+	api_state = UPWR_API_INITLZED;
+
+	return 0;
+}
+
+/**
+ * upwr_start() - Starts the uPower services.
+ * @launchopt: a number to select between multiple launch options,
+ * that may define, among other things, which services will be started,
+ * or which services implementations, features etc.
+ * launchopt = 0 selects a subset of services implemented in ROM;
+ * any other number selects service sets implemented in RAM, launched
+ * by the firmware function ram_launch; if an invalid launchopt value is passed,
+ * no services are started, and the callback returns error (see below).
+ * @rdycallb: pointer to the callback to be called when the uPower is ready
+ * to receive service requests. NULL if no callback needed.
+ * The callback receives as arguments the RAM firmware version numbers.
+ * If all 3 numbers (vmajor, vminor, vfixes) are 0, that means the
+ * service launching failed.
+ * Firmware version numbers will be the same as ROM if launchopt = 0,
+ * selecting the ROM services.
+ *
+ * upwr_start can be called by any domain even if the services are already
+ * started: it has no effect, returning success, if the launch option is the
+ * same as the one that actually started the service, and returns error if
+ * called with a different option.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if a resource failed,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_start(uint32_t launchopt, const upwr_rdy_callb rdycallb)
+{
+	upwr_start_msg txmsg = {0};
+
+	if (api_state != UPWR_API_INITLZED) {
+		return -3;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, (upwr_callb)rdycallb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_START);
+
+	txmsg.hdr.arg = fw_launch_option = launchopt;
+
+	if (upwr_tx((uint32_t *)&txmsg, sizeof(txmsg) / 4U, NULL) < 0) {
+		/* catastrophic error, but is it possible to happen? */
+		return -1;
+	}
+
+	api_state = UPWR_API_START_WAIT;
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * EXCEPTION SERVICE GROUP
+ */
+
+/**
+ * upwr_xcp_config() - Applies general uPower configurations.
+ * @config: pointer to the uPower SoC-dependent configuration struct
+ * upwr_xcp_config_t defined in upower_soc_defs.h. NULL may be passed, meaning
+ * a request to read the configuration, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_xcp_config_t.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the configuration, or NULL if no callback needed (polling used instead).
+ *
+ * Some configurations are targeted for a specific domain (see the struct
+ * upwr_xcp_config_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * The return value is always the current configuration value, either in a
+ * read-only request (config = NULL) or after setting a new configuration
+ * (non-NULL config).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_config(const upwr_xcp_config_t *config, const upwr_callb callb)
+{
+	upwr_xcp_config_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	if (config == NULL) {
+		txmsg.hdr.arg = 1U;         /* 1= read, txmsg.word2 ignored */
+	} else {
+		txmsg.hdr.arg = 0U;         /* 1= write */
+		txmsg.word2   = config->R;
+	}
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_CONFIG);
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_sw_alarm() - Makes uPower issue an alarm interrupt to given domain.
+ * @domain: identifier of the domain to alarm. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @code: alarm code. Defined by SoC-dependent type upwr_alarm_t found in
+ * upower_soc_defs.h.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the alarm, or NULL if no callback needed (polling used instead).
+ *
+ * The function requests the uPower to issue an alarm of the given code as if
+ * it had originated internally. This service is useful mainly to test the
+ * system response to such alarms, or to make the system handle a similar alarm
+ * situation detected externally to uPower.
+ *
+ * The system ISR/code handling the alarm may retrieve the alarm code by calling
+ * the auxiliary function upwr_alarm_code.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_sw_alarm(soc_domain_t domain,
+		      upwr_alarm_t code,
+		      const upwr_callb callb)
+{
+	upwr_xcp_swalarm_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SW_ALARM);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)code;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_ddr_retention() - M33/A35 can use this API to set/clear ddr retention
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_ddr_retention(soc_domain_t domain,
+			       uint32_t enable,
+			       const upwr_callb callb)
+{
+	upwr_xcp_ddr_retn_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_DDR_RETN);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)enable;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_mipi_dsi_ena() - M33/A35 can use this API to set/clear mipi dsi ena
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_mipi_dsi_ena(soc_domain_t domain,
+			      uint32_t enable,
+			      const upwr_callb callb)
+{
+	upwr_xcp_set_mipi_dsi_ena_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_MIPI_DSI_ENA);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)enable;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_get_mipi_dsi_ena() - M33/A35 can use this API to get mipi dsi ena status
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_get_mipi_dsi_ena(soc_domain_t domain, const upwr_callb callb)
+{
+	upwr_xcp_get_mipi_dsi_ena_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_GET_MIPI_DSI_ENA);
+	txmsg.hdr.domain = (uint32_t)domain;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_osc_mode() - M33/A35 can use this API to set uPower OSC mode
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @osc_mode, 0 means low frequency, not 0 means high frequency.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_osc_mode(soc_domain_t domain,
+			  uint32_t osc_mode,
+			  const upwr_callb callb)
+{
+	upwr_xcp_set_osc_mode_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_OSC_MODE);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)osc_mode;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_rtd_use_ddr() - M33 call this API to inform uPower, M33 is using ddr
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @is_use_ddr: not 0, true, means that RTD is using ddr. 0, false, means that, RTD
+ * is not using ddr.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_use_ddr(soc_domain_t domain,
+			     uint32_t is_use_ddr,
+			     const upwr_callb callb)
+{
+	upwr_xcp_rtd_use_ddr_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_RTD_USE_DDR);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)is_use_ddr;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_rtd_apd_llwu() - M33/A35 can use this API to set/clear rtd_llwu apd_llwu
+ * @domain: set which domain (RTD_DOMAIN, APD_DOMAIN) LLWU.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set rtd_llwu or apd_llwu, false clear rtd_llwu or apd_llwu.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_apd_llwu(soc_domain_t domain,
+			      uint32_t enable,
+			      const upwr_callb callb)
+{
+	upwr_xcp_rtd_apd_llwu_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_RTD_APD_LLWU);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)enable;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_shutdown() - Shuts down all uPower services and power mode tasks.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the shutdown, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * At the callback the uPower/API is back to initialization/start-up phase,
+ * so service request calls return error.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_shutdown(const upwr_callb callb)
+{
+	upwr_xcp_shutdown_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SHUTDOWN);
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	api_state = UPWR_API_SHUTDOWN_WAIT;
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_i2c_access() - Performs an access through the uPower I2C interface.
+ * @addr: I2C slave address, up to 10 bits.
+ * @data_size: determines the access direction and data size in bytes, up to 4;
+ * negetive data_size determines a read  access with size -data_size;
+ * positive data_size determines a write access with size  data_size;
+ * data_size=0 is invalid, making the service return error UPWR_RESP_BAD_REQ.
+ * @subaddr_size: size of the sub-address in bytes, up to 4; if subaddr_size=0,
+ * no subaddress is used.
+ * @subaddr: sub-address, only used if subaddr_size > 0.
+ * @wdata: write data, up to 4 bytes; ignored if data_size < 0 (read)
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the access, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * The service performs a read (data_size < 0) or a write (data_size > 0) of
+ * up to 4 bytes on the uPower I2C interface. The data read from I2C comes via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Sub-addressing is supported, with sub-address size determined by the argument
+ * subaddr_size, up to 4 bytes. Sub-addressing is not used if subaddr_size=0.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_i2c_access(uint16_t addr,
+			int8_t data_size,
+			uint8_t subaddr_size,
+			uint32_t subaddr,
+			uint32_t wdata,
+			const upwr_callb callb)
+{
+	unsigned long ptrval = (unsigned long)sh_buffer[UPWR_SG_EXCEPT];
+	upwr_i2c_access *i2c_acc_ptr = (upwr_i2c_access *)ptrval;
+	upwr_pwm_pmiccfg_msg  txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_I2C);
+
+	i2c_acc_ptr->addr = addr;
+	i2c_acc_ptr->subaddr = subaddr;
+	i2c_acc_ptr->subaddr_size = subaddr_size;
+	i2c_acc_ptr->data = wdata;
+	i2c_acc_ptr->data_size = data_size;
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_EXCEPT,
+				    (size_t)sizeof(upwr_i2c_access),
+				    0U,
+				    i2c_acc_ptr);
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * VOLTAGE MANAGERMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_vtm_pmic_cold_reset() -request cold reset the pmic.
+ * pmic will power cycle all the regulators
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to cold reset the pmic.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_cold_reset(upwr_callb callb)
+{
+	upwr_volt_pmic_cold_reset_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_PMIC_COLD_RESET);
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_set_pmic_mode() -request uPower set pmic mode
+ * @pmic_mode: the target mode need to be set
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to set pmic mode
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_set_pmic_mode(uint32_t pmic_mode, upwr_callb callb)
+{
+	upwr_volt_pmic_set_mode_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_SET_PMIC_MODE);
+
+	txmsg.hdr.arg = pmic_mode;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_chng_pmic_voltage() - Changes the voltage of a given rail.
+ * @rail: pmic rail id.
+ * @volt: the target voltage of the given rail, accurate to uV
+ * If pass volt value 0, means that power off this rail.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_chng_pmic_voltage(uint32_t rail, uint32_t volt, upwr_callb callb)
+{
+	upwr_volt_pmic_set_volt_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_CHNG_PMIC_RAIL_VOLT);
+
+	txmsg.args.rail = rail;
+
+	txmsg.args.volt = (volt + PMIC_VOLTAGE_MIN_STEP - 1U) / PMIC_VOLTAGE_MIN_STEP;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_get_pmic_voltage() - Get the voltage of a given rail.
+ * @rail: pmic rail id.
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_get_pmic_voltage(uint32_t rail, upwr_callb callb)
+{
+	upwr_volt_pmic_get_volt_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_GET_PMIC_RAIL_VOLT);
+
+	txmsg.args.rail = rail;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_power_measure() - request uPower to measure power consumption
+ * @ssel: This field determines which power switches will have their currents
+ * sampled to be accounted for a
+ * current/power measurement. Support 0~7
+
+ * SSEL bit #	Power Switch
+ * 0	M33 core complex/platform/peripherals
+ * 1	Fusion Core and Peripherals
+ * 2	A35[0] core complex
+ * 3	A35[1] core complex
+ * 4	3DGPU
+ * 5	HiFi4
+ * 6	DDR Controller (PHY and PLL NOT included)
+ * 7	PXP, EPDC
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure power consumption
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The power consumption data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Accurate to uA
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_power_measure(uint32_t ssel, upwr_callb callb)
+{
+	upwr_volt_pmeter_meas_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_PMETER_MEAS);
+
+	txmsg.hdr.arg = ssel;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_vmeter_measure() - request uPower to measure voltage
+ * @vdetsel: Voltage Detector Selector, support 0~3
+ * 00b - RTD sense point
+   01b - LDO output
+   10b - APD domain sense point
+   11b - AVD domain sense point
+   Refer to upower_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to use vmeter to measure voltage
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Refer to RM COREREGVL (Core Regulator Voltage Level)
+ * uPower return VDETLVL to user, user can calculate the real voltage:
+ *
+0b000000(0x00) - 0.595833V
+0b100110(0x26) - 1.007498V
+<value> - 0.595833V + <value>x10.8333mV
+0b110010(0x32) - 1.138V
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_vmeter_measure(uint32_t vdetsel, upwr_callb callb)
+{
+	upwr_volt_vmeter_meas_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_VMETER_MEAS);
+
+	txmsg.hdr.arg = vdetsel;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_pmic_config() - Configures the SoC PMIC (Power Management IC).
+ * @config: pointer to a PMIC-dependent struct defining the PMIC configuration.
+ * @size:   size of the struct pointed by config, in bytes.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the PMIC configuration.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_config(const void *config, uint32_t size, upwr_callb callb)
+{
+	upwr_pwm_pmiccfg_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_PMIC_CONFIG);
+
+	ptrval = (unsigned long)os_ptr2phy(config);
+	if (ptrval == 0UL) {
+		return -2; /* pointer conversion failed */
+	}
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_VOLTM,
+				    (size_t)size,
+				    0U,
+				    config);
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * TEMPERATURE MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_tpm_get_temperature() - request uPower to get temperature of one temperature sensor
+ * @sensor_id: temperature sensor ID, support 0~2
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure temperature
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_TEMPM as the service group argument.
+ *
+ * The temperature data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * uPower return TSEL to the caller (M33 or A35), caller calculate the real temperature
+ * Tsh = 0.000002673049*TSEL[7:0]^3 + 0.0003734262*TSEL[7:0]^2 +
+0.4487042*TSEL[7:0] - 46.98694
+ *
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_tpm_get_temperature(uint32_t sensor_id, upwr_callb callb)
+{
+	upwr_temp_get_cur_temp_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_TEMPM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_TEMPM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_TEMPM, UPWR_TEMP_GET_CUR_TEMP);
+
+	txmsg.args.sensor_id = sensor_id;
+
+	upwr_srv_req(UPWR_SG_TEMPM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * DELAY MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_dlm_get_delay_margin() - request uPower to get delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The delay margin data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_get_delay_margin(uint32_t path, uint32_t index, upwr_callb callb)
+{
+	upwr_dmeter_get_delay_margin_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_DELAYM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DELAYM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DELAYM, UPWR_DMETER_GET_DELAY_MARGIN);
+
+	txmsg.args.path = path;
+	txmsg.args.index = index;
+
+	upwr_srv_req(UPWR_SG_DELAYM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_dlm_set_delay_margin() - request uPower to set delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @delay_margin: the value of delay margin
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to set delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of the corresponding critical path,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_set_delay_margin(uint32_t path, uint32_t index, uint32_t delay_margin,
+			      upwr_callb callb)
+{
+	upwr_dmeter_set_delay_margin_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_DELAYM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DELAYM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DELAYM, UPWR_DMETER_SET_DELAY_MARGIN);
+
+	txmsg.args.path = path;
+	txmsg.args.index = index;
+	txmsg.args.dm = delay_margin;
+
+	upwr_srv_req(UPWR_SG_DELAYM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_dlm_process_monitor() - request uPower to do process monitor
+ * @chain_sel: Chain Cell Type Selection
+ * Select the chain to be used for the clock signal generation.
+ * Support two types chain cell, 0~1
+0b - P4 type delay cells selected
+1b - P16 type delay cells selected
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to do process monitor
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of process monitor,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_process_monitor(uint32_t chain_sel, upwr_callb callb)
+{
+	upwr_pmon_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_DELAYM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DELAYM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DELAYM, UPWR_PMON_REQ);
+
+	txmsg.args.chain_sel = chain_sel;
+
+	upwr_srv_req(UPWR_SG_DELAYM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * POWER MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_pwm_dom_power_on() - Commands uPower to power on the platform of other
+ * domain (not necessarily its core(s)); does not release the core reset.
+ * @domain: identifier of the domain to power on. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @boot_start: must be 1 to start the domain core(s) boot(s), releasing
+ * its (their) resets, or 0 otherwise.
+ * @pwroncallb: pointer to the callback to be called when the uPower has
+ * finished the power on procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_dom_power_on(soc_domain_t domain,
+			  int boot_start,
+			  const upwr_callb pwroncallb)
+{
+	upwr_pwm_dom_pwron_msg txmsg = {0};
+
+	if (pwr_domain == domain) {
+		return -2;
+	}
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, (upwr_callb)pwroncallb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_DOM_PWRON);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg    = (uint32_t)boot_start;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_boot_start() - Commands uPower to release the reset of other CPU(s),
+ * starting their boots.
+ * @domain: identifier of the domain to release the reset. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bootcallb: pointer to the callback to be called when the uPower has finished
+ * the boot start procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The callback calling doesn't mean the CPUs boots have finished:
+ * it only indicates that uPower released the CPUs resets, and can receive
+ * other power management service group requests.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_boot_start(soc_domain_t domain, const upwr_callb  bootcallb)
+{
+	upwr_pwm_boot_start_msg txmsg = {0};
+
+	if (pwr_domain == domain) {
+		return -2;
+	}
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, (upwr_callb)bootcallb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_BOOT);
+	txmsg.hdr.domain = (uint32_t)domain;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_param() - Changes Power Management parameters.
+ * @param: pointer to a parameter structure upwr_pwm_param_t, SoC-dependent,
+ * defined in upwr_soc_defines.h. NULL may be passed, meaning
+ * a request to read the parameter set, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_pwm_param_t.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The return value is always the current parameter set value, either in a
+ * read-only request (param = NULL) or after setting a new parameter
+ * (non-NULL param).
+ *
+ * Some parameters may be targeted for a specific domain (see the struct
+ * upwr_pwm_param_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_param(upwr_pwm_param_t *param, const upwr_callb callb)
+{
+	upwr_pwm_param_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_PARAM);
+
+	if (param == NULL) {
+		txmsg.hdr.arg = 1U;        /* 1= read, txmsg.word2 ignored */
+	} else {
+		txmsg.hdr.arg = 0U;        /* 1= write */
+		txmsg.word2 = param->R; /* just 1 word, so that's ok */
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_reg_voltage() - Changes the voltage at a given regulator.
+ * @reg: regulator id.
+ * @volt: voltage value; value unit is SoC-dependent, converted from mV by the
+ * macro UPWR_VTM_MILIV, or from micro-Volts by the macro UPWR_VTM_MICROV,
+ * both macros in upower_soc_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given regulator.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_reg_voltage(uint32_t reg, uint32_t volt, upwr_callb callb)
+{
+	upwr_pwm_volt_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_VOLT);
+
+	txmsg.args.reg = reg;
+	txmsg.args.volt = volt;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_freq_setup() - Determines the next frequency target for a given
+ *                         domain and current frequency.
+ * @domain: identifier of the domain to change frequency. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @rail: the pmic regulator number for the target domain.
+ * @stage: DVA adjust stage
+ * refer to upower_defs.h "DVA adjust stage"
+ * @target_freq: the target adjust frequency, accurate to MHz
+ *
+ * refer to upower_defs.h structure definition upwr_pwm_freq_msg
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The DVA algorithm is broken down into two phases.
+ * The first phase uses a look up table to get a safe operating voltage
+ * for the requested frequency.
+ * This voltage is guaranteed to work over process and temperature.
+ *
+ * The second step of the second phase is to measure the temperature
+ * using the uPower Temperature Sensor module.
+ * This is accomplished by doing a binary search of the TSEL bit field
+ * in the Temperature Measurement Register (TMR).
+ * The search is repeated until the THIGH bit fields in the same register change value.
+ * There are 3 temperature sensors in 8ULP (APD, AVD, and RTD).
+ *
+ *
+ * The second phase is the fine adjust of the voltage.
+ * This stage is entered only when the new frequency requested
+ * by application was already set as well as the voltage for that frequency.
+ * The first step of the fine adjust is to find what is the current margins
+ * for the monitored critical paths, or, in other words,
+ * how many delay cells will be necessary to generate a setup-timing violation.
+ * The function informs uPower that the given domain frequency has changed or
+ * will change to the given value. uPower firmware will then adjust voltage and
+ * bias to cope with the new frequency (if decreasing) or prepare for it
+ * (if increasing). The function must be called after decreasing the frequency,
+ * and before increasing it. The actual increase in frequency must not occur
+ * before the service returns its response.
+ *
+ * So, for increase clock frequency case, user need to call this API twice,
+ * the first stage gross adjust and the second stage fine adjust.
+ *
+ * for reduce clock frequency case, user can only call this API once,
+ * full stage (combine gross stage and fine adjust)
+ *
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_freq_setup(soc_domain_t domain, uint32_t rail, uint32_t stage, uint32_t target_freq,
+			upwr_callb   callb)
+{
+	upwr_pwm_freq_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_FREQ);
+
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.args.rail = rail;
+	txmsg.args.stage = stage;
+	txmsg.args.target_freq = target_freq;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_power_on()- Powers on (not off) one or more switches and ROM/RAMs.
+ * @swton: pointer to an array of words that tells which power switches to
+ *  turn on. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned on,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swton must not point to the first shared memory address.
+ * @memon: pointer to an array of words that tells which memories to turn on.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned on, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed.
+ *  WARNING: memon must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn on the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the pwron
+ * array is not provided (that is, if pwron is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_power_on(const uint32_t swton[],
+		      const uint32_t memon[],
+		      upwr_callb     callb)
+{
+	upwr_pwm_pwron_msg txmsg = {0};
+	unsigned long  ptrval = 0UL; /* needed for X86, ARM64 */
+	size_t stsize = 0U;
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_PWR_ON);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)swton);
+	if (swton == NULL) {
+		txmsg.ptrs.ptr0 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr0 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  (stsize = UPWR_PMC_SWT_WORDS * 4U),
+						  0U,
+						  swton);
+	}
+
+	ptrval = (unsigned long)os_ptr2phy((void *)memon);
+	if (memon == NULL) {
+		txmsg.ptrs.ptr1 = 0; /* NULL pointer -> 0 offset */
+
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr1 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  UPWR_PMC_MEM_WORDS * 4U,
+						  stsize,
+						  memon);
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_power_off()- Powers off (not on) one or more switches and ROM/RAMs.
+ * @swtoff: pointer to an array of words that tells which power switches to
+ *  turn off. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned off,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed.
+ *  WARNING: swtoff must not point to the first shared memory address.
+ * @memoff: pointer to an array of words that tells which memories to turn off.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned off, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed,
+ *  but notice it may be turned off if the switch that feeds it is powered off.
+ *  WARNING: memoff must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_power_off(const uint32_t swtoff[],
+		       const uint32_t memoff[],
+		       upwr_callb     callb)
+{
+	upwr_pwm_pwroff_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+	size_t stsize = 0;
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_PWR_OFF);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)swtoff);
+	if (swtoff == NULL) {
+		txmsg.ptrs.ptr0 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr0 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  (stsize = UPWR_PMC_SWT_WORDS * 4U),
+						  0U,
+						  swtoff);
+	}
+
+	ptrval = (unsigned long)os_ptr2phy((void *)memoff);
+	if (memoff == NULL) {
+		txmsg.ptrs.ptr1 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr1 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  UPWR_PMC_MEM_WORDS * 4U,
+						  stsize,
+						  memoff);
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_mem_retain()- Configures one or more memory power switches to
+ * retain its contents, having the power array on, while its peripheral logic
+ * is turned off.
+ * @mem: pointer to an array of words that tells which memories to put in a
+ *  retention state. Each word in the array has 1 bit for each memory.
+ *  A bit=1 means the respective memory must be put in retention state,
+ *  bit = 0 means it will stay unchanged (retention, fully on or off).
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the memory peripheral and leave
+ * its array on, as specified above.
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_mem_retain(const uint32_t mem[], upwr_callb callb)
+{
+	upwr_pwm_retain_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_RETAIN);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)mem);
+	if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	}
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_PWRMGMT,
+				    UPWR_PMC_MEM_WORDS * 4U,
+				    0U,
+				    mem);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_switch_mem() - Turns on/off power on one or more PMC switches
+ * and memories, including their array and peripheral logic.
+ * @swt: pointer to a list of PMC switches to be opened/closed.
+ *  The list is structured as an array of struct upwr_switch_board_t
+ *  (see upower_defs.h), each one containing a word for up to 32 switches,
+ *  one per bit. A bit = 1 means switch closed, bit = 0 means switch open.
+ *  struct upwr_switch_board_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swt must not point to the first shared memory address.
+ * @mem: pointer to a list of switches to be turned on/off.
+ *  The list is structured as an array of struct upwr_mem_switches_t
+ *  (see upower_defs.h), each one containing 2 word for up to 32 switches,
+ *  one per bit, one word for the RAM array power switch, other for the
+ *  RAM peripheral logic power switch. A bit = 1 means switch closed,
+ *  bit = 0 means switch open.
+ *  struct upwr_mem_switches_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no memory switch will be
+ *  changed, but notice it may be turned off if the switch that feeds it is
+ *  powered off.
+ *  WARNING: mem must not point to the first shared memory address.
+ * @callb: pointer to the callback called when the configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the PMC switches and/or memory power
+ * as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate switch combinations and overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the swt
+ * array is not provided (that is, if swt is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy.
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_chng_switch_mem(const struct upwr_switch_board_t  swt[],
+			     const struct upwr_mem_switches_t  mem[],
+			     upwr_callb callb)
+{
+	upwr_pwm_switch_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+	size_t stsize = 0U;
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_SWITCH);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)swt);
+	if (swt == NULL) {
+		txmsg.ptrs.ptr0 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr0 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  (stsize = UPWR_PMC_SWT_WORDS * sizeof(struct upwr_switch_board_t)),
+						  0U,
+						  swt);
+	}
+
+	ptrval = (unsigned long)os_ptr2phy((void *)mem);
+	if (mem == NULL) {
+		txmsg.ptrs.ptr1 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr1 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  UPWR_PMC_MEM_WORDS * sizeof(struct upwr_mem_switches_t),
+						  stsize,
+						  mem);
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_pmode_config() - Configures a given power mode in a given domain.
+ * @domain: identifier of the domain to which the power mode belongs.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @pmode: SoC-dependent power mode identifier defined by type abs_pwr_mode_t
+ * found in upower_soc_defs.h.
+ * @config: pointer to an SoC-dependent struct defining the power mode
+ * configuration, found in upower_soc_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the power mode configuration as
+ * specified above. The request is executed if arguments are within range,
+ * and complies with SoC-dependent restrictions on value combinations.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_pmode_config(soc_domain_t domain,
+			  abs_pwr_mode_t pmode,
+			  const void *config,
+			  upwr_callb callb)
+{
+	upwr_pwm_pmode_cfg_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_CONFIG);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = pmode;
+
+	ptrval = (unsigned long)os_ptr2phy(config);
+	if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	}
+
+	/*
+	 * upwr_pwm_pmode_config is an exception: use the pointer
+	 * (physical addr) as is
+	 */
+
+	txmsg.ptr = (uint32_t)ptrval;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_reg_config() - Configures the uPower internal regulators.
+ * @config: pointer to the struct defining the regulator configuration;
+ * the struct upwr_reg_config_t is defined in the file upower_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the configurations of the
+ * internal regulators.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The service may fail with error UPWR_RESP_RESOURCE if a power mode transition
+ * or the same service (called from another domain) is executing simultaneously.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_reg_config(const struct upwr_reg_config_t *config,
+			upwr_callb   callb)
+{
+	upwr_pwm_regcfg_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_REGCFG);
+
+	ptrval = (unsigned long)os_ptr2phy(config);
+	if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	}
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_PWRMGMT,
+				    sizeof(struct upwr_reg_config_t),
+				    0U,
+				    config);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_dom_bias() - Changes the domain bias.
+ * @bias: pointer to a domain bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the domain bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_dom_bias(const struct upwr_dom_bias_cfg_t *bias,
+			   upwr_callb callb)
+{
+	upwr_pwm_dom_bias_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_DOM_BIAS);
+
+	/* SoC-dependent argument filling, defined in upower_soc_defs.h */
+	UPWR_FILL_DOMBIAS_ARGS(txmsg.hdr.domain, bias, txmsg.args);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_mem_bias()- Changes a ROM/RAM power bias.
+ * @domain: identifier of the domain upon which the bias is applied.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bias: pointer to a memory bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the memory bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_mem_bias(soc_domain_t domain,
+			   const struct upwr_mem_bias_cfg_t *bias,
+			   upwr_callb callb)
+{
+	upwr_pwm_mem_bias_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_MEM_BIAS);
+
+	txmsg.hdr.domain = (uint32_t)domain;
+
+	/* SoC-dependent argument filling, defined in upower_soc_defs.h */
+	UPWR_FILL_MEMBIAS_ARGS(bias, txmsg.args);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * DIAGNOSE SERVICE GROUP
+ */
+
+/**
+ * upwr_dgn_mode() - Sets the diagnostic mode.
+ * @mode:  diagnostic mode, which can be:
+ *  - UPWR_DGN_NONE:   no diagnostic recorded
+ *  - UPWR_DGN_TRACE:  warnings, errors, service, internal activity recorded
+ *  - UPWR_DGN_SRVREQ: warnings, errors, service activity recorded
+ *  - UPWR_DGN_WARN:   warnings and errors recorded
+ *  - UPWR_DGN_ALL:    trace, service, warnings, errors, task state recorded
+ *  - UPWR_DGN_ERROR:  only errors recorded
+ *  - UPWR_DGN_ALL2ERR: record all until an error occurs,
+ *    freeze recording on error
+ *  - UPWR_DGN_ALL2HLT: record all until an error occurs,
+ *    executes an ebreak on error, which halts the core if enabled through
+ *    the debug interface
+ * @callb: pointer to the callback called when mode is changed.
+ * NULL if no callback is required.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_dgn_mode(upwr_dgn_mode_t mode, const upwr_callb callb)
+{
+	upwr_dgn_mode_msg txmsg = {0};
+
+	if (UPWR_SG_BUSY(UPWR_SG_DIAG)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DIAG, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DIAG, UPWR_DGN_MODE);
+
+	txmsg.hdr.arg = mode;
+
+	upwr_srv_req(UPWR_SG_DIAG, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * AUXILIARY CALLS
+ */
+
+/**
+ * upwr_rom_version() - informs the ROM firwmware version.
+ * @vmajor: pointer to the variable to get the firmware major version number.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: SoC id.
+ */
+uint32_t upwr_rom_version(uint32_t *vmajor, uint32_t *vminor, uint32_t *vfixes)
+{
+	uint32_t soc;
+
+	upwr_lock(1);
+	soc = fw_rom_version.soc_id;
+	*vmajor = fw_rom_version.vmajor;
+	*vminor = fw_rom_version.vminor;
+	*vfixes = fw_rom_version.vfixes;
+	upwr_lock(0);
+	return soc;
+}
+
+/**
+ * upwr_ram_version() - informs the RAM firwmware version.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * The 3 values returned are 0 if no RAM firmwmare was loaded and initialized.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: firmware major version number.
+ */
+uint32_t upwr_ram_version(uint32_t *vminor, uint32_t *vfixes)
+{
+	uint32_t vmajor;
+
+	upwr_lock(1);
+	vmajor = fw_ram_version.vmajor;
+	*vminor = fw_ram_version.vminor;
+	*vfixes = fw_ram_version.vfixes;
+	upwr_lock(0);
+
+	return vmajor;
+}
+
+/**
+ * upwr_req_status() - tells the status of the service group request, and
+ *                     returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ *
+ * This call can be used in a poll loop of a service request completion in case
+ * a callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+upwr_req_status_t upwr_req_status(upwr_sg_t sg,
+				  uint32_t *sgfptr,
+				  upwr_resp_t *errptr,
+				  int *retptr)
+{
+	upwr_req_status_t status;
+
+	upwr_lock(1);
+	if (sgfptr != NULL) {
+		*sgfptr = (uint32_t)sg_rsp_msg[sg].hdr.function;
+	}
+
+	if (errptr != NULL) {
+		*errptr = (upwr_resp_t)sg_rsp_msg[sg].hdr.errcode;
+	}
+
+	if (retptr != NULL) {
+		*retptr = (int)((sg_rsp_siz[sg] == 2U) ?
+			  sg_rsp_msg[sg].word2 : sg_rsp_msg[sg].hdr.ret);
+	}
+
+	status = ((sg_busy & (1UL << sg)) == 1U) ? UPWR_REQ_BUSY :
+		 (sg_rsp_msg[sg].hdr.errcode == UPWR_RESP_OK) ? UPWR_REQ_OK :
+								UPWR_REQ_ERR;
+	upwr_lock(0);
+	return status;
+}
+
+/**
+ * upwr_poll_req_status() - polls the status of the service group request, and
+ *                          returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ * @attempts: maximum number of polling attempts; if attempts > 0 and is
+ * reached with no service response received, upwr_poll_req_status returns
+ * UPWR_REQ_BUSY and variables pointed by sgfptr, retptr and errptr are not
+ * updated; if attempts = 0, upwr_poll_req_status waits "forever".
+ *
+ * This call can be used to poll a service request completion in case a
+ * callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+upwr_req_status_t upwr_poll_req_status(upwr_sg_t sg,
+				       uint32_t *sgfptr,
+				       upwr_resp_t *errptr,
+				       int *retptr,
+				       uint32_t attempts)
+{
+	uint32_t i;
+	upwr_req_status_t ret;
+
+	if (attempts == 0U) {
+		while ((ret = upwr_req_status(sg, sgfptr, errptr, retptr)) == UPWR_REQ_BUSY) {
+		};
+
+		return ret;
+	}
+
+	for (i = 0U; i < attempts; i++) {
+		ret = upwr_req_status(sg, sgfptr, errptr, retptr);
+		if (ret != UPWR_REQ_BUSY) {
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * upwr_alarm_code() - returns the alarm code of the last alarm occurrence.
+ *
+ * The value returned is not meaningful if no alarm was issued by uPower.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: alarm code, as defined by the type upwr_alarm_t in upwr_soc_defines.h
+ */
+upwr_alarm_t upwr_alarm_code(void)
+{
+	return (upwr_alarm_t)(3U & (mu->FSR.R >> 1U)); /* FSR[2:1] */
+}
+
+/**---------------------------------------------------------------
+ * TRANSMIT/RECEIVE PRIMITIVES
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * upwr_copy2tr() - copies a message to the MU TR registers;
+ * fill the TR registers before writing TIEN to avoid early interrupts;
+ * also, fill them from the higher index to the lowest, so the receive
+ * interrupt flag RF[0] will be the last to set, regardless of message size;
+ */
+void upwr_copy2tr(struct MU_t *local_mu, const uint32_t *msg, unsigned int size)
+{
+	for (int i = (int)size - 1; i > -1; i--) {
+		local_mu->TR[i].R = msg[i];
+	}
+}
+
+/**
+ * upwr_tx() - queues a message for transmission.
+ * @msg : pointer to the message sent.
+ * @size: message size in 32-bit words
+ * @callback: pointer to a function to be called when transmission done;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of vacant positions left in the transmission queue, or
+ *         -1 if the queue was already full when upwr_tx was called, or
+ *         -2 if any argument is invalid (like size off-range)
+ */
+int upwr_tx(const uint32_t *msg,
+	    unsigned int size,
+	    UPWR_TX_CALLB_FUNC_T callback)
+{
+	if (size > UPWR_MU_MSG_SIZE) {
+		return -2;
+	}
+
+	if (size == 0U) {
+		return -2;
+	}
+
+	if (mu->TSR.R != UPWR_MU_TSR_EMPTY) {
+		return -1;  /* not all TE bits in 1: some data to send still */
+	}
+
+	mu_tx_callb = callback;
+
+	upwr_copy2tr(mu, msg, size);
+	mu->TCR.R = 1UL << (size - 1UL);
+
+	mu_tx_pend = 1UL;
+
+	return 0;
+}
+
+/**
+ * upwr_rx() - unqueues a received message from the reception queue.
+ * @msg: pointer to the message destination buffer.
+ * @size: pointer to variable to hold message size in 32-bit words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of messages remaining in the reception queue, or
+ *         -1 if the queue was already empty when upwr_rx was called, or
+ *         -2 if any argument is invalid (like mu off-range)
+ */
+int upwr_rx(char *msg, unsigned int *size)
+{
+	unsigned int len = mu->RSR.R;
+
+	len = (len == 0x0U) ? 0U :
+	      (len == 0x1U) ? 1U :
+	      #if UPWR_MU_MSG_SIZE > 1
+	      (len == 0x3U) ? 2U :
+	      #if UPWR_MU_MSG_SIZE > 2
+	      (len == 0x7U) ? 3U :
+	      #if UPWR_MU_MSG_SIZE > 3
+	      (len == 0xFU) ? 4U :
+	      #endif
+	      #endif
+	      #endif
+	      0xFFFFFFFFU; /* something wrong */
+
+	if (len  == 0xFFFFFFFFU) {
+		return -3;
+	}
+
+	if (len == 0U) {
+		return -1;
+	}
+
+	*size = len;
+
+	/*
+	 * copy the received message to the rx queue,
+	 * so the interrupts are cleared.
+	 */
+	msg_copy(msg, (char *)&mu->RR[0], len);
+
+	mu->RCR.R = 1U; /* enable only RR[0] receive interrupt */
+
+	return 0;
+}
+
+/**
+ * upwr_rx_callback() - sets up a callback for a message receiving event.
+ * @callback: pointer to a function to be called when a message arrives;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok; -2 if any argument is invalid (mu off-range).
+ */
+int upwr_rx_callback(UPWR_RX_CALLB_FUNC_T callback)
+{
+	mu_rx_callb = callback;
+
+	return 0;
+}
+
+/**
+ * msg_copy() - copies a message.
+ * @dest: pointer to the destination message.
+ * @src : pointer to the source message.
+ * @size: message size in words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+void msg_copy(char *dest, char *src, unsigned int size)
+{
+	for (uint32_t i = 0U; i < size * sizeof(uint32_t); i++) {
+		dest[i] = src[i];
+	}
+}
diff --git a/plat/imx/imx8ulp/upower/upower_api.h b/plat/imx/imx8ulp/upower/upower_api.h
new file mode 100644
index 0000000..0069f5f
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_api.h
@@ -0,0 +1,1629 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ * -----------------------------------------------------------------------------
+ * PURPOSE: uPower driver API
+ * -----------------------------------------------------------------------------
+ * PARAMETERS:
+ * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
+ * -----------------------------------------------------------------------------
+ * REUSE ISSUES: no reuse issues
+ */
+#ifndef UPWR_API_H
+#define UPWR_API_H
+
+#include "upmu.h"
+#include "upower_soc_defs.h"
+/******************************************************************************
+ * uPower API Overview and Concepts
+ *
+ * This API is intended to be used by the OS drivers (Linux, FreeRTOS etc)
+ * as well as bare metal drivers to command and use services from the uPower.
+ * It aims to be OS-independent.
+ *
+ * The API functions fall in 3 categories:
+ *  - initialization/start-up
+ *  - service requests
+ *  - auxiliary
+ *
+ * The communication with the uPower is mostly made through the Message Unit
+ * (MU) IP. uPower provides one MU for each CPU cluster in a different
+ * power domain. An API instance runs on each CPU cluster.
+ *
+ * The API assumes each SoC power domain/CPU cluster receives 2 interrupts
+ * from the uPower MU:
+ *  1. Tx/Rx, which is issued on both transmission and reception
+ *  2. Exception interrupt, to handle critical alams, catastrophic errors, etc.
+ *     This interrupt should have a high priority, preferably an NMI.
+ *
+ * The normal uPower operation is done by service requests. There is an API
+ * function for each service request, and all service requests send back a
+ * response, at least to indicate success/failure.
+ * The service request functions are non-blocking, and their completion can be
+ * tracked in two ways:
+ *  1. by a callback, registered when the service request call is made by
+ *     passing the callback function pointer; a NULL pointer may be passed,
+ *     in which case no callback is made.
+ *  2. by polling, using the auxiliary functions upwr_req_status or
+ *     upwr_poll_req_status;
+ *     polling must be used if no callback is registered, but callbacks and
+ *     polling are completely independent.
+ *
+ * Note: a service request must not be started from a callback.
+ *
+ * uPower service requests are classified in Service Groups.
+ * Each Service Group has a set of related functions, named upwr_XXX_,
+ * where XXX is a 3-letter service group mnemonic. The service groups are:
+ *  - Exception Service Group - upwr_xcp_*
+ *     ~ gathers functions that deal with errors and other processes outside
+ *       the functional scope.
+ *  - Power Management Service Group - upwr_pwm_*
+ *     ~ functions to control switches, configure power modes, set internal voltage etc
+ *  - Delay Measurement Service Group - upwr_dlm_*
+ *     ~ delay measurements function using the process monitor and delay meter
+ *  - Voltage Measurement Service Group - upwr_vtm_*
+ *     ~ functions for voltage measurements, comparisons, alarms, power meter, set PMIC rail voltage
+ *  - Temperature Measurement Service Group - upwr_tpm_*
+ *     ~ functions for temperature measurements, comparisons, alarms
+ *  - Current Measurement Service Group  - upwr_crm_*
+ *     ~ functions for current and charge measurement
+ *  - Diagnostic Service Group - upwr_dgn_*
+ *     ~ functions for log configuration and statistics collecting
+ *
+ * Service requests follow this "golden rule":
+ * *** No two requests run simultaneously for the same service group,
+ *     on the same domain ***
+ * They can run simultaneously on different domains (RTD/APD), and can also run
+ * simultaneously if belong to different service groups (even on same domain).
+ * Therefore, requests to the same service group on the same domain must be
+ * serialized. A service request call returns error if there is another request
+ * on the same service group pending, waiting a response (on the same domain).
+ *
+ * A request for continuous service does not block the service group.
+ * For instance, a request to "measure the temperature each 10 miliseconds"
+ * responds quickly, unlocks the service group, and the temperature
+ * continues to be measured as requested, every 10 miliseconds from then on.
+ *
+ * Service Groups have a fixed priority in the API, from higher to lower:
+ *  1. Exception
+ *  2. Power Management
+ *  3. Delay Measurement
+ *  4. Voltage Measurement
+ *  5. Current Measurement
+ *  6. Temperature Measurement
+ *  7. Diagnostics
+ *
+ * The priority above only affects the order in which requests are sent to the
+ * uPower firmware: request to the higher priority Service Group is sent first,
+ * even if the call was made later, if there is an MU transmission pending,
+ * blocking it. The service priorities in the firmware depend on other factors.
+ *
+ * Services are requested using API functions. A service function returns with
+ * no error if a request was successfully made, but it doesn't mean the service
+ * was completed. The service is executed asynchronously, and returns a result
+ * (at least success/fail) via a callback or polling for service status.
+ * The possible service response codes are:
+ * - UPWR_RESP_OK = 0,     : no error
+ * - UPWR_RESP_SG_BUSY     : service group is busy
+ * - UPWR_RESP_SHUTDOWN    : services not up or shutting down
+ * - UPWR_RESP_BAD_REQ     : invalid request (usually invalid argumnents)
+ * - UPWR_RESP_BAD_STATE   : system state doesn't allow perform the request
+ * - UPWR_RESP_UNINSTALLD  : service or function not installed
+ * - UPWR_RESP_UNINSTALLED : service or function not installed (alias)
+ * - UPWR_RESP_RESOURCE    : resource not available
+ * - UPWR_RESP_TIMEOUT     : service timeout
+ */
+
+/**
+ * upwr_callb()-generic function pointer for a request return callback;
+ * @sg: request service group
+ * @func: service request function id.
+ * @errcode: error code.
+ * @ret: return value, if any. Note that a request may return a value even if
+ * service error is returned (errcode != UPWR_RESP_OK); that is dependent on
+ * the specific service.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+typedef void (*upwr_callb)(upwr_sg_t sg, uint32_t func,
+			   upwr_resp_t errcode, ...);
+
+/**---------------------------------------------------------------
+ * INITIALIZATION, CONFIGURATION
+ *
+ * A reference uPower initialization sequence goes as follows:
+ *
+ * 1. host CPU calls upwr_init.
+ * 2. (optional) host checks the ROM version and SoC code calling upwr_vers(...)
+ *    and optionally performs any configuration or workaround accordingly.
+ * 3. host CPU calls upwr_start to start the uPower services, passing a
+ *    service option number.
+ *    If no RAM code is loaded or it has no service options, the launch option
+ *    number passed must be 0, which will start the services available in ROM.
+ *    upwr_start also receives a pointer to a callback called by the API
+ *    when the firmware is ready to receive service requests.
+ *    The callback may be replaced by polling, calling upwr_req_status in a loop
+ *    or upwr_poll_req_status; in this case the callback pointer may be NULL.
+ *    A host may call upwr_start even if the services were already started by
+ *    any host: if the launch option is the same, the response will be ok,
+ *    but will indicate error if the services were already started with a
+ *    different launch option.
+ * 4. host waits for the callback calling, or polling finishing;
+ *    if no error is returned, it can start making service calls using the API.
+ *
+ * Variations on that reference sequence are possible:
+ *  - the uPower services can be started using the ROM code only, which includes
+ *    the basic Power Management services, among others, with launch option
+ *    number = 0.
+ *    The code RAM can be loaded while these services are running and,
+ *    when the loading is done, the services can be re-started with these 2
+ *    requests executed in order: upwr_xcp_shutdown and upwr_start,
+ *    using the newly loaded RAM code (launch option > 0).
+ *
+ * NOTE: the initialization call upwr_init is not effective and
+ *       returns error when called after the uPower services are started.
+ */
+
+/**
+ * upwr_init() - API initialization; must be the first API call after reset.
+ * @domain: SoC-dependent CPU domain id; identifier used by the firmware in
+ * many services. Defined by SoC-dependent type soc_domain_t found in
+ * upower_soc_defs.h.
+ * @muptr: pointer to the MU instance.
+ * @mallocptr: pointer to the memory allocation function
+ * @physaddrptr: pointer to the function to convert pointers to
+ * physical addresses. If NULL, no conversion is made (pointer=physical address)
+ * @isrinstptr: pointer to the function to install the uPower ISR callbacks;
+ * the function receives the pointers to the MU tx/rx and Exception ISRs
+ * callbacks, which must be called from the actual system ISRs.
+ * The function pointed by isrinstptr must also enable the interrupt at the
+ * core/interrupt controller, but must not enable the interrupt at the MU IP.
+ * The system ISRs are responsible for dealing with the interrupt controller,
+ * performing any other context save/restore, and any other housekeeping.
+ * @lockptr: pointer to a function that prevents MU interrupts (if argrument=1)
+ * or allows it (if argument=0). The API calls this function to make small
+ * specific code portions thread safe. Only MU interrupts must be avoided,
+ * the code may be suspended for other reasons.
+ * If no MU interrupts can happen during the execution of an API call or
+ * callback, even if enabled, for some other reason (e.g. interrupt priority),
+ * then this argument may be NULL.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if failed to allocate memory, or use some other resource.
+ *        -2 if any argument is invalid.
+ *        -3 if failed to send the ping message.
+ *        -4 if failed to receive the initialization message, or was invalid
+ */
+
+/* malloc function ptr */
+typedef void* (*upwr_malloc_ptr_t)(unsigned int size);
+
+/* pointer->physical address conversion function ptr */
+typedef void* (*upwr_phyadr_ptr_t)(const void *addr);
+
+typedef uint32_t upwr_api_state_t;
+
+extern volatile upwr_api_state_t api_state;
+
+/*
+ * upwr_lock_ptr_t: pointer to a function that prevents MU interrupts
+ * (if argrument lock=1) or allows it (if argument lock=0).
+ * The API calls this function to make small specific code portions thread safe.
+ * Only MU interrupts must be avoided, the code may be suspended for other
+ * reasons.
+ */
+typedef void  (*upwr_lock_ptr_t)(int lock);
+
+typedef void (*upwr_isr_callb)(void);
+
+typedef void (*upwr_inst_isr_ptr_t)(upwr_isr_callb txrx_isr,
+				    upwr_isr_callb excp_isr);
+void upwr_start_callb(void);
+
+int upwr_init(soc_domain_t domain, struct MU_t *muptr,
+	      const upwr_malloc_ptr_t mallocptr,
+	      const upwr_phyadr_ptr_t phyadrptr,
+	      const upwr_inst_isr_ptr_t isrinstptr,
+	      const upwr_lock_ptr_t lockptr);
+
+/**
+ * upwr_start() - Starts the uPower services.
+ * @launchopt: a number to select between multiple launch options,
+ * that may define, among other things, which services will be started,
+ * or which services implementations, features etc.
+ * launchopt = 0 selects a subset of services implemented in ROM;
+ * any other number selects service sets implemented in RAM, launched
+ * by the firmware function ram_launch; if an invalid launchopt value is passed,
+ * no services are started, and the callback returns error (see below).
+ * @rdycallb: pointer to the callback to be called when the uPower is ready
+ * to receive service requests. NULL if no callback needed.
+ * The callback receives as arguments the RAM firmware version numbers.
+ * If all 3 numbers (vmajor, vminor, vfixes) are 0, that means the
+ * service launching failed.
+ * Firmware version numbers will be the same as ROM if launchopt = 0,
+ * selecting the ROM services.
+ *
+ * upwr_start can be called by any domain even if the services are already
+ * started: it has no effect, returning success, if the launch option is the
+ * same as the one that actually started the service, and returns error if
+ * called with a different option.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if a resource failed,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+
+extern void upwr_txrx_isr(void);
+
+typedef void (*upwr_rdy_callb)(uint32_t vmajor, uint32_t vminor, uint32_t vfixes);
+
+int upwr_start(uint32_t launchopt, const upwr_rdy_callb rdycallb);
+
+
+/**---------------------------------------------------------------
+ * EXCEPTION SERVICE GROUP
+ */
+
+/**
+ * upwr_xcp_config() - Applies general uPower configurations.
+ * @config: pointer to the uPower SoC-dependent configuration struct
+ * upwr_xcp_config_t defined in upower_soc_defs.h. NULL may be passed, meaning
+ * a request to read the configuration, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_xcp_config_t.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the configuration, or NULL if no callback needed (polling used instead).
+ *
+ * Some configurations are targeted for a specific domain (see the struct
+ * upwr_xcp_config_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * The return value is always the current configuration value, either in a
+ * read-only request (config = NULL) or after setting a new configuration
+ * (non-NULL config).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_config(const upwr_xcp_config_t *config, const upwr_callb callb);
+
+/**
+ * upwr_xcp_sw_alarm() - Makes uPower issue an alarm interrupt to given domain.
+ * @domain: identifier of the domain to alarm. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @code: alarm code. Defined by SoC-dependent type upwr_alarm_t found in
+ * upower_soc_defs.h.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the alarm, or NULL if no callback needed (polling used instead).
+ *
+ * The function requests the uPower to issue an alarm of the given code as if
+ * it had originated internally. This service is useful mainly to test the
+ * system response to such alarms, or to make the system handle a similar alarm
+ * situation detected externally to uPower.
+ *
+ * The system ISR/code handling the alarm may retrieve the alarm code by calling
+ * the auxiliary function upwr_alarm_code.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_sw_alarm(soc_domain_t domain, upwr_alarm_t code,
+		      const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_ddr_retention() - M33/A35 can use this API to set/clear ddr retention
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_set_ddr_retention(soc_domain_t domain, uint32_t enable,
+			       const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_mipi_dsi_ena() - M33/A35 can use this API to set/clear mipi dsi ena
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_set_mipi_dsi_ena(soc_domain_t domain, uint32_t enable,
+			      const upwr_callb callb);
+
+/**
+ * upwr_xcp_get_mipi_dsi_ena() - M33/A35 can use this API to get mipi dsi ena status
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_get_mipi_dsi_ena(soc_domain_t domain, const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_osc_mode() - M33/A35 can use this API to set uPower OSC mode
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @osc_mode, 0 means low frequency, not 0 means high frequency.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_osc_mode(soc_domain_t domain, uint32_t osc_mode,
+			  const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_rtd_use_ddr() - M33 call this API to inform uPower, M33 is using ddr
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @is_use_ddr: not 0, true, means that RTD is using ddr. 0, false, means that, RTD
+ * is not using ddr.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_use_ddr(soc_domain_t domain, uint32_t is_use_ddr,
+			     const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_rtd_apd_llwu() - M33/A35 can use this API to set/clear rtd_llwu apd_llwu
+ * @domain: set which domain (RTD_DOMAIN, APD_DOMAIN) LLWU.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set rtd_llwu or apd_llwu, false clear rtd_llwu or apd_llwu.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_apd_llwu(soc_domain_t domain, uint32_t enable,
+			      const upwr_callb callb);
+/**
+ * upwr_xcp_shutdown() - Shuts down all uPower services and power mode tasks.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the shutdown, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * At the callback the uPower/API is back to initialization/start-up phase,
+ * so service request calls return error.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_shutdown(const upwr_callb callb);
+
+/**
+ * upwr_xcp_i2c_access() - Performs an access through the uPower I2C interface.
+ * @addr: I2C slave address, up to 10 bits.
+ * @data_size: determines the access direction and data size in bytes, up to 4;
+ * negetive data_size determines a read  access with size -data_size;
+ * positive data_size determines a write access with size  data_size;
+ * data_size=0 is invalid, making the service return error UPWR_RESP_BAD_REQ.
+ * @subaddr_size: size of the sub-address in bytes, up to 4; if subaddr_size=0,
+ * no subaddress is used.
+ * @subaddr: sub-address, only used if subaddr_size > 0.
+ * @wdata: write data, up to 4 bytes; ignored if data_size < 0 (read)
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the access, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * The service performs a read (data_size < 0) or a write (data_size > 0) of
+ * up to 4 bytes on the uPower I2C interface. The data read from I2C comes via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Sub-addressing is supported, with sub-address size determined by the argument
+ * subaddr_size, up to 4 bytes. Sub-addressing is not used if subaddr_size=0.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_i2c_access(uint16_t addr, int8_t data_size, uint8_t subaddr_size,
+			uint32_t subaddr, uint32_t wdata,
+			const upwr_callb callb);
+
+
+/**---------------------------------------------------------------
+ * POWER MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_pwm_dom_power_on() - Commands uPower to power on the platform of other
+ * domain (not necessarily its core(s)); does not release the core reset.
+ * @domain: identifier of the domain to power on. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @boot_start: must be 1 to start the domain core(s) boot(s), releasing
+ * its (their) resets, or 0 otherwise.
+ * @pwroncallb: pointer to the callback to be called when the uPower has
+ * finished the power on procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_dom_power_on(soc_domain_t domain, int boot_start,
+			  const upwr_callb pwroncallb);
+
+/**
+ * upwr_pwm_boot_start() - Commands uPower to release the reset of other CPU(s),
+ * starting their boots.
+ * @domain: identifier of the domain to release the reset. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bootcallb: pointer to the callback to be called when the uPower has finished
+ * the boot start procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The callback calling doesn't mean the CPUs boots have finished:
+ * it only indicates that uPower released the CPUs resets, and can receive
+ * other power management service group requests.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_boot_start(soc_domain_t domain, const upwr_callb  bootcallb);
+
+/**
+ * upwr_pwm_param() - Changes Power Management parameters.
+ * @param: pointer to a parameter structure upwr_pwm_param_t, SoC-dependent,
+ * defined in upwr_soc_defines.h. NULL may be passed, meaning
+ * a request to read the parameter set, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_pwm_param_t.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The return value is always the current parameter set value, either in a
+ * read-only request (param = NULL) or after setting a new parameter
+ * (non-NULL param).
+ *
+ * Some parameters may be targeted for a specific domain (see the struct
+ * upwr_pwm_param_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_param(upwr_pwm_param_t *param, const upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_reg_voltage() - Changes the voltage at a given regulator.
+ * @reg: regulator id.
+ * @volt: voltage value; value unit is SoC-dependent, converted from mV by the
+ * macro UPWR_VOLT_MILIV, or from micro-Volts by the macro UPWR_VOLT_MICROV,
+ * both macros in upower_soc_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given regulator.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_reg_voltage(uint32_t reg, uint32_t volt, upwr_callb callb);
+
+/**
+ * upwr_pwm_freq_setup() - Determines the next frequency target for a given
+ *                         domain and current frequency.
+ * @domain: identifier of the domain to change frequency. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @rail: the pmic regulator number for the target domain.
+ * @stage: DVA adjust stage
+ * refer to upower_defs.h "DVA adjust stage"
+ * @target_freq: the target adjust frequency, accurate to MHz
+ *
+ * refer to upower_defs.h structure definition upwr_pwm_freq_msg
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The DVA algorithm is broken down into two phases.
+ * The first phase uses a look up table to get a safe operating voltage
+ * for the requested frequency.
+ * This voltage is guaranteed to work over process and temperature.
+ *
+ * The second step of the second phase is to measure the temperature
+ * using the uPower Temperature Sensor module.
+ * This is accomplished by doing a binary search of the TSEL bit field
+ * in the Temperature Measurement Register (TMR).
+ * The search is repeated until the THIGH bit fields in the same register change value.
+ * There are 3 temperature sensors in 8ULP (APD, AVD, and RTD).
+ *
+ *
+ * The second phase is the fine adjust of the voltage.
+ * This stage is entered only when the new frequency requested
+ * by application was already set as well as the voltage for that frequency.
+ * The first step of the fine adjust is to find what is the current margins
+ * for the monitored critical paths, or, in other words,
+ * how many delay cells will be necessary to generate a setup-timing violation.
+ * The function informs uPower that the given domain frequency has changed or
+ * will change to the given value. uPower firmware will then adjust voltage and
+ * bias to cope with the new frequency (if decreasing) or prepare for it
+ * (if increasing). The function must be called after decreasing the frequency,
+ * and before increasing it. The actual increase in frequency must not occur
+ * before the service returns its response.
+ *
+ * So, for increase clock frequency case, user need to call this API twice,
+ * the first stage gross adjust and the second stage fine adjust.
+ *
+ * for reduce clock frequency case, user can only call this API once,
+ * full stage (combine gross stage and fine adjust)
+ *
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_freq_setup(soc_domain_t domain, uint32_t rail, uint32_t stage,
+			uint32_t target_freq, upwr_callb callb);
+
+/**
+ * upwr_pwm_power_on()- Powers on (not off) one or more switches and ROM/RAMs.
+ * @swton: pointer to an array of words that tells which power switches to
+ *  turn on. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned on,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swton must not point to the first shared memory address.
+ * @memon: pointer to an array of words that tells which memories to turn on.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned on, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed.
+ *  WARNING: memon must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn on the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the pwron
+ * array is not provided (that is, if pwron is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_power_on(const uint32_t swton[], const uint32_t memon[],
+		      upwr_callb callb);
+
+/**
+ * upwr_pwm_power_off()- Powers off (not on) one or more switches and ROM/RAMs.
+ * @swtoff: pointer to an array of words that tells which power switches to
+ *  turn off. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned off,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed.
+ *  WARNING: swtoff must not point to the first shared memory address.
+ * @memoff: pointer to an array of words that tells which memories to turn off.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned off, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed,
+ *  but notice it may be turned off if the switch that feeds it is powered off.
+ *  WARNING: memoff must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_power_off(const uint32_t swtoff[], const uint32_t memoff[],
+		       upwr_callb callb);
+
+/**
+ * upwr_pwm_mem_retain()- Configures one or more memory power switches to
+ * retain its contents, having the power array on, while its peripheral logic
+ * is turned off.
+ * @mem: pointer to an array of words that tells which memories to put in a
+ *  retention state. Each word in the array has 1 bit for each memory.
+ *  A bit=1 means the respective memory must be put in retention state,
+ *  bit = 0 means it will stay unchanged (retention, fully on or off).
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the memory peripheral and leave
+ * its array on, as specified above.
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_mem_retain(const uint32_t mem[], upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_switch_mem() - Turns on/off power on one or more PMC switches
+ * and memories, including their array and peripheral logic.
+ * @swt: pointer to a list of PMC switches to be opened/closed.
+ *  The list is structured as an array of struct upwr_switch_board_t
+ *  (see upower_defs.h), each one containing a word for up to 32 switches,
+ *  one per bit. A bit = 1 means switch closed, bit = 0 means switch open.
+ *  struct upwr_switch_board_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swt must not point to the first shared memory address.
+ * @mem: pointer to a list of switches to be turned on/off.
+ *  The list is structured as an array of struct upwr_mem_switches_t
+ *  (see upower_defs.h), each one containing 2 word for up to 32 switches,
+ *  one per bit, one word for the RAM array power switch, other for the
+ *  RAM peripheral logic power switch. A bit = 1 means switch closed,
+ *  bit = 0 means switch open.
+ *  struct upwr_mem_switches_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no memory switch will be
+ *  changed, but notice it may be turned off if the switch that feeds it is
+ *  powered off.
+ *  WARNING: mem must not point to the first shared memory address.
+ * @callb: pointer to the callback called when the configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the PMC switches and/or memory power
+ * as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate switch combinations and overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the swt
+ * array is not provided (that is, if swt is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy.
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_switch_mem(const struct upwr_switch_board_t swt[],
+			     const struct upwr_mem_switches_t mem[],
+			     upwr_callb callb);
+
+/**
+ * upwr_pwm_pmode_config() - Configures a given power mode in a given domain.
+ * @domain: identifier of the domain to which the power mode belongs.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @pmode: SoC-dependent power mode identifier defined by type abs_pwr_mode_t
+ * found in upower_soc_defs.h.
+ * @config: pointer to an SoC-dependent struct defining the power mode
+ * configuration, found in upower_soc_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the power mode configuration as
+ * specified above. The request is executed if arguments are within range,
+ * and complies with SoC-dependent restrictions on value combinations.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_pmode_config(soc_domain_t domain, abs_pwr_mode_t pmode,
+			  const void *config, upwr_callb callb);
+
+
+
+/**
+ * upwr_pwm_reg_config() - Configures the uPower internal regulators.
+ * @config: pointer to the struct defining the regulator configuration;
+ * the struct upwr_reg_config_t is defined in the file upower_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the configurations of the
+ * internal regulators.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The service may fail with error UPWR_RESP_RESOURCE if a power mode transition
+ * or the same service (called from another domain) is executing simultaneously.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_reg_config(const struct upwr_reg_config_t *config,
+			upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_dom_bias() - Changes the domain bias.
+ * @bias: pointer to a domain bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the domain bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_chng_dom_bias(const struct upwr_dom_bias_cfg_t *bias,
+			   upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_mem_bias()- Changes a ROM/RAM power bias.
+ * @domain: identifier of the domain upon which the bias is applied.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bias: pointer to a memory bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the memory bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_chng_mem_bias(soc_domain_t domain,
+			   const struct upwr_mem_bias_cfg_t *bias,
+			   upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * VOLTAGE MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_vtm_pmic_cold_reset() -request cold reset the pmic.
+ * pmic will power cycle all the regulators
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to cold reset the pmic.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_cold_reset(upwr_callb callb);
+
+/**
+ * upwr_vtm_set_pmic_mode() -request uPower set pmic mode
+ * @pmic_mode: the target mode need to be set
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to set pmic mode
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_set_pmic_mode(uint32_t pmic_mode, upwr_callb callb);
+
+/**
+ * upwr_vtm_chng_pmic_voltage() - Changes the voltage of a given rail.
+ * @rail: pmic rail id.
+ * @volt: the target voltage of the given rail, accurate to uV
+ * If pass volt value 0, means that power off this rail.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_chng_pmic_voltage(uint32_t rail, uint32_t volt, upwr_callb callb);
+
+/**
+ * upwr_vtm_get_pmic_voltage() - Get the voltage of a given ral.
+ * @rail: pmic rail id.
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_get_pmic_voltage(uint32_t rail, upwr_callb callb);
+
+
+/**
+ * upwr_vtm_power_measure() - request uPower to measure power consumption
+ * @ssel: This field determines which power switches will have their currents
+ * sampled to be accounted for a
+ * current/power measurement. Support 0~7
+
+ * SSEL bit #	Power Switch
+ * 0	M33 core complex/platform/peripherals
+ * 1	Fusion Core and Peripherals
+ * 2	A35[0] core complex
+ * 3	A35[1] core complex
+ * 4	3DGPU
+ * 5	HiFi4
+ * 6	DDR Controller (PHY and PLL NOT included)
+ * 7	PXP, EPDC
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure power consumption
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The power consumption data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Accurate to uA
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_power_measure(uint32_t ssel, upwr_callb callb);
+
+/**
+ * upwr_vtm_vmeter_measure() - request uPower to measure voltage
+ * @vdetsel: Voltage Detector Selector, support 0~3
+ * 00b - RTD sense point
+ * 01b - LDO output
+ * 10b - APD domain sense point
+ * 11b - AVD domain sense point
+ * Refer to upower_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to use vmeter to measure voltage
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Refer to RM COREREGVL (Core Regulator Voltage Level)
+ * uPower return VDETLVL to user, user can calculate the real voltage:
+ *
+ * 0b000000(0x00) - 0.595833V
+ * 0b100110(0x26) - 1.007498V
+ * <value> - 0.595833V + <value>x10.8333mV
+ * 0b110010(0x32) - 1.138V
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_vmeter_measure(uint32_t vdetsel, upwr_callb callb);
+
+/**
+ * upwr_vtm_pmic_config() - Configures the SoC PMIC (Power Management IC).
+ * @config: pointer to a PMIC-dependent struct defining the PMIC configuration.
+ * @size:   size of the struct pointed by config, in bytes.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the PMIC configuration.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_config(const void *config, uint32_t size, upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * TEMPERATURE MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_tpm_get_temperature() - request uPower to get temperature of one temperature sensor
+ * @sensor_id: temperature sensor ID, support 0~2
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure temperature
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_TEMPM as the service group argument.
+ *
+ * The temperature data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * uPower return TSEL to the caller (M33 or A35), caller calculate the real temperature
+ * Tsh = 0.000002673049*TSEL[7:0]^3 + 0.0003734262*TSEL[7:0]^2 +
+0.4487042*TSEL[7:0] - 46.98694
+ *
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_tpm_get_temperature(uint32_t sensor_id, upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * DELAY MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_dlm_get_delay_margin() - request uPower to get delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The delay margin data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_get_delay_margin(uint32_t path, uint32_t index, upwr_callb callb);
+
+/**
+ * upwr_dlm_set_delay_margin() - request uPower to set delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @delay_margin: the value of delay margin
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to set delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of the corresponding critical path,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_set_delay_margin(uint32_t path, uint32_t index, uint32_t delay_margin, upwr_callb callb);
+
+/**
+ * upwr_dlm_process_monitor() - request uPower to do process monitor
+ * @chain_sel: Chain Cell Type Selection
+ * Select the chain to be used for the clock signal generation.
+ * Support two types chain cell, 0~1
+0b - P4 type delay cells selected
+1b - P16 type delay cells selected
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to do process monitor
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of process monitor,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_process_monitor(uint32_t chain_sel, upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * DIAGNOSE SERVICE GROUP
+ */
+
+/**
+ * upwr_dgn_mode() - Sets the diagnostic mode.
+ * @mode:  diagnostic mode, which can be:
+ *  - UPWR_DGN_NONE:   no diagnostic recorded
+ *  - UPWR_DGN_TRACE:  warnings, errors, service, internal activity recorded
+ *  - UPWR_DGN_SRVREQ: warnings, errors, service activity recorded
+ *  - UPWR_DGN_WARN:   warnings and errors recorded
+ *  - UPWR_DGN_ALL:    trace, service, warnings, errors, task state recorded
+ *  - UPWR_DGN_ERROR:  only errors recorded
+ *  - UPWR_DGN_ALL2ERR: record all until an error occurs,
+ *    freeze recording on error
+ *  - UPWR_DGN_ALL2HLT: record all until an error occurs,
+ *    executes an ebreak on error, which halts the core if enabled through
+ *    the debug interface
+ * @callb: pointer to the callback called when mode is changed.
+ * NULL if no callback is required.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_dgn_mode(upwr_dgn_mode_t mode, const upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * AUXILIARY CALLS
+ */
+
+/**
+ * upwr_rom_version() - informs the ROM firwmware version.
+ * @vmajor: pointer to the variable to get the firmware major version number.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: SoC id.
+ */
+uint32_t upwr_rom_version(uint32_t *vmajor, uint32_t *vminor, uint32_t *vfixes);
+
+/**
+ * upwr_ram_version() - informs the RAM firwmware version.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * The 3 values returned are 0 if no RAM firmwmare was loaded and initialized.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: firmware major version number.
+ */
+uint32_t upwr_ram_version(uint32_t *vminor, uint32_t *vfixes);
+
+/**
+ * upwr_req_status() - tells the status of the service group request, and
+ *                     returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ *
+ * This call can be used in a poll loop of a service request completion in case
+ * a callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+
+/* service request status */
+typedef enum {
+	UPWR_REQ_OK,     /* request succeeded */
+	UPWR_REQ_ERR,    /* request failed */
+	UPWR_REQ_BUSY    /* request execution ongoing */
+} upwr_req_status_t;
+
+upwr_req_status_t upwr_req_status(upwr_sg_t sg,
+				  uint32_t *sgfptr,
+				  upwr_resp_t *errptr,
+				  int *retptr);
+
+/**
+ * upwr_poll_req_status() - polls the status of the service group request, and
+ *                          returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ * @attempts: maximum number of polling attempts; if attempts > 0 and is
+ * reached with no service response received, upwr_poll_req_status returns
+ * UPWR_REQ_BUSY and variables pointed by sgfptr, retptr and errptr are not
+ * updated; if attempts = 0, upwr_poll_req_status waits "forever".
+ *
+ * This call can be used to poll a service request completion in case a
+ * callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+upwr_req_status_t upwr_poll_req_status(upwr_sg_t sg,
+				       uint32_t *sgfptr,
+				       upwr_resp_t *errptr,
+				       int *retptr,
+				       uint32_t attempts);
+
+/**
+ * upwr_alarm_code() - returns the alarm code of the last alarm occurrence.
+ *
+ * The value returned is not meaningful if no alarm was issued by uPower.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: alarm code, as defined by the type upwr_alarm_t in upwr_soc_defines.h
+ */
+upwr_alarm_t upwr_alarm_code(void);
+
+/**---------------------------------------------------------------
+ * TRANSMIT/RECEIVE PRIMITIVES
+ * ---------------------------------------------------------------
+ */
+
+typedef void (*UPWR_TX_CALLB_FUNC_T)(void);
+typedef void (*UPWR_RX_CALLB_FUNC_T)(void);
+
+/**
+ * upwr_tx() - queues a message for transmission.
+ * @msg : pointer to the message sent.
+ * @size: message size in 32-bit words
+ * @callback: pointer to a function to be called when transmission done;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of vacant positions left in the transmission queue, or
+ *         -1 if the queue was already full when upwr_tx was called, or
+ *         -2 if any argument is invalid (like size off-range)
+ */
+int upwr_tx(const uint32_t *msg, unsigned int size,
+	    UPWR_TX_CALLB_FUNC_T callback);
+
+/**
+ * upwr_rx() - unqueues a received message from the reception queue.
+ * @msg: pointer to the message destination buffer.
+ * @size: pointer to variable to hold message size in 32-bit words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of messages remaining in the reception queue, or
+ *         -1 if the queue was already empty when upwr_rx was called, or
+ *         -2 if any argument is invalid (like mu off-range)
+ */
+int upwr_rx(char *msg, unsigned int *size);
+
+/**
+ * upwr_rx_callback() - sets up a callback for a message receiving event.
+ * @callback: pointer to a function to be called when a message arrives;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok; -2 if any argument is invalid (mu off-range).
+ */
+int upwr_rx_callback(UPWR_RX_CALLB_FUNC_T callback);
+
+/**
+ * msg_copy() - copies a message.
+ * @dest: pointer to the destination message.
+ * @src : pointer to the source message.
+ * @size: message size in words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+void msg_copy(char *dest, char *src, unsigned int size);
+
+#endif /* UPWR_API_H */
diff --git a/plat/imx/imx8ulp/upower/upower_defs.h b/plat/imx/imx8ulp/upower/upower_defs.h
new file mode 100644
index 0000000..118d7e0
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_defs.h
@@ -0,0 +1,742 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ * -----------------------------------------------------------------------------
+ * PURPOSE: uPower driver API #defines and typedefs shared with the firmware
+ * -----------------------------------------------------------------------------
+ * PARAMETERS:
+ * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
+ * -----------------------------------------------------------------------------
+ * REUSE ISSUES: no reuse issues
+ */
+
+#ifndef UPWR_DEFS_H
+#define UPWR_DEFS_H
+
+#include <stdint.h>
+
+#ifndef UPWR_PMC_SWT_WORDS
+#define UPWR_PMC_SWT_WORDS              (1U)
+#endif
+
+#ifndef UPWR_PMC_MEM_WORDS
+#define UPWR_PMC_MEM_WORDS              (2U)
+#endif
+
+/* ****************************************************************************
+ * DOWNSTREAM MESSAGES - COMMANDS/FUNCTIONS
+ * ****************************************************************************
+ */
+#define UPWR_SRVGROUP_BITS  (4U)
+#define UPWR_FUNCTION_BITS  (4U)
+#define UPWR_PWDOMAIN_BITS  (4U)
+#define UPWR_HEADER_BITS   \
+		(UPWR_SRVGROUP_BITS + UPWR_FUNCTION_BITS + UPWR_PWDOMAIN_BITS)
+#define UPWR_ARG_BITS      (32U - UPWR_HEADER_BITS)
+#if   ((UPWR_ARG_BITS & 1U) > 0U)
+#error "UPWR_ARG_BITS must be an even number"
+#endif
+#define UPWR_ARG64_BITS          (64U - UPWR_HEADER_BITS)
+#define UPWR_HALF_ARG_BITS       (UPWR_ARG_BITS >> 1U)
+#define UPWR_DUAL_OFFSET_BITS    ((UPWR_ARG_BITS + 32U) >> 1U)
+
+/*
+ * message header: header fields common to all downstream messages.
+ */
+struct upwr_msg_hdr {
+	uint32_t domain   : UPWR_PWDOMAIN_BITS; /* power domain */
+	uint32_t srvgrp   : UPWR_SRVGROUP_BITS; /* service group */
+	uint32_t function : UPWR_FUNCTION_BITS; /* function */
+	uint32_t arg      : UPWR_ARG_BITS; /* function-specific argument */
+};
+
+/* generic 1-word downstream message format */
+typedef union {
+	struct upwr_msg_hdr  hdr;
+	uint32_t             word;  /* message first word */
+} upwr_down_1w_msg;
+
+/* generic 2-word downstream message format */
+typedef struct {
+	struct upwr_msg_hdr  hdr;
+	uint32_t             word2;  /* message second word */
+} upwr_down_2w_msg;
+
+/* message format for functions that receive a pointer/offset */
+typedef struct {
+	struct upwr_msg_hdr  hdr;
+	uint32_t             ptr; /* config struct offset */
+} upwr_pointer_msg;
+
+/* message format for functions that receive 2 pointers/offsets */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint64_t rsv : UPWR_HEADER_BITS;
+		uint64_t ptr0 : UPWR_DUAL_OFFSET_BITS;
+		uint64_t ptr1 : UPWR_DUAL_OFFSET_BITS;
+	} ptrs;
+} upwr_2pointer_msg;
+
+#define UPWR_SG_EXCEPT   (0U) /* 0 = exception           */
+#define UPWR_SG_PWRMGMT  (1U) /* 1 = power management    */
+#define UPWR_SG_DELAYM   (2U) /* 2 = delay   measurement */
+#define	UPWR_SG_VOLTM    (3U) /* 3 = voltage measurement */
+#define UPWR_SG_CURRM    (4U) /* 4 = current measurement */
+#define	UPWR_SG_TEMPM    (5U) /* 5 = temperature measurement */
+#define	UPWR_SG_DIAG     (6U) /* 6 = diagnostic  */
+#define	UPWR_SG_COUNT    (7U)
+
+typedef uint32_t upwr_sg_t;
+
+/* *************************************************************************
+ * Initialization - downstream
+ ***************************************************************************/
+typedef upwr_down_1w_msg upwr_start_msg; /* start command message */
+typedef upwr_down_1w_msg upwr_power_on_msg;   /* power on   command message */
+typedef upwr_down_1w_msg upwr_boot_start_msg; /* boot start command message */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	upwr_power_on_msg   power_on;
+	upwr_boot_start_msg boot_start;
+	upwr_start_msg      start;
+} upwr_startup_down_msg;
+
+/* *************************************************************************
+ * Service Group EXCEPTION - downstream
+ ***************************************************************************/
+
+#define	UPWR_XCP_INIT			(0U) /* 0 = init msg (not a service request itself) */
+#define	UPWR_XCP_PING			(0U) /* 0 = also ping request, since its response isan init msg */
+#define	UPWR_XCP_START			(1U) /* 1 = service start: upwr_start *(not a service request itself) */
+#define	UPWR_XCP_SHUTDOWN		(2U) /* 2 = service shutdown: upwr_xcp_shutdown */
+#define	UPWR_XCP_CONFIG			(3U) /* 3 = uPower configuration: upwr_xcp_config */
+#define	UPWR_XCP_SW_ALARM		(4U) /* 4 = uPower software alarm: upwr_xcp_sw_alarm */
+#define	UPWR_XCP_I2C			(5U) /* 5 = I2C access: upwr_xcp_i2c_access */
+#define	UPWR_XCP_SPARE_6		(6U) /* 6 = spare */
+#define	UPWR_XCP_SET_DDR_RETN		(7U) /* 7 = set/clear ddr retention */
+#define UPWR_XCP_SET_RTD_APD_LLWU	(8U) /* 8 = set/clear rtd/apd llwu */
+#define	UPWR_XCP_SPARE_8		(8U) /* 8 = spare */
+#define UPWR_XCP_SET_RTD_USE_DDR	(9U) /* 9 = M33 core set it is using DDR or not */
+#define	UPWR_XCP_SPARE_9		(9U)  /*  9 = spare */
+#define	UPWR_XCP_SPARE_10		(10U) /* 10 = spare */
+#define	UPWR_XCP_SET_MIPI_DSI_ENA	(10U) /* 10 = set/clear mipi dsi ena */
+#define	UPWR_XCP_SPARE_11		(11U) /* 11 = spare */
+#define	UPWR_XCP_GET_MIPI_DSI_ENA	(11U) /* 11 = get mipi dsi ena status */
+#define	UPWR_XCP_SPARE_12		(12U) /* 12 = spare */
+#define	UPWR_XCP_SET_OSC_MODE		(12U) /* 12 = set uPower OSC mode, high or low */
+#define	UPWR_XCP_SPARE_13		(13U) /* 13 = spare */
+#define	UPWR_XCP_SPARE_14		(14U) /* 14 = spare */
+#define	UPWR_XCP_SPARE_15		(15U) /* 15 = spare */
+#define	UPWR_XCP_F_COUNT		(16U)
+
+typedef uint32_t upwr_xcp_f_t;
+typedef upwr_down_1w_msg    upwr_xcp_ping_msg;
+typedef upwr_down_1w_msg    upwr_xcp_shutdown_msg;
+typedef upwr_power_on_msg   upwr_xcp_power_on_msg;
+typedef upwr_boot_start_msg upwr_xcp_boot_start_msg;
+typedef upwr_start_msg      upwr_xcp_start_msg;
+typedef upwr_down_2w_msg    upwr_xcp_config_msg;
+typedef upwr_down_1w_msg    upwr_xcp_swalarm_msg;
+typedef upwr_down_1w_msg    upwr_xcp_ddr_retn_msg;
+typedef upwr_down_1w_msg    upwr_xcp_set_mipi_dsi_ena_msg;
+typedef upwr_down_1w_msg    upwr_xcp_get_mipi_dsi_ena_msg;
+typedef upwr_down_1w_msg    upwr_xcp_rtd_use_ddr_msg;
+typedef upwr_down_1w_msg    upwr_xcp_rtd_apd_llwu_msg;
+typedef upwr_down_1w_msg    upwr_xcp_set_osc_mode_msg;
+typedef upwr_pointer_msg    upwr_xcp_i2c_msg;
+
+ /* structure pointed by message upwr_xcp_i2c_msg */
+typedef struct {
+	uint16_t addr;
+	int8_t data_size;
+	uint8_t subaddr_size;
+	uint32_t subaddr;
+	uint32_t data;
+} upwr_i2c_access;
+
+/* Exception all messages */
+typedef union {
+	struct upwr_msg_hdr       hdr;       /* message header */
+	upwr_xcp_ping_msg         ping;      /* ping */
+	upwr_xcp_start_msg        start;     /* service start */
+	upwr_xcp_shutdown_msg     shutdown;  /* shutdown */
+	upwr_xcp_boot_start_msg   bootstart; /* boot start */
+	upwr_xcp_config_msg       config;    /* uPower configuration */
+	upwr_xcp_swalarm_msg      swalarm;   /* software alarm */
+	upwr_xcp_i2c_msg          i2c;       /* I2C access */
+	upwr_xcp_ddr_retn_msg     set_ddr_retn;       /* set ddr retention msg */
+	upwr_xcp_set_mipi_dsi_ena_msg     set_mipi_dsi_ena; /* set mipi dsi ena msg */
+	upwr_xcp_get_mipi_dsi_ena_msg     get_mipi_dsi_ena; /* get mipi dsi ena msg */
+	upwr_xcp_rtd_use_ddr_msg     set_rtd_use_ddr; /* set rtd is using ddr msg */
+	upwr_xcp_rtd_apd_llwu_msg     set_llwu; /* set rtd/apd llwu msg */
+	upwr_xcp_set_osc_mode_msg     set_osc_mode; /* set osc_mode msg */
+} upwr_xcp_msg;
+
+/* structure pointed by message upwr_volt_dva_req_id_msg */
+typedef struct {
+	uint32_t id_word0;
+	uint32_t id_word1;
+	uint32_t mode;
+} upwr_dva_id_struct;
+
+/**
+ * PMIC voltage accuracy is 12.5 mV, 12500 uV
+ */
+#define PMIC_VOLTAGE_MIN_STEP 12500U
+
+/* *************************************************************************
+ * Service Group POWER MANAGEMENT - downstream
+ ***************************************************************************/
+
+#define	UPWR_PWM_REGCFG    (0U)     /* 0 = regulator config: upwr_pwm_reg_config */
+#define UPWR_PWM_DEVMODE   (0U)     /* deprecated, for old compile */
+#define	UPWR_PWM_VOLT      (1U)     /* 1 = voltage change: upwr_pwm_chng_reg_voltage */
+#define	UPWR_PWM_SWITCH    (2U)     /* 2 = switch control: upwr_pwm_chng_switch_mem */
+#define UPWR_PWM_PWR_ON    (3U)     /* 3 = switch/RAM/ROM power on: upwr_pwm_power_on  */
+#define	UPWR_PWM_PWR_OFF   (4U)     /* 4 = switch/RAM/ROM power off: upwr_pwm_power_off */
+#define	UPWR_PWM_RETAIN    (5U)     /* 5 = retain memory array: upwr_pwm_mem_retain */
+#define UPWR_PWM_DOM_BIAS  (6U)     /* 6 = Domain bias control: upwr_pwm_chng_dom_bias */
+#define	UPWR_PWM_MEM_BIAS  (7U)     /* 7 = Memory bias control: upwr_pwm_chng_mem_bias */
+#define	UPWR_PWM_PMICCFG   (8U)     /* 8 = PMIC configuration:  upwr_pwm_pmic_config */
+#define	UPWR_PWM_PMICMOD   (8U)     /* deprecated, for old compile */
+#define	UPWR_PWM_PES       (9U)     /* 9 so far, no use */
+#define	UPWR_PWM_CONFIG    (10U)    /* 10= apply power mode defined configuration */
+#define	UPWR_PWM_CFGPTR    (11U)    /* 11= configuration pointer */
+#define	UPWR_PWM_DOM_PWRON (12U)    /* 12 = domain power on: upwr_pwm_dom_power_on */
+#define	UPWR_PWM_BOOT      (13U)    /* 13 = boot start: upwr_pwm_boot_start */
+#define UPWR_PWM_FREQ      (14U)    /* 14 = domain frequency setup */
+#define	UPWR_PWM_PARAM     (15U)    /* 15 = power management parameters */
+#define	UPWR_PWM_F_COUNT (16U)
+
+typedef uint32_t upwr_pwm_f_t;
+
+#define MAX_PMETER_SSEL 7U
+
+#define	UPWR_VTM_CHNG_PMIC_RAIL_VOLT    (0U)      /* 0 = change pmic rail voltage */
+#define	UPWR_VTM_GET_PMIC_RAIL_VOLT     (1U)      /* 1 = get pmic rail voltage */
+#define UPWR_VTM_PMIC_CONFIG            (2U)      /* 2 = configure PMIC IC */
+#define UPWR_VTM_DVA_DUMP_INFO          (3U)      /* 3 = dump dva information */
+#define UPWR_VTM_DVA_REQ_ID             (4U)      /* 4 = dva request ID array */
+#define UPWR_VTM_DVA_REQ_DOMAIN         (5U)      /* 5 = dva request domain */
+#define UPWR_VTM_DVA_REQ_SOC            (6U)      /* 6 = dva request the whole SOC */
+#define UPWR_VTM_PMETER_MEAS            (7U)      /* 7 = pmeter measure */
+#define UPWR_VTM_VMETER_MEAS            (8U)      /* 8 = vmeter measure */
+#define UPWR_VTM_PMIC_COLD_RESET        (9U)      /* 9 = pmic cold reset */
+#define UPWR_VTM_SET_DVFS_PMIC_RAIL     (10U)     /* 10 = set which domain use which pmic rail, for DVFS use */
+#define UPWR_VTM_SET_PMIC_MODE          (11U)     /* 11 = set pmic mode */
+#define UPWR_VTM_F_COUNT                (16U)
+
+typedef uint32_t upwr_volt_f_t;
+
+#define VMETER_SEL_RTD 0U
+#define VMETER_SEL_LDO 1U
+#define VMETER_SEL_APD 2U
+#define VMETER_SEL_AVD 3U
+#define VMETER_SEL_MAX 3U
+
+/**
+ * The total TSEL count is 256
+ */
+#define MAX_TEMP_TSEL 256U
+
+/**
+ * Support 3 temperature sensor, sensor 0, 1, 2
+ */
+#define MAX_TEMP_SENSOR 2U
+
+#define UPWR_TEMP_GET_CUR_TEMP (0U)  /* 0 = get current temperature */
+#define UPWR_TEMP_F_COUNT      (1U)
+typedef uint32_t upwr_temp_f_t;
+
+#define UPWR_DMETER_GET_DELAY_MARGIN (0U)  /* 0 = get delay margin */
+#define UPWR_DMETER_SET_DELAY_MARGIN (1U) /* 1 = set delay margin */
+#define UPWR_PMON_REQ                (2U) /* 2 = process monitor service */
+#define UPWR_DMETER_F_COUNT          (3U)
+
+typedef uint32_t upwr_dmeter_f_t;
+
+typedef upwr_down_1w_msg upwr_volt_pmeter_meas_msg;
+typedef upwr_down_1w_msg upwr_volt_pmic_set_mode_msg;
+typedef upwr_down_1w_msg upwr_volt_vmeter_meas_msg;
+
+struct upwr_reg_config_t {
+	uint32_t reg;
+};
+
+ /* set of 32 switches */
+struct upwr_switch_board_t {
+	uint32_t on;   /* Switch on state,1 bit per instance */
+	uint32_t mask; /* actuation mask, 1 bit per instance */
+};
+
+ /* set of 32 RAM/ROM switches */
+struct upwr_mem_switches_t {
+	uint32_t array;   /* RAM/ROM array state, 1 bit per instance */
+	uint32_t perif;   /* RAM/ROM peripheral state, 1 bit per instance */
+	uint32_t mask;    /* actuation mask, 1 bit per instance */
+};
+
+typedef upwr_down_1w_msg upwr_pwm_dom_pwron_msg;  /* domain power on message */
+typedef upwr_down_1w_msg upwr_pwm_boot_start_msg; /* boot start message */
+
+/* functions with complex arguments use the pointer message formats: */
+typedef upwr_pointer_msg upwr_pwm_retain_msg;
+typedef upwr_pointer_msg upwr_pwm_pmode_cfg_msg;
+
+#if (UPWR_ARG_BITS < UPWR_DOMBIAS_ARG_BITS)
+#if ((UPWR_ARG_BITS + 32) < UPWR_DOMBIAS_ARG_BITS)
+#error "too few message bits for domain bias argument"
+#endif
+#endif
+
+/* service upwr_pwm_chng_dom_bias message argument fields */
+#define UPWR_DOMBIAS_MODE_BITS    (2U)
+#define UPWR_DOMBIAS_RBB_BITS     (8U)
+#define UPWR_DOMBIAS_RSV_BITS     (14U)
+#define UPWR_DOMBIAS_ARG_BITS     (UPWR_DOMBIAS_RSV_BITS + \
+				  (2U * UPWR_DOMBIAS_MODE_BITS) + \
+				  (4U * UPWR_DOMBIAS_RBB_BITS) + 2U)
+/*
+ * upwr_pwm_dom_bias_args is an SoC-dependent message,
+ */
+typedef struct {
+	uint32_t: 12U; /* TODO: find a way to use UPWR_HEADER_BITS */
+	uint32_t dommode : UPWR_DOMBIAS_MODE_BITS;
+	uint32_t avdmode : UPWR_DOMBIAS_MODE_BITS;
+	uint32_t domapply : 1U;
+	uint32_t avdapply : 1U;
+	uint32_t rsv : UPWR_DOMBIAS_RSV_BITS;
+	uint32_t domrbbn : UPWR_DOMBIAS_RBB_BITS; /* RTD/APD back bias N-well */
+	uint32_t domrbbp : UPWR_DOMBIAS_RBB_BITS; /* RTD/APD back bias P-well */
+	uint32_t avdrbbn : UPWR_DOMBIAS_RBB_BITS; /* AVD back bias N-well */
+	uint32_t avdrbbp : UPWR_DOMBIAS_RBB_BITS; /* AVD back bias P-well */
+} upwr_pwm_dom_bias_args;
+
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	struct {
+		upwr_pwm_dom_bias_args B;
+	} args;
+} upwr_pwm_dom_bias_msg;
+
+/* service upwr_pwm_chng_mem_bias message argument fields */
+/*
+ * upwr_pwm_mem_bias_args is an SoC-dependent message,
+ * defined in upower_soc_defs.h
+ */
+typedef struct {
+	uint32_t: 12U; /* TODO: find a way to use UPWR_HEADER_BITS */
+	uint32_t en : 1U;
+	uint32_t rsv : 19U;
+} upwr_pwm_mem_bias_args;
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	struct {
+		upwr_pwm_mem_bias_args B;
+	} args;
+} upwr_pwm_mem_bias_msg;
+
+typedef upwr_pointer_msg upwr_pwm_pes_seq_msg;
+
+/* upwr_pwm_reg_config-specific message format */
+typedef upwr_pointer_msg upwr_pwm_regcfg_msg;
+
+/* upwr_volt_pmic_volt-specific message format */
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t domain : 8U;
+		uint32_t rail : 8U;
+	} args;
+} upwr_volt_dom_pmic_rail_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t rail : 4U;  /* pmic rail id  */
+		uint32_t volt : 12U; /* voltage value, accurate to mV, support 0~3.3V */
+	} args;
+} upwr_volt_pmic_set_volt_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t rail : 16U;  /* pmic rail id  */
+	} args;
+} upwr_volt_pmic_get_volt_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv :UPWR_HEADER_BITS;
+		uint32_t domain : 8U;
+		uint32_t mode : 8U; /* work mode */
+	} args;
+} upwr_volt_dva_req_domain_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t mode : 16U;  /* work mode  */
+	} args;
+} upwr_volt_dva_req_soc_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t addr_offset : 16U;  /* addr_offset to 0x28330000  */
+	} args;
+} upwr_volt_dva_dump_info_msg;
+
+typedef upwr_pointer_msg upwr_volt_pmiccfg_msg;
+typedef upwr_pointer_msg upwr_volt_dva_req_id_msg;
+typedef upwr_down_1w_msg upwr_volt_pmic_cold_reset_msg;
+
+/* upwr_pwm_volt-specific message format */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t reg : UPWR_HALF_ARG_BITS;  /* regulator id  */
+		uint32_t volt : UPWR_HALF_ARG_BITS; /* voltage value */
+	} args;
+} upwr_pwm_volt_msg;
+
+/* upwr_pwm_freq_setup-specific message format */
+/**
+ * DVA adjust stage
+ */
+#define DVA_ADJUST_STAGE_INVALID 0U
+/* first stage, gross adjust, for increase frequency use */
+#define DVA_ADJUST_STAGE_ONE 1U
+/* second stage, fine adjust for increase frequency use */
+#define DVA_ADJUST_STAGE_TWO 2U
+/* combine first + second stage, for descrese frequency use */
+#define DVA_ADJUST_STAGE_FULL 3U
+
+/**
+ * This message structure is used for DVFS feature
+ * 1. Because user may use different PMIC or different board,
+ * the pmic regulator of RTD/APD may change,
+ * so, user need to tell uPower the regulator number.
+ * The number must be matched with PMIC IC and board.
+ * use 4 bits for pmic regulator, support to 16 regulator.
+ *
+ * use 2 bits for DVA stage
+ *
+ * use 10 bits for target frequency, accurate to MHz, support to 1024 MHz
+ */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t rail : 4; /* pmic regulator  */
+		uint32_t stage : 2; /* DVA stage */
+		uint32_t target_freq : 10; /* target frequency */
+	} args;
+} upwr_pwm_freq_msg;
+
+typedef upwr_down_2w_msg upwr_pwm_param_msg;
+
+/* upwr_pwm_pmiccfg-specific message format */
+typedef upwr_pointer_msg upwr_pwm_pmiccfg_msg;
+
+/* functions that pass a pointer use message format upwr_pointer_msg */
+typedef upwr_pointer_msg upwr_pwm_cfgptr_msg;
+
+/* functions that pass 2 pointers use message format upwr_2pointer_msg
+ */
+typedef upwr_2pointer_msg upwr_pwm_switch_msg;
+typedef upwr_2pointer_msg upwr_pwm_pwron_msg;
+typedef upwr_2pointer_msg upwr_pwm_pwroff_msg;
+
+/* Power Management all messages */
+typedef union {
+	struct upwr_msg_hdr     hdr;      /* message header */
+	upwr_pwm_param_msg      param;    /* power management parameters */
+	upwr_pwm_dom_bias_msg   dom_bias; /* domain bias message */
+	upwr_pwm_mem_bias_msg   mem_bias; /* memory bias message */
+	upwr_pwm_pes_seq_msg    pes;      /* PE seq. message */
+	upwr_pwm_pmode_cfg_msg  pmode;    /* power mode config message */
+	upwr_pwm_regcfg_msg     regcfg;   /* regulator config message */
+	upwr_pwm_volt_msg       volt;     /* set voltage message */
+	upwr_pwm_freq_msg       freq;     /* set frequency message */
+	upwr_pwm_switch_msg     switches; /* switch control message */
+	upwr_pwm_pwron_msg      pwron;    /* switch/RAM/ROM power on  message */
+	upwr_pwm_pwroff_msg     pwroff;   /* switch/RAM/ROM power off message */
+	upwr_pwm_retain_msg     retain;   /* memory retain message */
+	upwr_pwm_cfgptr_msg     cfgptr;   /* configuration pointer message*/
+	upwr_pwm_dom_pwron_msg  dompwron; /* domain power on message */
+	upwr_pwm_boot_start_msg boot;     /* boot start      message */
+} upwr_pwm_msg;
+
+typedef union {
+	struct upwr_msg_hdr     hdr;      /* message header */
+	upwr_volt_pmic_set_volt_msg  set_pmic_volt;     /* set pmic voltage message */
+	upwr_volt_pmic_get_volt_msg  get_pmic_volt;     /* set pmic voltage message */
+	upwr_volt_pmic_set_mode_msg  set_pmic_mode;     /* set pmic mode message */
+	upwr_volt_pmiccfg_msg    pmiccfg;  /* PMIC configuration message */
+	upwr_volt_dom_pmic_rail_msg   dom_pmic_rail; /* domain bias message */
+	upwr_volt_dva_dump_info_msg    dva_dump_info;  /* dump dva info message */
+	upwr_volt_dva_req_id_msg    dva_req_id;  /* dump dva request id array message */
+	upwr_volt_dva_req_domain_msg    dva_req_domain;  /* dump dva request domain message */
+	upwr_volt_dva_req_soc_msg    dva_req_soc;  /* dump dva request whole soc message */
+	upwr_volt_pmeter_meas_msg    pmeter_meas_msg;  /* pmeter measure message */
+	upwr_volt_vmeter_meas_msg    vmeter_meas_msg;  /* vmeter measure message */
+	upwr_volt_pmic_cold_reset_msg    cold_reset_msg;  /* pmic cold reset message */
+} upwr_volt_msg;
+
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t sensor_id : 16U; /* temperature sensor id  */
+	} args;
+} upwr_temp_get_cur_temp_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t index : 8U; /* the delay meter index  */
+		uint32_t path : 8U; /* the critical path number  */
+	} args;
+} upwr_dmeter_get_delay_margin_msg;
+
+#define MAX_DELAY_MARGIN 63U
+#define MAX_DELAY_CRITICAL_PATH 7U
+#define MAX_DELAY_METER_NUM 1U
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t index: 4U;  /* the delay meter index  */
+		uint32_t path: 4U;  /* the critical path number  */
+		uint32_t dm: 8U;  /* the delay margin value of delay meter  */
+	} args;
+} upwr_dmeter_set_delay_margin_msg;
+
+#define MAX_PMON_CHAIN_SEL 1U
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t chain_sel : 16U;  /* the process monitor delay chain sel  */
+	} args;
+} upwr_pmon_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	upwr_temp_get_cur_temp_msg get_temp_msg; /* get current temperature message */
+} upwr_temp_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	upwr_dmeter_get_delay_margin_msg  get_margin_msg; /* get delay margin message */
+	upwr_dmeter_set_delay_margin_msg  set_margin_msg; /* set delay margin message */
+	upwr_pmon_msg pmon_msg; /* process monitor message */
+} upwr_dmeter_msg;
+
+typedef upwr_down_2w_msg upwr_down_max_msg; /* longest downstream msg */
+
+/*
+ * upwr_dom_bias_cfg_t and upwr_mem_bias_cfg_t are SoC-dependent structs,
+ * defined in upower_soc_defs.h
+ */
+/* Power and mem switches */
+typedef struct {
+	volatile struct upwr_switch_board_t swt_board[UPWR_PMC_SWT_WORDS];
+	volatile struct upwr_mem_switches_t swt_mem[UPWR_PMC_MEM_WORDS];
+} swt_config_t;
+
+/* *************************************************************************
+ * Service Group DIAGNOSE - downstream
+ ***************************************************************************/
+/* Diagnose Functions */
+#define	UPWR_DGN_MODE              (0U) /* 0 = diagnose mode: upwr_dgn_mode */
+#define	UPWR_DGN_F_COUNT           (1U)
+#define UPWR_DGN_BUFFER_EN         (2U)
+typedef uint32_t upwr_dgn_f_t;
+
+#define UPWR_DGN_ALL2ERR            (0U) /* record all until an error occurs, freeze recording on error */
+#define UPWR_DGN_ALL2HLT            (1U) /* record all until an error occurs, halt core on error */
+#define UPWR_DGN_ALL                (2U) /* trace, warnings, errors, task state recorded */
+#define UPWR_DGN_MAX                UPWR_DGN_ALL
+#define UPWR_DGN_TRACE              (3U) /* trace, warnings, errors recorded */
+#define UPWR_DGN_SRVREQ             (4U) /* service request activity recorded */
+#define UPWR_DGN_WARN               (5U) /* warnings and errors recorded */
+#define UPWR_DGN_ERROR              (6U) /* only errors recorded */
+#define UPWR_DGN_NONE               (7U) /* no diagnostic recorded */
+#define UPWR_DGN_COUNT              (8U)
+typedef uint32_t upwr_dgn_mode_t;
+
+typedef upwr_down_1w_msg upwr_dgn_mode_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	upwr_dgn_mode_msg mode_msg;
+} upwr_dgn_msg;
+
+typedef struct {
+	struct upwr_msg_hdr hdr;
+	uint32_t buf_addr;
+} upwr_dgn_v2_msg;
+
+/* diagnostics log types in the shared RAM log buffer */
+
+typedef enum {
+	DGN_LOG_NONE       = 0x00000000,
+	DGN_LOG_INFO       = 0x10000000,
+	DGN_LOG_ERROR      = 0x20000000,
+	DGN_LOG_ASSERT     = 0x30000000,
+	DGN_LOG_EXCEPT     = 0x40000000,
+	DGN_LOG_EVENT      = 0x50000000, // old event trace
+	DGN_LOG_EVENTNEW   = 0x60000000, // new event trace
+	DGN_LOG_SERVICE    = 0x70000000,
+	DGN_LOG_TASKDEF    = 0x80000000,
+	DGN_LOG_TASKEXE    = 0x90000000,
+	DGN_LOG_MUTEX      = 0xA0000000,
+	DGN_LOG_SEMAPH     = 0xB0000000,
+	DGN_LOG_TIMER      = 0xC0000000,
+	DGN_LOG_CALLTRACE  = 0xD0000000,
+	DGN_LOG_DATA       = 0xE0000000,
+	DGN_LOG_PCTRACE    = 0xF0000000
+} upwr_dgn_log_t;
+
+/* ****************************************************************************
+ * UPSTREAM MESSAGES - RESPONSES
+ * ****************************************************************************
+ */
+/* generic ok/ko response message */
+#define UPWR_RESP_ERR_BITS (4U)
+#define UPWR_RESP_HDR_BITS (UPWR_RESP_ERR_BITS+\
+			    UPWR_SRVGROUP_BITS+UPWR_FUNCTION_BITS)
+#define UPWR_RESP_RET_BITS (32U - UPWR_RESP_HDR_BITS)
+
+#define UPWR_RESP_OK                (0U) /* no error */
+#define UPWR_RESP_SG_BUSY           (1U) /* service group is busy */
+#define UPWR_RESP_SHUTDOWN          (2U) /* services not up or shutting down */
+#define UPWR_RESP_BAD_REQ           (3U) /* invalid request */
+#define UPWR_RESP_BAD_STATE         (4U) /* system state doesn't allow perform the request */
+#define UPWR_RESP_UNINSTALLD        (5U) /* service or function not installed */
+#define UPWR_RESP_UNINSTALLED       (5U) /* service or function not installed (alias) */
+#define UPWR_RESP_RESOURCE          (6U) /* resource not available */
+#define UPWR_RESP_TIMEOUT           (7U) /* service timeout */
+#define UPWR_RESP_COUNT             (8U)
+
+typedef uint32_t upwr_resp_t;
+
+struct upwr_resp_hdr {
+	uint32_t errcode : UPWR_RESP_ERR_BITS;
+	uint32_t srvgrp  : UPWR_SRVGROUP_BITS;      /* service group */
+	uint32_t function: UPWR_FUNCTION_BITS;
+	uint32_t ret     : UPWR_RESP_RET_BITS;      /* return value, if any */
+};
+
+/* generic 1-word upstream message format */
+typedef union {
+	struct upwr_resp_hdr hdr;
+	uint32_t word;
+} upwr_resp_msg;
+
+/* generic 2-word upstream message format */
+typedef struct {
+	struct upwr_resp_hdr hdr;
+	uint32_t word2;  /* message second word */
+} upwr_up_2w_msg;
+
+typedef upwr_up_2w_msg upwr_up_max_msg;
+
+/* *************************************************************************
+ * Exception/Initialization - upstream
+ ***************************************************************************/
+#define UPWR_SOC_BITS    (7U)
+#define UPWR_VMINOR_BITS (4U)
+#define UPWR_VFIXES_BITS (4U)
+#define UPWR_VMAJOR_BITS \
+		(32U - UPWR_HEADER_BITS - UPWR_SOC_BITS - UPWR_VMINOR_BITS - UPWR_VFIXES_BITS)
+
+typedef struct {
+	uint32_t soc_id;
+	uint32_t vmajor;
+	uint32_t vminor;
+	uint32_t vfixes;
+} upwr_code_vers_t;
+
+/* message sent by firmware initialization, received by upwr_init */
+typedef union {
+	struct upwr_resp_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_RESP_HDR_BITS;
+		uint32_t soc : UPWR_SOC_BITS;        /* SoC identification */
+		uint32_t vmajor : UPWR_VMAJOR_BITS;  /* firmware major version */
+		uint32_t vminor : UPWR_VMINOR_BITS;  /* firmware minor version */
+		uint32_t vfixes : UPWR_VFIXES_BITS;  /* firmware fixes version */
+	} args;
+} upwr_init_msg;
+
+/* message sent by firmware when the core platform is powered up */
+typedef upwr_resp_msg upwr_power_up_msg;
+
+/* message sent by firmware when the core reset is released for boot */
+typedef upwr_resp_msg upwr_boot_up_msg;
+
+/* message sent by firmware when ready for service requests */
+#define UPWR_RAM_VMINOR_BITS (7)
+#define UPWR_RAM_VFIXES_BITS (6)
+#define UPWR_RAM_VMAJOR_BITS (32 - UPWR_HEADER_BITS \
+		- UPWR_RAM_VFIXES_BITS - UPWR_RAM_VMINOR_BITS)
+typedef union {
+	struct upwr_resp_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_RESP_HDR_BITS;
+		uint32_t vmajor : UPWR_RAM_VMAJOR_BITS; /* RAM fw major version */
+		uint32_t vminor : UPWR_RAM_VMINOR_BITS; /* RAM fw minor version */
+		uint32_t vfixes : UPWR_RAM_VFIXES_BITS; /* RAM fw fixes version */
+	} args;
+} upwr_ready_msg;
+
+/* message sent by firmware when shutdown finishes */
+typedef upwr_resp_msg upwr_shutdown_msg;
+
+typedef union {
+	struct upwr_resp_hdr hdr;
+	upwr_init_msg        init;
+	upwr_power_up_msg    pwrup;
+	upwr_boot_up_msg     booted;
+	upwr_ready_msg       ready;
+} upwr_startup_up_msg;
+
+/* message sent by firmware for uPower config setting */
+typedef upwr_resp_msg upwr_config_resp_msg;
+
+/* message sent by firmware for uPower alarm */
+typedef upwr_resp_msg upwr_alarm_resp_msg;
+
+/* *************************************************************************
+ * Power Management - upstream
+ ***************************************************************************/
+typedef upwr_resp_msg upwr_param_resp_msg;
+
+enum work_mode {
+	OVER_DRIVE,
+	NORMAL_DRIVE,
+	LOW_DRIVE
+};
+
+#define UTIMER3_MAX_COUNT 0xFFFFU
+
+#endif /* UPWR_DEFS_H */
diff --git a/plat/imx/imx8ulp/upower/upower_hal.c b/plat/imx/imx8ulp/upower/upower_hal.c
new file mode 100644
index 0000000..337857b
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_hal.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "upower_api.h"
+#include "upower_defs.h"
+
+#define UPOWER_AP_MU1_ADDR	U(0x29280000)
+
+struct MU_t *muptr = (struct MU_t *)UPOWER_AP_MU1_ADDR;
+
+void upower_apd_inst_isr(upwr_isr_callb txrx_isr,
+			 upwr_isr_callb excp_isr)
+{
+	/* Do nothing */
+}
+
+int upower_status(int status)
+{
+	int ret = -1;
+
+	switch (status) {
+	case 0:
+		VERBOSE("finished successfully!\n");
+		ret = 0;
+		break;
+	case -1:
+		VERBOSE("memory allocation or resource failed!\n");
+		break;
+	case -2:
+		VERBOSE("invalid argument!\n");
+		break;
+	case -3:
+		VERBOSE("called in an invalid API state!\n");
+		break;
+	default:
+		VERBOSE("invalid return status\n");
+		break;
+	}
+
+	return ret;
+}
+
+
+void upower_wait_resp(void)
+{
+	while (muptr->RSR.B.RF0 == 0) {
+		udelay(100);
+	}
+	upwr_txrx_isr();
+}
+
+static void user_upwr_rdy_callb(uint32_t soc, uint32_t vmajor, uint32_t vminor)
+{
+	NOTICE("%s: soc=%x\n", __func__, soc);
+	NOTICE("%s: RAM version:%d.%d\n", __func__, vmajor, vminor);
+}
+
+int upower_init(void)
+{
+	int status;
+
+	status = upwr_init(APD_DOMAIN, muptr, NULL, NULL, upower_apd_inst_isr, NULL);
+	if (upower_status(status)) {
+		ERROR("%s: upower init failure\n", __func__);
+		return -EINVAL;
+	}
+
+	NOTICE("%s: start uPower RAM service\n", __func__);
+	status = upwr_start(1, user_upwr_rdy_callb);
+	upower_wait_resp();
+	/* poll status */
+	if (upower_status(status)) {
+		NOTICE("%s: upower init failure\n", __func__);
+		return status;
+	}
+
+	return 0;
+}
+
+int upower_pwm(int domain_id, bool pwr_on)
+{
+	int ret, ret_val;
+	uint32_t swt;
+
+	if (domain_id == 9U || domain_id == 11U || domain_id == 12U) {
+		swt = BIT_32(12) | BIT_32(11) | BIT_32(10) | BIT_32(9);
+	} else {
+		swt = BIT_32(domain_id);
+	}
+
+	if (pwr_on) {
+		ret = upwr_pwm_power_on(&swt, NULL, NULL);
+	} else {
+		ret = upwr_pwm_power_off(&swt, NULL, NULL);
+	}
+
+	if (ret) {
+		NOTICE("%s failed: ret: %d, pwr_on: %d\n", __func__, ret, pwr_on);
+		return ret;
+	}
+	upower_wait_resp();
+
+	ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		NOTICE("Failure %d, %s\n", ret, __func__);
+		if (ret == UPWR_REQ_BUSY) {
+			return -EBUSY;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int upower_read_temperature(uint32_t sensor_id, int32_t *temperature)
+{
+	int ret, ret_val;
+	upwr_resp_t err_code;
+	int64_t t;
+
+	ret = upwr_tpm_get_temperature(sensor_id, NULL);
+	if (ret) {
+		return ret;
+	}
+
+	upower_wait_resp();
+	ret = upwr_poll_req_status(UPWR_SG_TEMPM, NULL, &err_code, &ret_val, 1000);
+	if (ret > UPWR_REQ_OK) {
+		return ret;
+	}
+
+	t = ret_val & 0xff;
+	*temperature = (2673049 * t * t * t / 10000000 + 3734262 * t * t / 100000 +
+			4487042 * t / 100 - 4698694) / 100000;
+
+	return 0;
+}
+
+int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val)
+{
+	int ret, ret_val;
+	upwr_resp_t err_code;
+
+	ret = upwr_xcp_i2c_access(0x32, 1, 1, reg_addr, reg_val, NULL);
+	if (ret) {
+		WARN("pmic i2c read failed ret %d\n", ret);
+		return ret;
+	}
+
+	upower_wait_resp();
+	ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		WARN("i2c poll Failure %d, err_code %d, ret_val 0x%x\n",
+		     ret, err_code, ret_val);
+		return ret;
+	}
+
+	VERBOSE("PMIC write reg[0x%x], val[0x%x]\n", reg_addr, reg_val);
+
+	return 0;
+}
+
+int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val)
+{
+	int ret, ret_val;
+	upwr_resp_t err_code;
+
+	if (reg_val == NULL) {
+		return -1;
+	}
+
+	ret = upwr_xcp_i2c_access(0x32, -1, 1, reg_addr, 0, NULL);
+	if (ret) {
+		WARN("pmic i2c read failed ret %d\n", ret);
+		return ret;
+	}
+
+	upower_wait_resp();
+	ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		WARN("i2c poll Failure %d, err_code %d, ret_val 0x%x\n",
+			ret, err_code, ret_val);
+		return ret;
+	}
+
+	*reg_val = ret_val;
+
+	VERBOSE("PMIC read reg[0x%x], val[0x%x]\n", reg_addr, *reg_val);
+
+	return 0;
+}
diff --git a/plat/imx/imx8ulp/upower/upower_soc_defs.h b/plat/imx/imx8ulp/upower/upower_soc_defs.h
new file mode 100644
index 0000000..111be14
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_soc_defs.h
@@ -0,0 +1,1154 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ * -----------------------------------------------------------------------------
+ * PURPOSE: SoC-dependent uPower driver API #defines and typedefs shared
+ *          with the firmware
+ * -----------------------------------------------------------------------------
+ * PARAMETERS:
+ * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
+ * -----------------------------------------------------------------------------
+ * REUSE ISSUES: no reuse issues
+ */
+
+#ifndef UPWR_SOC_DEFS_H
+#define UPWR_SOC_DEFS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "upower_defs.h"
+
+#define UPWR_MU_MSG_SIZE            (2U) /* words */
+
+#ifdef NUM_PMC_SWT_WORDS
+#define UPWR_PMC_SWT_WORDS          NUM_PMC_SWT_WORDS
+#endif
+
+#ifdef NUM_PMC_RAM_WORDS
+#define UPWR_PMC_MEM_WORDS          NUM_PMC_RAM_WORDS
+#endif
+
+#ifndef UPWR_DRAM_SHARED_BASE_ADDR
+#define UPWR_DRAM_SHARED_BASE_ADDR      (0x28330000U)
+#endif
+
+#ifndef UPWR_DRAM_SHARED_SIZE
+#define UPWR_DRAM_SHARED_SIZE           (2048U)
+#endif
+
+#define UPWR_DRAM_SHARED_ENDPLUS        (UPWR_DRAM_SHARED_BASE_ADDR+\
+					 UPWR_DRAM_SHARED_SIZE)
+
+#ifndef UPWR_API_BUFFER_BASE
+#define UPWR_API_BUFFER_BASE            (0x28330600U)
+#endif
+
+#ifndef UPWR_API_BUFFER_ENDPLUS
+#define UPWR_API_BUFFER_ENDPLUS         (UPWR_DRAM_SHARED_ENDPLUS - 64U)
+#endif
+
+#ifndef UPWR_PMC_SWT_WORDS
+#define UPWR_PMC_SWT_WORDS              (1U)
+#endif
+
+#ifndef UPWR_PMC_MEM_WORDS
+#define UPWR_PMC_MEM_WORDS              (2U)
+#endif
+
+#define UPWR_OSC_HI_FREQ               (64U) // MHz
+#define UPWR_OSC_LO_FREQ               (16U) // MHz
+
+#ifndef UPWR_I2C_FREQ
+#define UPWR_I2C_FREQ                  (UPWR_OSC_HI_FREQ * 1000000U)
+#endif
+
+/*
+ * i.MX8ULP-dependent uPower API Definition
+ *
+ * This chapter documents the API definitions that are specific to the
+ * i.MX8ULP SoC.
+ *
+ */
+
+/**---------------------------------------------------------------
+ * INITIALIZATION, CONFIGURATION
+ *
+ * i.MX8ULP provides only one Message Unit (MU) for each core domain:
+ * Real Time Domain (RTD) and Application Domain (APD), which has two A35 cores.
+ * Both A35 cores in APD must share the same API instance, meaning upwr_init
+ * must be called only once for each domain. The API does not provide any
+ * mutually exclusion or locking mechanism for concurrent accesses from both
+ * APD cores, so any API arbitration, if needed, must be implemented by the
+ * API user code.
+ *
+ * A domain must not go to Power Down (PD) or Deep Power Down (DPD) power modes
+ * with any service still pending (response not received).
+ *
+ * Next sections describe the i.MX8ULP particularities of service calls.
+ *
+ */
+
+/**+
+ * upwr_start()
+ *
+ * i.MX8ULP ROM firmware provides only the launch option 0, which has no
+ * power mode transition support and provides the following services:
+ * - upwr_xcp_config
+ * - upwr_xcp_sw_alarm
+ * - upwr_pwm_param
+ * - upwr_pwm_power_on
+ * - upwr_pwm_power-off
+ * - upwr_pwm_mem_retain
+ * - upwr_pwm_chng_dom_bias
+ * - upwr_pwm_chng_mem_bias
+ *
+ * i.MX8ULP RAM firmware provides 2 launch options:
+ *
+ * 1. starts all tasks, services and power mode ones;
+ *    this is the full-featured firmware option.
+ * 2. starts only the power mode tasks; services are not available with
+ *    this option, and futher calls to upwr_start (from either domain)
+ *    have no response; this option is mostly used to accelerate power mode
+ *    mixed-signal simulations, and not intended to be used with silicon.
+ *
+ * Note: option 0 is also available if the RAM firmware is loaded.
+ */
+
+/* service upwr_pwm_set_domain_pmic_rail message argument fields*/
+typedef struct {
+	uint32_t domain : 16U;
+	uint32_t rail : 16U;
+} upwr_pwm_dom_pmic_rail_args;
+
+#define UPWR_FILL_DOMBIAS_ARGS(dom, bias, args)           \
+do {                                                      \
+	(args).B.domapply = (args).B.avdapply = 0U;            \
+	switch ((bias)->apply) {                            \
+	case BIAS_APPLY_RTD_AVD:                  \
+		(args).B.avdapply = 1U;              \
+	/* fall through */                        \
+	case BIAS_APPLY_RTD:                      \
+		(dom) = (uint32_t)RTD_DOMAIN;       \
+		(args).B.domapply = 1U;              \
+		break;                            \
+	case BIAS_APPLY_APD_AVD:                  \
+		(args).B.avdapply = 1U;              \
+	/* fall through */                      \
+	case BIAS_APPLY_APD:                      \
+		(dom) = (uint32_t)APD_DOMAIN;       \
+		(args).B.domapply = 1U;              \
+		break;                            \
+	case BIAS_APPLY_AVD:                      \
+		(args).B.avdapply = 1U;              \
+		break;                            \
+	default:                              \
+		break;                            \
+	}                                                 \
+	(args).B.dommode = (uint32_t)((bias)->dommode);         \
+	(args).B.avdmode = (uint32_t)((bias)->avdmode);         \
+	uint32_t sat = UPWR_BIAS2MILIV((1UL << UPWR_DOMBIAS_RBB_BITS) - 1UL);\
+	(args).B.domrbbn = ((bias)->dombias.rbbn > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->dombias.rbbn); \
+	(args).B.domrbbp = ((bias)->dombias.rbbp > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->dombias.rbbp); \
+	(args).B.avdrbbn = ((bias)->avdbias.rbbn > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->avdbias.rbbn); \
+	(args).B.avdrbbp = ((bias)->avdbias.rbbp > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->avdbias.rbbp); \
+} while (false)
+
+#define UPWR_FILL_MEMBIAS_ARGS(bias, args)		\
+do {							\
+	(args).B.en = (bias)->en;			\
+} while (false)
+
+
+#define UPWR_APD_CORES      (2U)
+#define UPWR_RTD_CORES      (1U)
+
+#define RTD_DOMAIN (0U)
+#define APD_DOMAIN (1U)
+#define UPWR_MAIN_DOMAINS (2U)
+#define AVD_DOMAIN (2U)
+#define UPWR_DOMAIN_COUNT (3U)
+#define PSD_DOMAIN (3U)
+#define UPWR_ALL_DOMAINS (4U)
+
+typedef uint32_t soc_domain_t;
+
+/*=========================================================================
+ * UNIT CONVERSION MACROS
+ *   These macros convert physical units to the values passed as arguments
+ *   in API functions.
+ *=========================================================================
+ */
+
+#define UPWR_VOLT_MILIV(v) (v)        /* voltage in mV    to argument value */
+#define UPWR_VOLT_MICROV(v)((v) / 1000U) /* voltage in uV    to argument value */
+#define UPWR_BIAS_MILIV(v) (((v) + 49UL) / 50UL)   /* bias voltage(mV) to argument value */
+#define UPWR_BIAS2MILIV(v) ((v) * 50UL)   /* inverse of UPWR_BIAS_MILIV         */
+#define UPWR_FREQ_KHZ(f)   (f)        /* frequency (kHz)  to argument value */
+
+#define UPWR_DOMBIAS_MAX_MV      (UPWR_BIAS2MILIV((1U << UPWR_DOMBIAS_RBB_BITS) - 1U))
+
+/**---------------------------------------------------------------
+ * EXCEPTION SERVICE GROUP
+ */
+
+/**+
+ * upwr_xcp_config()
+ *
+ * The i.MX8ULP uPower configuration struct contains the following bitfields:
+ *
+ *  - ALARM_INT (1 bit): tells which RTD MU interrupt should be used for alarms;
+ *    1= MU GPI1; 0= MU GPI0; APD alarms always use GPI0.
+ *  - CFG_IOMUX (1 bit): determintes if uPower configures i.MX8ULP IOMUX for
+ *    I2C and mode pins used to control an external PMIC;
+ *    1= uPower firmware or PMIC driver configures i.MX8ULP IOMUX and mode pins;
+ *    0= i.MX8ULP IOMUX and mode pins not configured by uPower;
+ *  - DGNBUFBITS (4 bits): determines the diagnostic buffer size according to
+ *    the formula: size = 2^(DGNBUFBITS+3) bytes;
+ *
+ *  Defaults are all zeroes; all other bits are reserved, and must be written 0.
+ */
+
+typedef union {
+	uint32_t R;
+	struct {
+		uint32_t ALARM_INT : 1U;
+		uint32_t CFG_IOMUX : 1U;
+		uint32_t DGNBUFBITS : 4U;
+		uint32_t RSV : 26U;
+	} B;
+} upwr_xcp_config_t;
+
+/**+
+ * upwr_xcp_sw_alarm()
+ *
+ * Argument code is defined by the enum upwr_alarm_t, with the values:
+ *  - UPWR_ALARM_INTERNAL: internal software error
+ *  - UPWR_ALARM_EXCEPTION: uPower core exception, either illegal instruction or
+ *    bus error
+ *  - UPWR_ALARM_SLACK: delay path too slow, meaning a timing violation occurred
+ *    or is iminent.
+ *  - UPWR_ALARM_VOLTAGE: one of the measured voltages is below safety margins.
+ *
+ * Note that this service emulates an alarm that would normally be issued by
+ * uPower when it detects one of the causes above. A request to alarm the APD
+ * domain when it is powered off returns success, but is ineffective.
+ *
+ */
+
+#define	UPWR_ALARM_INTERNAL   (0U) /* internal error */
+#define	UPWR_ALARM_EXCEPTION  (1U) /* core exception */
+#define	UPWR_ALARM_SLACK      (2U) /* delay path too slow */
+#define	UPWR_ALARM_VOLTAGE    (3U) /* voltage drop */
+#define	UPWR_ALARM_LAST       UPWR_ALARM_VOLTAGE
+
+typedef uint32_t upwr_alarm_t;
+
+/**---------------------------------------------------------------
+ * POWER MANAGEMENT SERVICE GROUP
+ */
+
+/* values in mV: */
+#define UPWR_RTD_RBBN_MAX     (1300U) /* max. RTD Reverse Back Bias N-Well */
+#define UPWR_RTD_RBBN_MIN      (100U) /* min. RTD Reverse Back Bias N-Well */
+
+#define UPWR_RTD_RBBP_MAX     (1300U) /* max. RTD Reverse Back Bias P-Well */
+#define UPWR_RTD_RBBP_MIN      (100U) /* min. RTD Reverse Back Bias P-Well */
+
+/* APD bias can only two values (mV): */
+#define UPWR_APD_RBBN_LO      (1000U) /* low  APD Reverse Back Bias N-Well */
+#define UPWR_APD_RBBN_HI      (1300U) /* high APD Reverse Back Bias N-Well */
+
+#define UPWR_APD_RBBP_LO      (1000U) /* low  APD Reverse Back Bias P-Well */
+#define UPWR_APD_RBBP_HI      (1300U) /* high APD Reverse Back Bias P-Well */
+
+/* AVD bias can only two values (mV): */
+#define UPWR_AVD_RBBN_LO      (1000U) /* low  AVD Reverse Back Bias N-Well */
+#define UPWR_AVD_RBBN_HI      (1300U) /* high AVD Reverse Back Bias N-Well */
+
+#define UPWR_AVD_RBBP_LO      (1000U) /* low  AVD Reverse Back Bias P-Well */
+#define UPWR_AVD_RBBP_HI      (1300U) /* high AVD Reverse Back Bias P-Well */
+
+/**+
+ * upwr_pwm_param()
+ *
+ * Argument param is defined by the struct/union upwr_pwm_param_t with the
+ * following i.MX8ULP-specific bitfields:
+ * - DPD_ALLOW (1 bit): 1= allows uPower power mode to go Deep Power Down (DPD);
+ *   uPower DPD also depends on other conditions, but if this bit is 0 uPower
+ *   won't go DPD even if those conditions are met; it can go either Sleep or
+ *   Deep Sleep (DSL) depending on the other configurations.
+ * - DSL_DIS (1 bit): if this bit is 1, uPower power mode won't go Deep Sleep
+ *   (DSL) even if the other conditions for that are met;
+ *   it may go Sleep instead.
+ * - SLP_ALLOW (1 bit): if this bit is 1, uPower power mode will go Sleep if
+ *   the conditions for Partial Active are met; it may also go Deep Sleep if bit
+ *   DSL_DIS=1.
+ * - DSL_BGAP_OFF (1 bit): 1= turns bandgap off when uPower goes Deep Sleep;
+ *   0= leaves bandgap on when uPower goes Deep Sleep (DSL).
+ * - DPD_BGAP_ON (1 bit): 1= leaves bandgap on when uPower goes Deep Power Down
+ *   (DPD); 0= powers off bandgap when uPower goes Deep Power Down (DPD).
+ *
+ *  Defaults are all zeroes; all other bits are reserved, and must be written 0.
+ */
+
+typedef union {
+	uint32_t R;
+	struct {
+		uint32_t DPD_ALLOW : 1U;
+		uint32_t DSL_DIS : 1U;
+		uint32_t SLP_ALLOW : 1U;
+		uint32_t DSL_BGAP_OFF : 1U;
+		uint32_t DPD_BGAP_ON : 1U;
+		uint32_t RSV : 27U;
+	} B;
+} upwr_pwm_param_t;
+
+/**+
+ * upwr_pwm_chng_reg_voltage()
+ *
+ * Argument reg is defined by the enum upwr_pmc_reg_t, with regulator ids:
+ *  - RTD_PMC_REG: RTD regulator
+ *  - APD_PMC_REG: APD regulator
+ *  - RTD_BIAS_PMC_REG: RTD bias regulator
+ *  - APD_BIAS_PMC_REG: APD bias regulator
+ *  - RTD_LVD_PMC_MON: RTD LVD regulator
+ *  - APD_LVD_PMC_MON: APD LVD regulator
+ *  - AVD_LVD_PMC_MON: AVD LVD regulator
+ *
+ * Argument volt is defined by the formula:
+ *
+ * argument = 92.30797633*V - 55.000138, rounded to the nearest integer,
+ * where V is the value in Volts, with a minimum of 0.595833 V (argument = 0).
+ *
+ */
+
+/* Regulator ids */
+typedef enum {
+	RTD_PMC_REG,
+	APD_PMC_REG,
+	RTD_BIAS_PMC_REG,
+	APD_BIAS_PMC_REG,
+	RTD_LVD_PMC_MON,
+	APD_LVD_PMC_MON,
+	AVD_LVD_PMC_MON
+} upwr_pmc_reg_t;
+
+/**+
+ * upwr_pwm_freq_setup()
+ *
+ * Argument domain is either RTD_DOMAIN or APD_DOMAIN.
+ * Arguments nextfq and currfq are to be defined (TBD).
+ */
+
+/**+
+ * upwr_pwm_dom_power_on()
+ *
+ * The arguments must comply with the restrictions below, otherwise the service
+ * is not executed and returns error UPWR_RESP_BAD_REQ:
+ * - argument domain can only be APD_DOMAIN, because in i.MX8ULP it is not
+ *   possible APD powered on (calling the service) with RTD completely
+ *   powered off.
+ * - the call can only be made from the RTD domain, for the same reason.
+ * - argument boot can only be 1, because in i.MX8ULP it is not possible to
+ *   power on the APD domain without starting the core boot.
+ *
+ * If APD is already powered on and booting/booted when the service is called,
+ * it returns success without doing anything.
+ */
+
+/**+
+ * upwr_pwm_boot_start()
+ *
+ * The arguments must comply with the restrictions below, otherwise the service
+ * is not executed and returns error UPWR_RESP_BAD_REQ:
+ * - argument domain can only be APD_DOMAIN, because in i.MX8ULP it is not
+ *   possible APD powered on (calling the service) with RTD completely
+ *   powered off.
+ * - the call can only be made from the RTD domain, for the same reason.
+ *
+ * If APD is already booted when the service is called, it returns success
+ * without doing anything. Otherwise, it returns the error UPWR_RESP_BAD_STATE,
+ * because in i.MX8ULP APD cannot be booted separately from power on.
+ */
+
+/**+
+ * upwr_pwm_power_on(),
+ * upwr_pwm_power_off(),
+ * upwr_pwm_mem_retain()
+ *
+ * These three service functions use the same arguments:
+ *
+ * argument swt is an array of one 32-bit word: uint32_t swt[1];
+ * naturally the pointer to a single uint32_t variable may be passed.
+ * Each bit of the word corresponds to a switch, according to the i.MX8ULP
+ * Reference Manual Rev B draft 2 table 64 Power switch reset state,
+ * and the following formula:
+ *
+ * if switch number < 10 bit number = switch number;
+ * if switch number >  9 bit number = switch number + 3;
+ *
+ * bits 9, 10, 11 and 12 must have the same value (corresponding to switch 9)
+ *
+ * Note: this argument is not used in upwr_pwm_mem_retain.
+ *
+ * argument mem is an array of two 32-bit words: uint32_t mem[2];
+ * naturally the pointer to a single uint64_t variable may be passed, since
+ * both ARM and RISC-V are little endian architectures.
+ * Each bit of the words corresponds to a memory, according to the i.MX8ULP
+ * Reference Manual table "Memory Partitions".
+ *
+ * Turning a memory completely on (array and peripheral) will automatically
+ * turn on its power switch, even if not explicitly commanded.
+ * Turning a memory's power switch off will automatically turn off its array
+ * and peripheral beforehand, even if not explicitly commanded.
+ *
+ * Argument restrictions:
+ *
+ * The swt and mem arguments must comply with the restrictions below, otherwise
+ * the service is not executed (no switch/memory is changed) and returns error
+ * UPWR_RESP_BAD_REQ:
+ *  1. one must not put a memory in retention coming from an off state.
+ *  2. switches 9, 10, 11 and 12 must be turned on/off simultaneously.
+ *  3. an AVD switch can only be turned off if all AVD switches belong to the
+ *     domain requesting the service (as defined by registers SYSCTRL0,
+ *     LPAV_MASTER_ALLOC_CTRL and LPAV_SLAVE_ALLOC_CTRL);
+ *     there is no such restriction to turn the switch on.
+ *  4. an AVD memory can only be turned off or put in retention if all
+ *     AVD memories belong to the domain requesting the service
+ *     (as defined by registers SYSCTRL0, LPAV_MASTER_ALLOC_CTRL and
+ *      LPAV_SLAVE_ALLOC_CTRL); there is no such restriction to turn on the
+ *     memories.
+ *  5. EdgeLock RAMs must not be turned off, unless RTD domain is in
+ *     Deep Power Down (DPD).
+ *  6. Power Switch 19 must be on to turn on switches 17 (MIPI/DSI),
+ *     18 (MIPI/CSI), and all AVD power switches.
+ *
+ * Service Errors:
+ *
+ * Besides the error UPWR_RESP_BAD_REQ caused by violations of the restrictions
+ * above, the services may fail with error UPWR_RESP_RESOURCE if a power mode
+ * transition or a similar service is executing at the same time.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ */
+
+/**+
+ * upwr_pwm_chng_switch_mem()
+ *
+ * The bit numbers in the argument struct mask and on/off state fields
+ * are the same as for services upwr_pwm_power_on, upwr_pwm_power_off and
+ * upwr_pwm_mem_retain.
+ *
+ * Turning a memory completely on (array and peripheral) will automatically
+ * turn on its power switch, even if not explicitly commanded.
+ *
+ * Argument restrictions:
+ *
+ * Same argument restrictions as services upwr_pwm_power_on, upwr_pwm_power_off
+ * and upwr_pwm_mem_retain, plus the following:
+ *
+ *  1. one must not turn a memory peripheral on and a memory array off.
+ *  2. one must not put a memory in retention and switch its power switch off.
+ *
+ * Service Errors:
+ *
+ * Besides the error UPWR_RESP_BAD_REQ caused by violations of the restrictions
+ * above, the service may fail with error UPWR_RESP_RESOURCE if a power mode
+ * transition or a similar service is executing at the same time.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ */
+
+/**+
+ * upwr_pwm_pmode_config()
+ *
+ * The same power switch and memory restrictions of service
+ * upwr_pwm_chng_switch_mem apply between power modes, however they are not
+ * enforced by this service, that is, it does not return service error.
+ *
+ * The default power mode configurations for RTD and APD are documented in the
+ * i.MX8ULP Reference Manual sections "Power mode details (real-time domain)"
+ * and "Power mode details (application domain)", respectively.
+ * If those configurations are satisfactory, this service does not have
+ * to be called.
+ *
+ * Power Mode Configuration Structure:
+ *
+ * Follows a description of the power mode configuration structure elements.
+ * - dom_swts: the same switch configuration structures used in service
+ *             upwr_pwm_chng_switch_mem argument swt.
+ * - mem_swts: the same memory configuration structures used in service
+ *             upwr_pwm_chng_switch_mem argument mem.
+ * - regs: an array of structs base_reg_cfg_t (see upower_soc_defs.h),
+ *         one element for each regulator; base_reg_cfg_t has fields
+ *         mode (regulator-dependent), lvl (voltage level in uV),
+ *         comp (regulator-dependent complamentary info).
+ * - pads: pad configuration in low power; see pad_cfg_t definition below.
+ * - mons: domain monitors (LVD and HVD) configuration;
+ *         see mon_cfg_t definition below.
+ * - avd_mons: same as mons for the AVD domain; see mon_cfg_t definition below.
+ * - dom_bbias: back-bias configuration for the domain;
+ *              see base_bbias_cfg_t definition below.
+ * - avd_bbias: back-bias configuration for the AVD domain;
+ *              see base_bbias_cfg_t definition below.
+ * - mem_bbias: back-bias configuration for the memory;
+ *              see base_bbias_cfg_t definition below.
+ * - mem_fbias: forward-bias configuration for the memory;
+ *              see base_fbias_cfg_t definition below.
+ * - pmic: PMIC-specific configuration
+ *
+ * Structure pad_cfg_t:
+ *
+ * Pad control for low power modes (power off, etc), 1 bit per pad segment.
+ * - rst  : put pad segment in reset.
+ * - iso  : put pad segment in isolation.
+ * - compl: specific pad segment information.
+ * - msk  : select which pads will be updated.
+ *
+ * Structure mon_cfg_t:
+ *
+ * Configures a voltage monitor and its actions.
+ * There are monitors for RTD, APD and AVD, monitoring LVD and HVD.
+ * - lvl  : Voltage level (in uV).
+ * - mode : Mode of monitor (ON, OFF, LP, etc).
+ * - compl: Extra info for the monitor.
+ *
+ * Structure base_bbias_cfg_t:
+ *
+ * Configures back-bias (for domain or memory).
+ * - mode : Back bias mode (OFF, RBB, ARBB, etc).
+ * - p_lvl: Voltage level of p-well (in mV).
+ * - n_lvl: Voltage level of n-well (in mV).
+ * - compl: Complementary bias-specific (enable reset, interrupt, clamp, etc).
+ *
+ * Structure base_fbias_cfg_t:
+ *
+ * Configure memory forward bias for a memory segment.
+ *
+ * - mode : Forward bias mode (OFF, ON).
+ * - msk  : Selects which memory will be updated
+ *
+ */
+
+/*=========================================================================
+ * Domain bias
+ *=========================================================================
+ */
+
+/**+
+ * upwr_pwm_chng_dom_bias()
+ *
+ * Argument bias is a pointer to a struct with fields:
+ *  - apply: tells to which domains the bias must be applied;
+ *    options are RTD only (BIAS_APPLY_RTD), RTD and AVD (BIAS_APPLY_RTD_AVD),
+ *    APD only (BIAS_APPLY_APD), APD and AVD (BIAS_APPLY_APD_AVD),
+ *    AVD only (BIAS_APPLY_AVD)
+ *  - dommode: bias mode of the main domain (RTD or APD, determined by apply);
+ *    options are disabled (NBB_BIAS_MODE), reverse back bias (RBB_BIAS_MODE),
+ *    asymmetrical forward bias (AFBB_BIAS_MODE), asymmetrical reverse bias
+ *    (ARBB_BIAS_MODE).
+ *  - avdmode: bias mode of Audio-Video Domain (AVD);
+ *    options are the same as dommode.
+ *  - dombias: bias voltage level(s) for the main domain (RTD or APD,
+ *    determined by apply); it is a structure with 2 fields, rbbn and rbbp,
+ *    for the N-well and P-well voltages, respectively; values are in mV.
+ *  - avdbias: bias voltage level(s) for the Audio-Video Domain (AVD);
+ *    same fields as dombias;
+ *
+ * Argument restrictions:
+ *
+ * Voltage levels must comply with the #define-determined limits/options:
+ * between UPWR_RTD_RBBN_MIN and UPWR_RTD_RBBN_MAX (inclusive) for RTD N-well;
+ * between UPWR_RTD_RBBP_MIN and UPWR_RTD_RBBP_MAX (inclusive) for RTD P-well;
+ * either UPWR_APD_RBBN_LO or UPWR_APD_RBBN_HI for APD N-well;
+ * either UPWR_APD_RBBP_LO or UPWR_APD_RBBP_HI for APD P-well;
+ * either UPWR_AVD_RBBN_LO or UPWR_AVD_RBBN_HI for AVD N-well;
+ * either UPWR_AVD_RBBP_LO or UPWR_AVD_RBBP_HI for AVD P-well;
+ *
+ * But note that the limits/options above do not apply to all bias modes:
+ * rbbn is used and checked only in mode RBB_BIAS_MODE;
+ * rbbp is used and checked only in modes RBB_BIAS_MODE and ARBB_BIAS_MODE;
+ * modes AFBB_BIAS_MODE and NBB_BIAS_MODE use or check neither rbbn nor rbbp;
+ *
+ * Service error UPWR_RESP_BAD_REQ is returned if the voltage limits/options
+ * above are violated.
+ */
+
+/* argument struct for service upwr_pwm_chng_dom_bias:
+ */
+
+typedef enum {               /* bias modes (both domain and memory): */
+	NBB_BIAS_MODE  = 0,  /* bias disabled */
+	RBB_BIAS_MODE  = 1,  /* reverse back bias enabled */
+	AFBB_BIAS_MODE = 2,  /* asymmetrical forward bias */
+	ARBB_BIAS_MODE = 3   /* asymmetrical reverse bias */
+} upwr_bias_mode_t;
+
+/* Domain Bias config (one per domain) */
+
+typedef enum {
+	BIAS_APPLY_RTD,      /* apply to RTD only    */
+	BIAS_APPLY_RTD_AVD,  /* apply to RTD and AVD */
+	BIAS_APPLY_APD,      /* apply to APD only    */
+	BIAS_APPLY_APD_AVD,  /* apply to APD and AVD */
+	BIAS_APPLY_AVD,      /* apply to AVD only    */
+	BIAS_APPLY_COUNT     /* number of apply options */
+} upwr_bias_apply_t;
+
+typedef struct {
+	uint16_t rbbn;    /* reverse back bias N well (mV) */
+	uint16_t rbbp;    /* reverse back bias P well (mV) */
+} upwr_rbb_t;
+
+struct upwr_dom_bias_cfg_t {
+	upwr_bias_apply_t apply;   /* bias application option  */
+	upwr_bias_mode_t  dommode; /* RTD/APD bias mode config */
+	upwr_bias_mode_t  avdmode; /* AVD     bias mode config */
+	upwr_rbb_t        dombias; /* RTD/APD reverse back bias */
+	upwr_rbb_t        avdbias; /* AVD     reverse back bias */
+};
+
+/* bias struct used in power mode config definitions */
+
+/**
+ * When write power mode transition program, please read below comments carefully.
+ * The structure and logic is complex, There is a lot of extension and reuse.
+ *
+ * First, for mode, extend "uint32_t mode" to a union struct, add support for AVD:
+ * typedef union {
+ *    uint32_t R;
+ *    struct {
+ *        uint32_t mode : 8;
+ *        uint32_t rsrv_1 : 8;
+ *        uint32_t avd_mode : 8;
+ *        uint32_t rsrv_2 : 8;
+ *    } B;
+ * } dom_bias_mode_cfg_t;
+
+  Second, if mode is AFBB mode, no need to configure rbbn and rbbp, uPower firmware
+  will configure all SRAM_AFBB_0 or SRAM_AFBB_1 for corresponding domain.
+
+  Third, if mode is RBB mode, extend "uint32_t rbbn" and "uint32_t rbbp" to a union
+  struct, add support for AVD:
+  typedef union {
+  uint32_t                  R;
+  struct {
+    uint32_t                  lvl       : 8;
+    uint32_t                  rsrv_1    : 8;
+    uint32_t                  avd_lvl   : 8;
+    uint32_t                  rsrv_2    : 8;
+  }                         B;
+} dom_bias_lvl_cfg_t;
+
+ *
+ */
+typedef struct {
+	uint32_t mode; /* Domain bias mode config, extend to dom_bias_mode_cfg_t to support RTD, APD, AVD */
+	uint32_t rbbn; /* reverse back bias N well */
+	uint32_t rbbp; /* reverse back bias P well */
+} UPWR_DOM_BIAS_CFG_T;
+
+/*=========================================================================
+ * Memory bias
+ *=========================================================================
+ */
+/**+
+ * upwr_pwm_chng_mem_bias()
+ *
+ * Argument struct contains only the field en, which can be either 1 (bias
+ * enabled) or 0 (bias disabled).
+ *
+ * Argument domain must be either RTD_DOMAIN (Real Time Domain) or APD_DOMAIN
+ * (Application Domain).
+ */
+
+/* Memory Bias config */
+struct upwr_mem_bias_cfg_t {
+	uint32_t en; /* Memory bias enable config */
+};
+
+/* bias struct used in power mode config definitions */
+typedef struct {
+	uint32_t en; /* Memory bias enable config */
+} UPWR_MEM_BIAS_CFG_T;
+
+/* Split different Bias */
+struct upwr_pmc_bias_cfg_t {
+	UPWR_DOM_BIAS_CFG_T dombias_cfg; /* Domain Bias config */
+	UPWR_MEM_BIAS_CFG_T membias_cfg; /* Memory Bias config */
+};
+
+/*=========================================================================
+ * Power modes
+ *=========================================================================
+ */
+
+/* from msb->lsb: Azure bit, dual boot bit, low power boot bit */
+typedef enum {
+	SOC_BOOT_SINGLE   = 0,
+	SOC_BOOT_LOW_PWR  = 1,
+	SOC_BOOT_DUAL     = 2,
+	SOC_BOOT_AZURE    = 4
+} SOC_BOOT_TYPE_T;
+
+#ifdef UPWR_COMP_RAM
+/* Power modes for RTD domain  */
+typedef enum {
+	DPD_RTD_PWR_MODE, /* Real Time Deep Power Down mode */
+	PD_RTD_PWR_MODE,  /* Real Time Power Down mode */
+	DSL_RTD_PWR_MODE, /* Real Time Domain Deep Sleep Mode */
+	HLD_RTD_PWR_MODE, /* Real Time Domain Hold Mode */
+	SLP_RTD_PWR_MODE, /* Sleep Mode */
+	ADMA_RTD_PWR_MODE,/* Active DMA Mode */
+	ACT_RTD_PWR_MODE, /* Active Domain Mode */
+	NUM_RTD_PWR_MODES
+} upwr_ps_rtd_pwr_mode_t;
+
+/* Abstract power modes */
+typedef enum {
+	DPD_PWR_MODE,
+	PD_PWR_MODE,
+	PACT_PWR_MODE,
+	DSL_PWR_MODE,
+	HLD_PWR_MODE,
+	SLP_PWR_MODE,
+	ADMA_PWR_MODE,
+	ACT_PWR_MODE,
+	NUM_PWR_MODES,
+	NUM_APD_PWR_MODES = NUM_PWR_MODES,
+	TRANS_PWR_MODE    = NUM_PWR_MODES,
+	INVALID_PWR_MODE  = TRANS_PWR_MODE + 1
+} abs_pwr_mode_t;
+#else /* UPWR_COMP_RAM */
+/* Power modes for RTD domain  */
+#define	DPD_RTD_PWR_MODE   (0U)  /* Real Time Deep Power Down mode */
+#define	PD_RTD_PWR_MODE    (1U)  /* Real Time Power Down mode */
+#define	DSL_RTD_PWR_MODE   (2U)  /* Real Time Domain Deep Sleep Mode */
+#define	HLD_RTD_PWR_MODE   (3U)  /* Real Time Domain Hold Mode */
+#define	SLP_RTD_PWR_MODE   (4U)  /* Sleep Mode */
+#define	ADMA_RTD_PWR_MODE  (5U)  /* Active DMA Mode */
+#define	ACT_RTD_PWR_MODE   (6U)  /* Active Domain Mode */
+#define	NUM_RTD_PWR_MODES  (7U)
+
+typedef uint32_t upwr_ps_rtd_pwr_mode_t;
+
+/* Abstract power modes */
+#define	DPD_PWR_MODE       (0U)
+#define	PD_PWR_MODE        (1U)
+#define	PACT_PWR_MODE      (2U)
+#define	DSL_PWR_MODE       (3U)
+#define	HLD_PWR_MODE       (4U)
+#define	SLP_PWR_MODE       (5U)
+#define	ADMA_PWR_MODE      (6U)
+#define	ACT_PWR_MODE       (7U)
+#define	NUM_PWR_MODES      (8U)
+#define	NUM_APD_PWR_MODES NUM_PWR_MODES
+#define	TRANS_PWR_MODE    NUM_PWR_MODES
+#define	INVALID_PWR_MODE  (TRANS_PWR_MODE + 1U)
+
+typedef uint32_t abs_pwr_mode_t;
+#endif /* UPWR_COMP_RAM */
+
+typedef struct {
+	abs_pwr_mode_t mode;
+	bool ok;
+} pch_trans_t;
+
+typedef pch_trans_t rtd_trans_t;
+
+typedef struct {
+	abs_pwr_mode_t mode;
+	pch_trans_t core[UPWR_APD_CORES];
+} apd_trans_t;
+
+/* Codes for APD pwr mode as programmed in LPMODE reg */
+typedef enum {
+	ACT_APD_LPM,
+	SLP_APD_LPM = 1,
+	DSL_APD_LPM = 3,
+	PACT_APD_LPM = 7,
+	PD_APD_LPM = 15,
+	DPD_APD_LPM = 31,
+	HLD_APD_LPM = 63
+} upwr_apd_lpm_t;
+
+/* PowerSys low power config */
+struct upwr_powersys_cfg_t {
+	uint32_t lpm_mode; /* Powersys low power mode */
+};
+
+/*=*************************************************************************
+ * RTD
+ *=*************************************************************************/
+/* Config pmc PADs */
+struct upwr_pmc_pad_cfg_t {
+	uint32_t pad_close;   /* PMC PAD close config */
+	uint32_t pad_reset;   /* PMC PAD reset config */
+	uint32_t pad_tqsleep; /* PMC PAD TQ Sleep config */
+};
+
+/* Config regulator (internal and external) */
+struct upwr_reg_cfg_t {
+	uint32_t volt;  /* Regulator voltage config */
+	uint32_t mode;  /* Regulator mode config */
+};
+
+/* Config pmc monitors */
+struct  upwr_pmc_mon_cfg_t {
+	uint32_t mon_hvd_en; /* PMC mon HVD */
+	uint32_t mon_lvd_en; /* PMC mon LVD */
+	uint32_t mon_lvdlvl; /* PMC mon LVDLVL */
+};
+
+/* Same monitor config for RTD (for compatibility) */
+#define upwr_pmc_mon_rtd_cfg_t upwr_pmc_mon_cfg_t
+
+typedef swt_config_t ps_rtd_swt_cfgs_t[NUM_RTD_PWR_MODES];
+typedef swt_config_t ps_apd_swt_cfgs_t[NUM_APD_PWR_MODES];
+
+/*=*************************************************************************
+ * APD
+ *=*************************************************************************/
+
+/* PowerSys PMIC config */
+struct upwr_pmic_cfg_t {
+	uint32_t volt;
+	uint32_t mode;
+	uint32_t mode_msk;
+};
+
+typedef uint32_t offs_t;
+
+struct ps_apd_pwr_mode_cfg_t {
+	#ifdef UPWR_SIMULATOR_ONLY
+	struct upwr_switch_board_t *swt_board_offs;
+	struct upwr_mem_switches_t *swt_mem_offs;
+	#else
+	offs_t swt_board_offs;
+	offs_t swt_mem_offs;
+	#endif
+	struct upwr_pmic_cfg_t pmic_cfg;
+	struct upwr_pmc_pad_cfg_t pad_cfg;
+	struct upwr_pmc_bias_cfg_t bias_cfg;
+};
+
+/* Get the pointer to swt config */
+static inline struct upwr_switch_board_t*
+get_apd_swt_cfg(volatile struct ps_apd_pwr_mode_cfg_t *cfg)
+{
+	char *ptr;
+
+	ptr = (char *)cfg;
+	ptr += (uint64_t)cfg->swt_board_offs;
+	return (struct upwr_switch_board_t *)ptr;
+}
+
+/* Get the pointer to mem config */
+static inline struct upwr_mem_switches_t*
+get_apd_mem_cfg(volatile struct ps_apd_pwr_mode_cfg_t *cfg)
+{
+	char *ptr;
+
+	ptr = (char *)cfg;
+	ptr += (uint64_t)cfg->swt_mem_offs;
+	return (struct upwr_mem_switches_t *)ptr;
+}
+
+/* Power Mode configuration */
+
+#define ps_rtd_pwr_mode_cfg_t upwr_power_mode_cfg_t
+
+/* these typedefs are just for RISC-V sizeof purpose */
+typedef uint32_t swt_board_ptr_t;
+typedef uint32_t swt_mem_ptr_t;
+
+struct upwr_power_mode_cfg_t {
+	#ifdef UPWR_SIMULATOR_ONLY
+	struct upwr_switch_board_t *swt_board; /* Swt board for mem. */
+	struct upwr_mem_switches_t *swt_mem;   /* Swt to mem. arrays, perif */
+	#else
+	#ifdef __LP64__
+	uint32_t swt_board;
+	uint32_t swt_mem;
+	#else
+	struct upwr_switch_board_t *swt_board; /* Swt board for mem. */
+	struct upwr_mem_switches_t *swt_mem;   /* Swt to mem. arrays, perif */
+	#endif
+	#endif
+	struct upwr_reg_cfg_t in_reg_cfg; /* internal regulator config*/
+	struct upwr_reg_cfg_t pmic_cfg;  /* external regulator - pmic*/
+	struct upwr_pmc_pad_cfg_t pad_cfg;  /* Pad conf for power trans*/
+	struct upwr_pmc_mon_rtd_cfg_t mon_cfg; /*monitor configuration */
+	struct upwr_pmc_bias_cfg_t bias_cfg; /* Memory/Domain Bias conf */
+	struct upwr_powersys_cfg_t pwrsys_lpm_cfg; /* pwrsys low power config*/
+};
+
+static inline unsigned int upwr_sizeof_pmode_cfg(uint32_t domain)
+{
+	switch (domain) {
+	case RTD_DOMAIN:
+		return sizeof(struct upwr_power_mode_cfg_t) +
+					(sizeof(struct upwr_switch_board_t)*
+					 UPWR_PMC_SWT_WORDS) +
+					(sizeof(struct upwr_mem_switches_t)*
+					 UPWR_PMC_MEM_WORDS) -
+					2U * (sizeof(void *) - sizeof(swt_board_ptr_t));
+
+		/* fall through */
+	case APD_DOMAIN:
+		return sizeof(struct ps_apd_pwr_mode_cfg_t) +
+					(sizeof(struct upwr_switch_board_t)*
+					 UPWR_PMC_SWT_WORDS) +
+					(sizeof(struct upwr_mem_switches_t)*
+					 UPWR_PMC_MEM_WORDS);
+
+		/* fall through */
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/*=*************************************************************************
+ * All configs
+ *=*************************************************************************/
+
+/* LVD/HVD monitor config for a single domain */
+
+/* Domain + AVD monitor config
+ * For RTD, mapped in mon_cfg.mon_hvd_en
+ * For APD, mapped temporarily in pad_cfg.pad_tqsleep
+ */
+typedef union upwr_mon_cfg_union_t {
+	volatile uint32_t R;
+	struct {
+		/* Original config, not change */
+		volatile uint32_t rsrv_1          : 8;
+		/* DOM */
+		volatile uint32_t dom_lvd_irq_ena : 1;
+		volatile uint32_t dom_lvd_rst_ena : 1;
+		volatile uint32_t dom_hvd_irq_ena : 1;
+		volatile uint32_t dom_hvd_rst_ena : 1;
+		volatile uint32_t dom_lvd_lvl     : 4;
+		volatile uint32_t dom_lvd_ena     : 1;
+		volatile uint32_t dom_hvd_ena     : 1;
+		/* AVD */
+		volatile uint32_t avd_lvd_irq_ena : 1;
+		volatile uint32_t avd_lvd_rst_ena : 1;
+		volatile uint32_t avd_hvd_irq_ena : 1;
+		volatile uint32_t avd_hvd_rst_ena : 1;
+		volatile uint32_t avd_lvd_lvl     : 4;
+		volatile uint32_t avd_lvd_ena     : 1;
+		volatile uint32_t avd_hvd_ena     : 1;
+	}                         B;
+} upwr_mon_cfg_t;
+
+/* Get the monitor config word from RAM (domaind and AVD) */
+static inline uint32_t get_mon_cfg(uint8_t dom, void *mode_cfg)
+{
+	if (dom == RTD_DOMAIN) {
+		return ((struct ps_rtd_pwr_mode_cfg_t *)mode_cfg)->mon_cfg.mon_hvd_en;
+	} else {
+		return ((struct ps_apd_pwr_mode_cfg_t *)mode_cfg)->pad_cfg.pad_tqsleep;
+	}
+}
+
+/* Set the monitor config word in RAM (domaind and AVD) */
+static inline void set_mon_cfg(uint8_t dom, void *mode_cfg,
+				upwr_mon_cfg_t mon_cfg)
+{
+	uint32_t *cfg;
+
+	if (dom == RTD_DOMAIN) {
+		cfg = (uint32_t *)&((struct ps_rtd_pwr_mode_cfg_t *)mode_cfg)->mon_cfg.mon_hvd_en;
+	} else {
+		cfg = (uint32_t *)&((struct ps_apd_pwr_mode_cfg_t *)mode_cfg)->pad_cfg.pad_tqsleep;
+	}
+
+	*cfg = mon_cfg.R;
+}
+
+#define PMIC_REG_VALID_TAG 0xAAU
+
+/**
+ * limit the max pmic register->value count to 8
+ * each data cost 4 Bytes, totally 32 Bytes
+ */
+#define MAX_PMIC_REG_COUNT 0x8U
+
+/**
+ * the configuration structure for PMIC register setting
+ *
+ * @ tag: The TAG number to judge if the data is valid or not, valid tag is PMIC_REG_VALID_TAG
+ * @ power_mode : corresponding to each domain's power mode
+ * RTD refer to upwr_ps_rtd_pwr_mode_t
+ * APD refer to abs_pwr_mode_t
+ * @ i2c_addr : i2c address
+ * @ i2c_data : i2c data value
+ */
+struct ps_pmic_reg_data_cfg_t {
+	uint32_t tag : 8;
+	uint32_t power_mode : 8;
+	uint32_t i2c_addr : 8;
+	uint32_t i2c_data : 8;
+};
+
+/* Uniformize access to PMIC cfg for RTD and APD */
+
+typedef union {
+	struct upwr_reg_cfg_t RTD;
+	struct upwr_pmic_cfg_t APD;
+} pmic_cfg_t;
+
+/* Access to PMIC mode mask and AVD mode */
+
+typedef union {
+	uint32_t R;
+	struct {
+		uint8_t mode;     /* Domain PMIC mode */
+		uint8_t msk;      /* Domain PMIC mode mask */
+		uint8_t avd_mode; /* AVD PMIC mode */
+		uint8_t avd_msk;  /* AVD PMIC mode mask */
+	} B;
+} pmic_mode_cfg_t;
+
+/* Access RTD, APD and AVD modes and masks */
+static inline pmic_mode_cfg_t *get_pmic_mode_cfg(uint8_t dom, pmic_cfg_t *cfg)
+{
+	uint32_t *mode_cfg;
+
+	if (dom == RTD_DOMAIN) {
+		mode_cfg = &cfg->RTD.mode;
+	} else {
+		mode_cfg = &cfg->APD.mode;
+	}
+
+	return (pmic_mode_cfg_t *)mode_cfg;
+}
+
+static inline uint8_t get_pmic_mode(uint8_t dom, pmic_cfg_t *cfg)
+{
+	return get_pmic_mode_cfg(dom, cfg)->B.mode;
+}
+
+static inline void set_pmic_mode(uint8_t dom, pmic_cfg_t *cfg, uint8_t mode)
+{
+	get_pmic_mode_cfg(dom, cfg)->B.mode = mode;
+}
+
+static inline uint32_t get_pmic_mode_msk(uint8_t dom, pmic_cfg_t *cfg)
+{
+	pmic_mode_cfg_t   *mode_cfg;
+
+	if (dom == RTD_DOMAIN) {
+		mode_cfg = (pmic_mode_cfg_t *)&cfg->RTD.mode;
+		return mode_cfg->B.msk;
+	} else {
+		return cfg->APD.mode_msk;
+	}
+}
+
+/* Getters and setters for AVD mode and mask */
+static inline uint8_t get_avd_pmic_mode(uint8_t dom, pmic_cfg_t *cfg)
+{
+	return get_pmic_mode_cfg(dom, cfg)->B.avd_mode;
+}
+
+static inline void set_avd_pmic_mode(uint8_t dom, pmic_cfg_t *cfg, uint8_t mode)
+{
+	get_pmic_mode_cfg(dom, cfg)->B.avd_mode = mode;
+}
+
+static inline uint8_t get_avd_pmic_mode_msk(uint8_t dom, pmic_cfg_t *cfg)
+{
+	return get_pmic_mode_cfg(dom, cfg)->B.avd_msk;
+}
+
+static inline void set_avd_pmic_mode_msk(uint8_t dom,
+					 pmic_cfg_t *cfg,
+					 uint8_t msk)
+{
+	get_pmic_mode_cfg(dom, cfg)->B.avd_msk = msk;
+}
+
+struct ps_delay_cfg_t {
+	uint32_t tag : 8U;
+	uint32_t rsv : 8U;
+	uint32_t exitdelay : 16U;   // exit delay in us
+};
+
+#define PS_DELAY_TAG 0xA5U
+
+/* max exit delay = 0xffff = 65535 us = 65.5 ms (it is enough...) */
+/* with 8 bits, 256 -> not enough */
+
+typedef struct ps_delay_cfg_t ps_rtd_delay_cfgs_t[NUM_RTD_PWR_MODES];
+typedef struct ps_delay_cfg_t ps_apd_delay_cfgs_t[NUM_APD_PWR_MODES];
+
+typedef struct ps_rtd_pwr_mode_cfg_t ps_rtd_pwr_mode_cfgs_t[NUM_RTD_PWR_MODES];
+typedef struct ps_apd_pwr_mode_cfg_t ps_apd_pwr_mode_cfgs_t[NUM_APD_PWR_MODES];
+typedef struct ps_pmic_reg_data_cfg_t ps_rtd_pmic_reg_data_cfgs_t[MAX_PMIC_REG_COUNT];
+typedef struct ps_pmic_reg_data_cfg_t ps_apd_pmic_reg_data_cfgs_t[MAX_PMIC_REG_COUNT];
+
+struct ps_pwr_mode_cfg_t {
+	ps_rtd_pwr_mode_cfgs_t  ps_rtd_pwr_mode_cfg;
+	ps_rtd_swt_cfgs_t       ps_rtd_swt_cfg;
+	ps_apd_pwr_mode_cfgs_t  ps_apd_pwr_mode_cfg;
+	ps_apd_swt_cfgs_t       ps_apd_swt_cfg;
+	ps_rtd_pmic_reg_data_cfgs_t ps_rtd_pmic_reg_data_cfg;
+	ps_apd_pmic_reg_data_cfgs_t ps_apd_pmic_reg_data_cfg;
+	ps_rtd_delay_cfgs_t    ps_rtd_delay_cfg;
+	ps_apd_delay_cfgs_t    ps_apd_delay_cfg;
+
+};
+
+#define UPWR_XCP_MIN_ADDR   (0x28350000U)
+#define UPWR_XCP_MAX_ADDR   (0x2836FFFCU)
+
+struct upwr_reg_access_t {
+	uint32_t addr;
+	uint32_t data;
+	uint32_t mask; /* mask=0 commands read */
+};
+
+typedef upwr_pointer_msg upwr_xcp_access_msg;
+
+/* unions for the shared memory buffer */
+
+typedef union {
+	struct upwr_reg_access_t reg_access;
+} upwr_xcp_union_t;
+
+typedef union {
+	struct {
+		struct ps_rtd_pwr_mode_cfg_t rtd_struct;
+		struct upwr_switch_board_t   rtd_switch;
+		struct upwr_mem_switches_t   rtd_memory;
+	} rtd_pwr_mode;
+	struct {
+		struct ps_apd_pwr_mode_cfg_t apd_struct;
+		struct upwr_switch_board_t   apd_switch;
+		struct upwr_mem_switches_t   apd_memory;
+	} apd_pwr_mode;
+} upwr_pwm_union_t;
+
+#define MAX_SG_EXCEPT_MEM_SIZE sizeof(upwr_xcp_union_t)
+#define MAX_SG_PWRMGMT_MEM_SIZE sizeof(upwr_pwm_union_t)
+
+/**
+ * VOLTM group need shared memory for PMIC IC configuration
+ * 256 Bytes is enough for PMIC register array
+ */
+#define MAX_SG_VOLTM_MEM_SIZE 256U
+
+#endif /* UPWR_SOC_DEFS_H */
diff --git a/plat/imx/imx8ulp/xrdc/xrdc_config.h b/plat/imx/imx8ulp/xrdc/xrdc_config.h
new file mode 100644
index 0000000..d2af55c
--- /dev/null
+++ b/plat/imx/imx8ulp/xrdc/xrdc_config.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <xrdc.h>
+
+#define SP(X)		((X) << 9)
+#define SU(X)		((X) << 6)
+#define NP(X)		((X) << 3)
+#define NU(X)		((X) << 0)
+
+#define RWX		7
+#define RW		6
+#define R		4
+#define X		1
+
+struct xrdc_mda_config imx8ulp_mda[] = {
+	{ 0, 7, MDA_SA_PT }, /* A core */
+	{ 1, 1, MDA_SA_NS }, /* DMA1 */
+	{ 2, 1, MDA_SA_NS }, /* USB */
+	{ 3, 1, MDA_SA_NS }, /* PXP-> .M10 */
+	{ 4, 1, MDA_SA_NS }, /* ENET */
+	{ 5, 1, MDA_SA_PT }, /* CAAM */
+	{ 6, 1, MDA_SA_NS }, /* USDHC0 */
+	{ 7, 1, MDA_SA_NS }, /* USDHC1 */
+	{ 8, 1, MDA_SA_NS }, /* USDHC2 */
+	{ 9, 2, MDA_SA_NS }, /* HIFI4 */
+	{ 10, 3, MDA_SA_NS }, /* GPU3D */
+	{ 11, 3, MDA_SA_NS }, /* GPU2D */
+	{ 12, 3, MDA_SA_NS }, /* EPDC */
+	{ 13, 3, MDA_SA_NS }, /* DCNano */
+	{ 14, 3, MDA_SA_NS }, /* ISI */
+	{ 15, 3, MDA_SA_NS }, /* PXP->NIC_LPAV.M0 */
+	{ 16, 3, MDA_SA_NS }, /* DMA2 */
+};
+
+#ifdef SPD_opteed
+#define TEE_SHM_SIZE 0x400000
+#else
+#define TEE_SHM_SIZE 0x0
+#endif
+
+#if defined(SPD_opteed) || defined(SPD_trusty)
+#define DRAM_MEM_0_START (0x80000000)
+#define DRAM_MEM_0_SIZE (BL32_BASE - 0x80000000)
+
+#define DRAM_MEM_1_START (BL32_BASE)
+#define DRAM_MEM_1_SIZE (BL32_SIZE - TEE_SHM_SIZE)
+
+#ifndef SPD_trusty
+#define DRAM_MEM_2_START (DRAM_MEM_1_START + DRAM_MEM_1_SIZE)
+#define DRAM_MEM_2_SIZE (0x80000000 - DRAM_MEM_1_SIZE - DRAM_MEM_0_SIZE)
+#else
+#define SECURE_HEAP_START   (0xA9600000)
+#define SECURE_HEAP_SIZE    (0x6000000)
+#define DRAM_MEM_END        (0x100000000)
+
+#define DRAM_MEM_2_START (DRAM_MEM_1_START + DRAM_MEM_1_SIZE)
+#define DRAM_MEM_2_SIZE  (SECURE_HEAP_START - DRAM_MEM_2_START)
+#define DRAM_MEM_3_START (DRAM_MEM_2_START + DRAM_MEM_2_SIZE)
+#define DRAM_MEM_3_SIZE  (SECURE_HEAP_SIZE)
+#define DRAM_MEM_4_START (DRAM_MEM_3_START + DRAM_MEM_3_SIZE)
+#define DRAM_MEM_4_SIZE  (DRAM_MEM_END - DRAM_MEM_4_START)
+#endif
+#endif
+
+struct xrdc_mrc_config imx8ulp_mrc[] = {
+	{ 0, 0, 0x0,        0x30000,    {0, 0, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* ROM1 */
+	{ 1, 0, 0x60000000, 0x10000000, {1, 1, 0, 0, 1, 0, 1, 1}, {0xfff, 0} }, /* Flexspi2 */
+	{ 2, 0, 0x22020000, 0x40000,    {1, 1, 0, 0, 1, 0, 1, 1}, {0xfff, 0} }, /* SRAM2 */
+	{ 3, 0, 0x22010000, 0x10000,    {1, 1, 0, 0, 1, 0, 1, 1}, {0xfff, 0} }, /* SRAM0 */
+#if defined(SPD_opteed) || defined(SPD_trusty)
+	{ 4, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+	{ 4, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfc0, 0} }, /* TEE DRAM for A35, DMA1, USDHC0*/
+	{ 4, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+#ifdef SPD_trusty
+	{ 4, 3, DRAM_MEM_3_START, DRAM_MEM_3_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfc0, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+	{ 4, 4, DRAM_MEM_4_START, DRAM_MEM_4_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+#endif
+
+	{ 5, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+	{ 5, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfc0, 0} }, /* TEE DRAM for NIC_PER */
+	{ 5, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+#ifdef SPD_trusty
+	{ 5, 3, DRAM_MEM_3_START, DRAM_MEM_3_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfc0, 0} }, /* DRAM for NIC_PER */
+	{ 5, 4, DRAM_MEM_4_START, DRAM_MEM_4_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+#endif
+
+#ifdef SPD_trusty
+	{ 6, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {1, 1, 0, 2, 1, 0, 1, 1}, {0xfff, 0x93f} }, /* DRAM for LPAV and RTD*/
+	{ 6, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfc0, 0} }, /* TEE DRAM for LPAV and RTD*/
+	{ 6, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {1, 1, 0, 2, 1, 0, 1, 1}, {0xfff, 0x93f} }, /* DRAM for LPAV and RTD*/
+	{ 6, 3, DRAM_MEM_3_START, DRAM_MEM_3_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfc0, 0} }, /* DRAM for LPAV and RTD*/
+	{ 6, 4, DRAM_MEM_4_START, DRAM_MEM_4_SIZE, {1, 1, 0, 2, 1, 0, 1, 1}, {0xfff, 0x93f} }, /* DRAM for LPAV and RTD*/
+#else
+	{ 6, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* DRAM for LPAV and RTD*/
+	{ 6, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfc0, 0} }, /* TEE DRAM for LPAV and RTD*/
+	{ 6, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* DRAM for LPAV and RTD*/
+#endif
+#else
+	{ 4, 0, 0x80000000, 0x80000000, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+	{ 5, 0, 0x80000000, 0x80000000, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+	{ 6, 0, 0x80000000, 0x80000000, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* DRAM for LPAV and RTD*/
+#endif
+	{ 7, 0, 0x80000000, 0x10000000, {0, 0, 1, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for HIFI4 */
+	{ 7, 1, 0x90000000, 0x10000000, {0, 0, 1, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for HIFI4 */
+	{ 8, 0, 0x21000000, 0x10000,    {1, 1, 1, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* SRAM1 */
+	{ 9, 0, 0x1ffc0000, 0xc0000,    {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0} }, /* SSRAM for HIFI4 */
+	{ 10, 0, 0x1ffc0000, 0xc0000,   {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0} }, /* SSRAM for LPAV */
+	{ 11, 0, 0x21170000, 0x10000,   {0, 0, 1, 0, 0, 0, 0, 2}, {0xfff, SP(RW) | SU(RW) | NP(RW)} }, /* HIFI4 TCM */
+	{ 11, 1, 0x21180000, 0x10000,   {0, 0, 1, 0, 0, 0, 0, 2}, {SP(RW) | SU(RW) | NP(RW) | NU(RW), SP(RW) | SU(RW) | NP(RW)} }, /* HIFI4 TCM */
+	{ 12, 0, 0x2d400000, 0x100000,  {0, 0, 0, 0, 0, 0, 0, 1}, {SP(RW) | SU(RW) | NP(RW) | NU(RW), 0} }, /* GIC500 */
+};
+
+struct xrdc_pac_msc_config imx8ulp_pdac[] = {
+	{ 0, PAC_SLOT_ALL, {0, 7, 0, 0, 0, 0, 0, 7} }, /* PAC0 */
+	{ 0, 44, {0, 7, 7, 0, 0, 0, 0, 7} }, /* PAC0 slot 44 for CGC1 */
+	{ 0, 36, {0, 0, 0, 0, 0, 0, 7, 7} }, /* PAC0 slot 36 for CMC1 */
+	{ 0, 41, {0, 0, 0, 0, 0, 0, 7, 7} }, /* PAC0 slot 41 for SIM_AD */
+	{ 1, PAC_SLOT_ALL, {0, 7, 0, 0, 0, 0, 0, 7} }, /* PAC1 */
+	{ 1, 0, {0, 7, 7, 0, 0, 0, 7, 7} }, /* PAC1 slot 0 for PCC4 */
+	{ 1, 6, {0, 7, 7, 0, 0, 0, 0, 7} }, /* PAC1 slot 6 for LPUART6 */
+	{ 1, 7, {0, 7, 7, 0, 0, 0, 0, 7} }, /* PAC1 slot 7 for LPUART7 */
+	{ 1, 9,  {0, 7, 7, 7, 0, 0, 0, 7} }, /* SAI5 for HIFI4 and eDMA2 */
+	{ 1, 12, {0, 7, 7, 0, 0, 0, 7, 7} }, /* PAC1 slot 12 for IOMUXC1 */
+	{ 2, PAC_SLOT_ALL, {7, 7, 7, 7, 0, 0, 7, 7} }, /* PAC2 */
+};
+
+struct xrdc_pac_msc_config imx8ulp_msc[] = {
+	{ 0, 0, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC0 GPIOE */
+	{ 0, 1, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC0 GPIOF */
+	{ 1, MSC_SLOT_ALL, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC1 GPIOD */
+	{ 2, MSC_SLOT_ALL, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC2 GPU3D/2D/DCNANO/DDR registers */
+};
diff --git a/plat/imx/imx8ulp/xrdc/xrdc_core.c b/plat/imx/imx8ulp/xrdc/xrdc_core.c
new file mode 100644
index 0000000..d022e4c
--- /dev/null
+++ b/plat/imx/imx8ulp/xrdc/xrdc_core.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "xrdc_config.h"
+
+#define XRDC_ADDR	0x292f0000
+#define MRC_OFFSET	0x2000
+#define MRC_STEP	0x200
+
+#define XRDC_MGR_PAC_ID	  U(0)
+#define XRDC_MGR_PAC_SLOT U(47)
+
+enum xrdc_comp_type {
+	MDA_TYPE = (1 << 16),
+	MRC_TYPE = (2 << 16),
+	PAC_TYPE = (3 << 16),
+	MSC_TYPE = (4 << 16),
+};
+
+enum xrdc_pd_type {
+	XRDC_AD_PD,
+	XRDC_HIFI_PD,
+	XRDC_AV_PD,
+};
+
+#define XRDC_TYPE_MASK (0x7 << 16)
+#define XRDC_ID_MASK 0xFFFF
+#define XRDC_ID(id) ((id) & XRDC_ID_MASK)
+
+typedef bool (*xrdc_check_func)(enum xrdc_comp_type type, uint16_t id);
+
+/* Access below XRDC needs enable PS 8
+ * and HIFI clocks and release HIFI firstly
+ */
+uint32_t hifi_xrdc_list[] = {
+	(MDA_TYPE | XRDC_ID(9)),
+	(MRC_TYPE | XRDC_ID(7)),
+	(MRC_TYPE | XRDC_ID(9)),
+	(MRC_TYPE | XRDC_ID(11)),
+};
+
+/* Access below XRDC needs enable PS 16 firstly */
+uint32_t av_periph_xrdc_list[] = {
+	(MDA_TYPE | XRDC_ID(10)),
+	(MDA_TYPE | XRDC_ID(11)),
+	(MDA_TYPE | XRDC_ID(12)),
+	(MDA_TYPE | XRDC_ID(13)),
+	(MDA_TYPE | XRDC_ID(14)),
+	(MDA_TYPE | XRDC_ID(15)),
+	(MDA_TYPE | XRDC_ID(16)),
+
+	(PAC_TYPE | XRDC_ID(2)),
+
+	(MRC_TYPE | XRDC_ID(6)),
+	(MRC_TYPE | XRDC_ID(8)),
+	(MRC_TYPE | XRDC_ID(10)),
+
+	(MSC_TYPE | XRDC_ID(1)),
+	(MSC_TYPE | XRDC_ID(2)),
+};
+
+uint32_t imx8ulp_pac_slots[] = {
+	61, 23, 53
+};
+
+uint32_t imx8ulp_msc_slots[] = {
+	2, 1, 7
+};
+
+static int xrdc_config_mrc_w0_w1(uint32_t mrc_con, uint32_t region, uint32_t w0, uint32_t size)
+{
+
+	uint32_t w0_addr, w1_addr;
+
+	w0_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20;
+	w1_addr = w0_addr + 4;
+
+	if ((size % 32) != 0) {
+		return -EINVAL;
+	}
+
+	mmio_write_32(w0_addr, w0 & ~0x1f);
+	mmio_write_32(w1_addr, w0 + size - 1);
+
+	return 0;
+}
+
+static int xrdc_config_mrc_w2(uint32_t mrc_con, uint32_t region, uint32_t dxsel_all)
+{
+	uint32_t w2_addr;
+
+	w2_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20 + 0x8;
+
+	mmio_write_32(w2_addr, dxsel_all);
+
+	return 0;
+}
+
+static int xrdc_config_mrc_w3_w4(uint32_t mrc_con, uint32_t region, uint32_t w3, uint32_t w4)
+{
+	uint32_t w3_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20 + 0xC;
+	uint32_t w4_addr = w3_addr + 4;
+
+	mmio_write_32(w3_addr, w3);
+	mmio_write_32(w4_addr, w4);
+
+	return 0;
+}
+
+static int xrdc_config_pac(uint32_t pac, uint32_t index, uint32_t dxacp)
+{
+	uint32_t w0_addr;
+	uint32_t val;
+
+	if (pac > 2U) {
+		return -EINVAL;
+	}
+
+	/* Skip the PAC slot for XRDC MGR, use Sentinel configuration */
+	if (pac == XRDC_MGR_PAC_ID && index == XRDC_MGR_PAC_SLOT) {
+		return 0;
+	}
+
+	w0_addr = XRDC_ADDR + 0x1000 + 0x400 * pac + 0x8 * index;
+
+	mmio_write_32(w0_addr, dxacp);
+
+	val = mmio_read_32(w0_addr + 4);
+	mmio_write_32(w0_addr + 4, val | BIT_32(31));
+
+	return 0;
+}
+
+static int xrdc_config_msc(uint32_t msc, uint32_t index, uint32_t dxacp)
+{
+	uint32_t w0_addr;
+	uint32_t val;
+
+	if (msc > 2) {
+		return -EINVAL;
+	}
+
+	w0_addr = XRDC_ADDR + 0x4000 + 0x400 * msc + 0x8 * index;
+
+	mmio_write_32(w0_addr, dxacp);
+
+	val = mmio_read_32(w0_addr + 4);
+	mmio_write_32(w0_addr + 4, val | BIT_32(31));
+
+	return 0;
+}
+
+static int xrdc_config_mda(uint32_t mda_con, uint32_t dom, enum xrdc_mda_sa sa)
+{
+	uint32_t w0_addr;
+	uint32_t val;
+
+	w0_addr = XRDC_ADDR + 0x800 + mda_con * 0x20;
+
+	val = mmio_read_32(w0_addr);
+
+	if (val & BIT_32(29)) {
+		mmio_write_32(w0_addr, (val & (~0xFF)) | dom |
+			      BIT_32(31) | 0x20 | ((sa & 0x3) << 6));
+	} else {
+		mmio_write_32(w0_addr, dom | BIT_32(31));
+		mmio_write_32(w0_addr + 0x4, dom | BIT_32(31));
+	}
+
+	return 0;
+}
+
+static bool xrdc_check_pd(enum xrdc_comp_type type,
+			  uint16_t id, enum xrdc_pd_type pd)
+{
+	unsigned int i, size;
+	uint32_t item = type | XRDC_ID(id);
+	uint32_t *list;
+
+	if (pd == XRDC_HIFI_PD) {
+		size = ARRAY_SIZE(hifi_xrdc_list);
+		list = hifi_xrdc_list;
+	} else if (pd == XRDC_AV_PD) {
+		size = ARRAY_SIZE(av_periph_xrdc_list);
+		list = av_periph_xrdc_list;
+	} else {
+		return false;
+	}
+
+	for (i = 0U; i < size; i++) {
+		if (item == list[i]) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool xrdc_check_lpav(enum xrdc_comp_type type, uint16_t id)
+{
+	return xrdc_check_pd(type, id, XRDC_AV_PD);
+}
+
+static bool xrdc_check_hifi(enum xrdc_comp_type type, uint16_t id)
+{
+	return xrdc_check_pd(type, id, XRDC_HIFI_PD);
+}
+
+static bool xrdc_check_ad(enum xrdc_comp_type type, uint16_t id)
+{
+	return (!xrdc_check_pd(type, id, XRDC_HIFI_PD) &&
+			!xrdc_check_pd(type, id, XRDC_AV_PD));
+}
+
+static int xrdc_apply_config(xrdc_check_func check_func)
+{
+	unsigned int i, j;
+	uint32_t val;
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_mda); i++) {
+		if (check_func(MDA_TYPE, imx8ulp_mda[i].mda_id)) {
+			xrdc_config_mda(imx8ulp_mda[i].mda_id,
+					imx8ulp_mda[i].did, imx8ulp_mda[i].sa);
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_mrc); i++) {
+		if (check_func(MRC_TYPE, imx8ulp_mrc[i].mrc_id)) {
+			xrdc_config_mrc_w0_w1(imx8ulp_mrc[i].mrc_id,
+					      imx8ulp_mrc[i].region_id,
+					      imx8ulp_mrc[i].region_start,
+					      imx8ulp_mrc[i].region_size);
+
+			val = 0;
+			for (j = 0U; j < DID_MAX; j++) {
+				val |= imx8ulp_mrc[i].dsel[j] << (3 * j);
+			}
+
+			xrdc_config_mrc_w2(imx8ulp_mrc[i].mrc_id, imx8ulp_mrc[i].region_id, val);
+			xrdc_config_mrc_w3_w4(imx8ulp_mrc[i].mrc_id, imx8ulp_mrc[i].region_id,
+				0, imx8ulp_mrc[i].accset[0] | (imx8ulp_mrc[i].accset[1] << 16) | BIT_32(31));
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_pdac); i++) {
+		if (check_func(PAC_TYPE, imx8ulp_pdac[i].pac_msc_id)) {
+			val = 0;
+			for (j = 0U; j < DID_MAX; j++) {
+				val |= imx8ulp_pdac[i].dsel[j] << (3 * j);
+			}
+
+			if (imx8ulp_pdac[i].slot_id == PAC_SLOT_ALL) {
+				/* Apply to all slots*/
+				for (j = 0U; j < imx8ulp_pac_slots[imx8ulp_pdac[i].pac_msc_id]; j++) {
+					xrdc_config_pac(imx8ulp_pdac[i].pac_msc_id, j, val);
+				}
+			} else {
+				if (imx8ulp_pdac[i].slot_id >= imx8ulp_pac_slots[imx8ulp_pdac[i].pac_msc_id]) {
+					return -EINVAL;
+				}
+
+				xrdc_config_pac(imx8ulp_pdac[i].pac_msc_id, imx8ulp_pdac[i].slot_id, val);
+			}
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_msc); i++) {
+		if (check_func(MSC_TYPE, imx8ulp_msc[i].pac_msc_id)) {
+			val = 0;
+			for (j = 0U; j < DID_MAX; j++) {
+				val |= imx8ulp_msc[i].dsel[j] << (3 * j);
+			}
+
+			if (imx8ulp_msc[i].slot_id == MSC_SLOT_ALL) {
+				/* Apply to all slots*/
+				for (j = 0U; j < imx8ulp_msc_slots[imx8ulp_msc[i].pac_msc_id]; j++) {
+					xrdc_config_msc(imx8ulp_msc[i].pac_msc_id, j, val);
+				}
+			} else {
+				if (imx8ulp_msc[i].slot_id >= imx8ulp_msc_slots[imx8ulp_msc[i].pac_msc_id]) {
+					return -EINVAL;
+				}
+
+				xrdc_config_msc(imx8ulp_msc[i].pac_msc_id, imx8ulp_msc[i].slot_id, val);
+			}
+		}
+	}
+
+	return 0;
+}
+
+int xrdc_apply_lpav_config(void)
+{
+	/* Configure PAC2 to allow to access PCC5 */
+	xrdc_config_pac(2, 39, 0xe00000);
+
+	/* Enable the eDMA2 MP clock for MDA16 access */
+	mmio_write_32(IMX_PCC5_BASE + 0x0, 0xc0000000);
+	return xrdc_apply_config(xrdc_check_lpav);
+}
+
+int xrdc_apply_hifi_config(void)
+{
+	return xrdc_apply_config(xrdc_check_hifi);
+}
+
+int xrdc_apply_apd_config(void)
+{
+	return xrdc_apply_config(xrdc_check_ad);
+}
+
+void xrdc_enable(void)
+{
+	mmio_write_32(XRDC_ADDR, BIT(14) | BIT(15) | BIT(0));
+}
diff --git a/plat/imx/imx93/imx93_bl31_setup.c b/plat/imx/imx93/imx93_bl31_setup.c
index 8458f6c..d997e9a 100644
--- a/plat/imx/imx93/imx93_bl31_setup.c
+++ b/plat/imx/imx93/imx93_bl31_setup.c
@@ -20,6 +20,7 @@
 #include <plat/common/platform.h>
 
 #include <imx8_lpuart.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 #include <platform_def.h>
 
@@ -90,6 +91,9 @@
 	bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
+
+	imx_bl31_params_parse(arg0, OCRAM_BASE, OCRAM_SIZE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
 }
 
 void bl31_plat_arch_setup(void)
@@ -136,11 +140,6 @@
 	plat_gic_init();
 }
 
-void bl31_plat_runtime_setup(void)
-{
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-}
-
 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
 {
 	if (type == NON_SECURE) {
diff --git a/plat/imx/imx93/include/platform_def.h b/plat/imx/imx93/include/platform_def.h
index 7efbf1c..f0d53cd 100644
--- a/plat/imx/imx93/include/platform_def.h
+++ b/plat/imx/imx93/include/platform_def.h
@@ -31,6 +31,9 @@
 #define BL31_BASE			U(0x204E0000)
 #define BL31_LIMIT			U(0x20520000)
 
+#define OCRAM_BASE			U(0x20480000)
+#define OCRAM_SIZE			U(0xA0000)
+
 /* non-secure uboot base */
 /* TODO */
 #define PLAT_NS_IMAGE_OFFSET		U(0x80200000)
diff --git a/plat/imx/imx93/platform.mk b/plat/imx/imx93/platform.mk
index ed7e81f..f506d8b 100644
--- a/plat/imx/imx93/platform.mk
+++ b/plat/imx/imx93/platform.mk
@@ -19,9 +19,11 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/common/aarch64/crash_console_helpers.S   \
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
 				plat/imx/imx93/aarch64/plat_helpers.S		\
 				plat/imx/imx93/plat_topology.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/lpuart_console.S		\
 				plat/imx/imx93/trdc.c			\
 				plat/imx/imx93/pwr_ctrl.c			\
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 0d4f2cc..8d3928f 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -182,7 +182,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index b9c28de..18f5430 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -150,90 +150,90 @@
 	$(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist"))
 	$(if $(wildcard $(CRYPTOPP_INCDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_INCDIR' was set to '$(CRYPTOPP_INCDIR)', but '$(CRYPTOPP_INCDIR)' does not exist"))
 ifdef CRYPTOPP_PATH
-	$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
+	$(q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
 endif
-	$(Q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
+	$(q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
 
 $(WTMI_MULTI_IMG): FORCE
-	$(Q)$(MAKE) --no-print-directory -C $(WTP) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
+	$(q)$(MAKE) --no-print-directory -C $(WTP) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
 
 $(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG)
-	$(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
+	$(q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
 
 $(TIMDDRTOOL): FORCE
 #	Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
 	$(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
 	$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
 	$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
-	$(Q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
+	$(q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
 
 $(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL)
-	@$(ECHO_BLANK_LINE)
-	@echo "Building uart images"
-	$(Q)mkdir -p $(BUILD_PLAT)/$(BUILD_UART)
-	$(Q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
-	$(Q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_UART_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_UART_CFG)
+	$(s)echo
+	$(s)echo "Building uart images"
+	$(q)mkdir -p $(BUILD_PLAT)/$(BUILD_UART)
+	$(q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
+	$(q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_UART_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_UART_CFG)
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_UART_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_UART_CFG)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_UART_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_UART_CFG)
 endif
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIM_UART_CFG) -v -D
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIM_UART_CFG) -v -D
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIMN_UART_CFG)
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIMN_UART_CFG)
 endif
-	$(Q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(UART_IMAGES)
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(UART_IMAGES)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 $(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL) $(TIM2IMG)
-	@$(ECHO_BLANK_LINE)
-	@echo "Building flash image"
-	$(Q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_CFG)
+	$(s)echo
+	$(s)echo "Building flash image"
+	$(q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_CFG)
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_CFG)
-	@$(ECHO_BLANK_LINE)
-	@echo "=======================================================";
-	@echo "  Secure boot. Encrypting wtmi and boot-image";
-	@echo "=======================================================";
-	@$(ECHO_BLANK_LINE)
-	$(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
-	$(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
-	$(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_CFG)
+	$(s)echo
+	$(s)echo "=======================================================";
+	$(s)echo "  Secure boot. Encrypting wtmi and boot-image";
+	$(s)echo "=======================================================";
+	$(s)echo
+	$(q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
+	$(q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
+	$(q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
 	-out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \
 	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
-	$(Q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
-	$(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
+	$(q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
+	$(q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
 	-out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
 	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 endif
-	$(Q)cd $(BUILD_PLAT) && $(TBB) -r $(TIM_CFG) -v -D
+	$(q)cd $(BUILD_PLAT) && $(TBB) -r $(TIM_CFG) -v -D
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)cd $(BUILD_PLAT) && $(TBB) -r $(TIMN_CFG)
-	$(Q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMN_CFG)
-	$(Q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMN_CFG)
+	$(q)cd $(BUILD_PLAT) && $(TBB) -r $(TIMN_CFG)
+	$(q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMN_CFG)
+	$(q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMN_CFG)
 endif
-	$(Q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 clean realclean distclean: mrvl_clean
 
 .PHONY: mrvl_clean
 mrvl_clean:
-	-$(Q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) clean
-	-$(Q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
+	-$(q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) clean
+	-$(q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
 ifdef CRYPTOPP_PATH
-	-$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
+	-$(q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
 endif
 
 else # WTP
diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c
index f105d59..030a614 100644
--- a/plat/marvell/armada/a3k/common/cm3_system_reset.c
+++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c
@@ -8,11 +8,22 @@
 #include <stdbool.h>
 
 #include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
+#include <a3700_pm.h>
+#include <platform_def.h>
 #include <mvebu_def.h>
 
+/* IO Decoder Error Interrupt Status Registers */
+#define MVEBU_DEC_WIN_REGS_BASE(p)		(MVEBU_REGS_BASE + 0xC000 + \
+						 (p) * 0x100)
+#define MVEBU_DEC_WIN_ERR_INT_STS_REG(p)	(MVEBU_DEC_WIN_REGS_BASE(p) + \
+						 0xF8)
+
 /* Cortex-M3 Secure Processor Mailbox Registers */
 #define MVEBU_RWTM_PARAM0_REG			(MVEBU_RWTM_REG_BASE)
 #define MVEBU_RWTM_CMD_REG			(MVEBU_RWTM_REG_BASE + 0x40)
@@ -23,6 +34,122 @@
 #define MVEBU_RWTM_REBOOT_CMD		0x0009
 #define MVEBU_RWTM_REBOOT_MAGIC		0xDEADBEEF
 
+static inline uint32_t a3700_gicd_read(uint32_t reg)
+{
+	return mmio_read_32(PLAT_MARVELL_GICD_BASE + reg);
+}
+
+static inline void a3700_gicd_write(uint32_t reg, uint32_t value)
+{
+	mmio_write_32(PLAT_MARVELL_GICD_BASE + reg, value);
+}
+
+static void a3700_gicd_ctlr_clear_bits(uint32_t bits)
+{
+	uint32_t val;
+
+	val = a3700_gicd_read(GICD_CTLR);
+	if ((val & bits) != 0U) {
+		a3700_gicd_write(GICD_CTLR, val & ~bits);
+		mdelay(1);
+
+		if ((a3700_gicd_read(GICD_CTLR) & GICD_CTLR_RWP_BIT) != 0U) {
+			ERROR("could not clear bits 0x%x in GIC distributor control\n",
+			      bits);
+		}
+	}
+}
+
+static void a3700_gic_dist_disable_irqs(void)
+{
+	int i;
+
+	for (i = 32; i < 224; i += 32) {
+		a3700_gicd_write(GICD_ICENABLER + (i >> 3), GENMASK_32(31, 0));
+	}
+}
+
+static inline uintptr_t a3700_rdist_base(unsigned int proc)
+{
+	return PLAT_MARVELL_GICR_BASE + (proc << GICR_V3_PCPUBASE_SHIFT);
+}
+
+static inline uint32_t a3700_gicr_read(unsigned int proc, uint32_t reg)
+{
+	return mmio_read_32(a3700_rdist_base(proc) + reg);
+}
+
+static inline void a3700_gicr_write(unsigned int proc, uint32_t reg,
+				    uint32_t value)
+{
+	mmio_write_32(a3700_rdist_base(proc) + reg, value);
+}
+
+static void a3700_gic_redist_disable_irqs(unsigned int proc)
+{
+	a3700_gicr_write(proc, GICR_ICENABLER0, GENMASK_32(31, 0));
+	mdelay(1);
+
+	if ((a3700_gicr_read(proc, GICR_CTLR) & GICR_CTLR_RWP_BIT) != 0U) {
+		ERROR("could not disable core %u PPIs & SGIs\n", proc);
+	}
+}
+
+static void a3700_gic_redist_mark_asleep(unsigned int proc)
+{
+	a3700_gicr_write(proc, GICR_WAKER,
+			 a3700_gicr_read(proc, GICR_WAKER) | WAKER_PS_BIT);
+	mdelay(1);
+
+	if ((a3700_gicr_read(proc, GICR_WAKER) & WAKER_CA_BIT) == 0U) {
+		ERROR("could not mark core %u redistributor asleep\n", proc);
+	}
+}
+
+static void a3700_io_addr_dec_ack_err_irq(void)
+{
+	unsigned int periph;
+
+	for (periph = 0; periph < 16; ++periph) {
+		/* periph 6 does not exist */
+		if (periph == 6)
+			continue;
+
+		mmio_write_32(MVEBU_DEC_WIN_ERR_INT_STS_REG(periph),
+			      GENMASK_32(1, 0));
+	}
+}
+
+static void a3700_gic_reset(void)
+{
+	a3700_gic_redist_disable_irqs(0);
+	a3700_gic_redist_disable_irqs(1);
+
+	a3700_gic_redist_mark_asleep(0);
+	a3700_gic_redist_mark_asleep(1);
+
+	a3700_io_addr_dec_ack_err_irq();
+
+	a3700_pm_ack_irq();
+
+	a3700_gic_dist_disable_irqs();
+
+	a3700_gicd_ctlr_clear_bits(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1NS_BIT |
+				   CTLR_ENABLE_G1S_BIT);
+
+	/* Clearing ARE_S and ARE_NS bits is undefined in the specification, but
+	 * works if the previous operations are successful. We need to do it in
+	 * order to put GIC into the same state it was in just after reset. If
+	 * this is successful, the rWTM firmware in the secure coprocessor will
+	 * reset all other peripherals one by one, load new firmware and boot
+	 * it, all without triggering the true warm reset via the WARM_RESET
+	 * register (which may hang the board).
+	 */
+
+	a3700_gicd_ctlr_clear_bits(CTLR_ARE_S_BIT);
+	a3700_gicd_ctlr_clear_bits(CTLR_ARE_NS_BIT);
+}
+
 static inline bool rwtm_completed(void)
 {
 	return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) &
@@ -43,6 +170,11 @@
 {
 	int tries = 5;
 
+	/* Put GIC into the same state it was just after reset. This is needed
+	 * for the reset issue workaround to work.
+	 */
+	a3700_gic_reset();
+
 	for (; tries > 0; --tries) {
 		mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG,
 				MVEBU_RWTM_HOST_INT_SP_COMPLETE);
diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h
index 44dbb9f..1be82b2 100644
--- a/plat/marvell/armada/a3k/common/include/a3700_pm.h
+++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h
@@ -48,6 +48,8 @@
 
 struct pm_wake_up_src_config *mv_wake_up_src_config_get(void);
 
+void a3700_pm_ack_irq(void);
+
 void cm3_system_reset(void);
 
 #endif /* A3700_PM_H */
diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c
index e2d15ab..d573b79 100644
--- a/plat/marvell/armada/a3k/common/plat_pm.c
+++ b/plat/marvell/armada/a3k/common/plat_pm.c
@@ -197,7 +197,7 @@
 {
 }
 
-static void a3700_pm_ack_irq(void)
+void a3700_pm_ack_irq(void)
 {
 	uint32_t reg;
 
diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index 4d8a87f..bdad8b5 100644
--- a/plat/marvell/armada/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -176,17 +176,17 @@
 
 .PHONY: mrvl_clean
 mrvl_clean:
-	@echo "  Doimage CLEAN"
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
+	$(s)echo "  Doimage CLEAN"
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}: FORCE
-	@$(DOIMAGE_LIBS_CHECK)
-	${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH}
+	$(q)$(DOIMAGE_LIBS_CHECK)
+	$(q)${MAKE} --no-print-directory -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/${FLASH_IMAGE}: ${ROM_BIN_EXT} ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL}
-	@${ECHO_BLANK_LINE}
-	@echo "Building flash image"
-	${Q}${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Building flash image"
+	$(q)${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 752ab41..5ab6123 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -32,4 +32,4 @@
 	$(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
 	$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
 	$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
-	@+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
+	$(q)+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
diff --git a/plat/marvell/armada/common/marvell_bl31_setup.c b/plat/marvell/armada/common/marvell_bl31_setup.c
index 26ba906..b3641e3 100644
--- a/plat/marvell/armada/common/marvell_bl31_setup.c
+++ b/plat/marvell/armada/common/marvell_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2018-2024 Marvell International Ltd.
  *
  * SPDX-License-Identifier:     BSD-3-Clause
  * https://spdx.org/licenses
@@ -181,8 +181,6 @@
  */
 void marvell_bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
 	/* Initialize the runtime console */
 	marvell_console_runtime_init();
 }
diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk
index f0e6edf..2561232 100644
--- a/plat/marvell/armada/common/marvell_common.mk
+++ b/plat/marvell/armada/common/marvell_common.mk
@@ -84,13 +84,13 @@
 
 $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME)
 	$(if $(shell find $(BUILD_PLAT)/bl1.bin -type f -size +128k),$(error "Image '$(BUILD_PLAT)/bl1.bin' is bigger than 128kB"))
-	@cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 .PHONY: mrvl_bootimage
 mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index ac2cbad..87a7db4 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -27,12 +27,10 @@
 # Determine option variable is defined or not then define it
 define add_defined_option
 ifdef $(1)
-ifeq ($(findstring $(value $(1)), $(uppercase_table)),)
-DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
-else
 ifeq ($(strip $(value $(1))),y)
 DEFINES += -D$(1)$(if $(value $(1)),=1,)
-endif
+else
+DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
 endif
 endif
 endef
diff --git a/plat/mediatek/common/mtk_bl31_setup.c b/plat/mediatek/common/mtk_bl31_setup.c
index 7c9db8b..0d264b9 100644
--- a/plat/mediatek/common/mtk_bl31_setup.c
+++ b/plat/mediatek/common/mtk_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -166,7 +166,6 @@
 void bl31_plat_runtime_setup(void)
 {
 	mtk_init_one_level(MTK_INIT_LVL_PLAT_RUNTIME);
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
index 86c4b81..cb57668 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -37,18 +37,8 @@
 
 int apusys_kernel_apusys_rv_setup_reviser(void)
 {
-	static bool apusys_rv_setup_reviser_called;
-
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_setup_reviser_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_setup_reviser_called = true;
-
 	mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
 	mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
 
@@ -74,18 +64,8 @@
 
 int apusys_kernel_apusys_rv_reset_mp(void)
 {
-	static bool apusys_rv_reset_mp_called;
-
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_reset_mp_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_reset_mp_called = true;
-
 	mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
 
 	dsb();
@@ -106,18 +86,8 @@
 
 int apusys_kernel_apusys_rv_setup_boot(void)
 {
-	static bool apusys_rv_setup_boot_called;
-
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_setup_boot_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_setup_boot_called = true;
-
 	mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA);
 
 	mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) |
@@ -130,55 +100,17 @@
 
 int apusys_kernel_apusys_rv_start_mp(void)
 {
-	static bool apusys_rv_start_mp_called;
-
 	spin_lock(&apusys_rv_lock);
-
-	if (apusys_rv_start_mp_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_start_mp_called = true;
-
 	mmio_write_32(MD32_RUNSTALL, MD32_RUN);
-
 	spin_unlock(&apusys_rv_lock);
 
 	return 0;
 }
 
-static bool watch_dog_is_timeout(void)
-{
-	if (mmio_read_32(WDT_INT) != WDT_INT_W1C) {
-		ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__);
-		return false;
-	}
-	return true;
-}
-
 int apusys_kernel_apusys_rv_stop_mp(void)
 {
-	static bool apusys_rv_stop_mp_called;
-
 	spin_lock(&apusys_rv_lock);
-
-	if (apusys_rv_stop_mp_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	if (watch_dog_is_timeout() == false) {
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_stop_mp_called = true;
-
 	mmio_write_32(MD32_RUNSTALL, MD32_STALL);
-
 	spin_unlock(&apusys_rv_lock);
 
 	return 0;
@@ -186,19 +118,10 @@
 
 int apusys_kernel_apusys_rv_setup_sec_mem(void)
 {
-	static bool apusys_rv_setup_sec_mem_called;
 	int ret;
 
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_setup_sec_mem_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_setup_sec_mem_called = true;
-
 	ret = set_apu_emi_mpu_region();
 	if (ret != 0) {
 		ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
@@ -230,12 +153,6 @@
 int apusys_kernel_apusys_rv_cg_gating(void)
 {
 	spin_lock(&apusys_rv_lock);
-
-	if (watch_dog_is_timeout() == false) {
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
 	spin_unlock(&apusys_rv_lock);
 
@@ -245,12 +162,6 @@
 int apusys_kernel_apusys_rv_cg_ungating(void)
 {
 	spin_lock(&apusys_rv_lock);
-
-	if (watch_dog_is_timeout() == false) {
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
 	spin_unlock(&apusys_rv_lock);
 
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
index da5242a..f4ff763 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
@@ -271,15 +271,8 @@
 
 int apusys_devapc_rcx_init(void)
 {
-	static bool apusys_devapc_rcx_init_called;
 	enum apusys_apc_err_status ret;
 
-	if (apusys_devapc_rcx_init_called == true) {
-		INFO(MODULE_TAG "%s: init more than once!\n", __func__);
-		return -1;
-	}
-	apusys_devapc_rcx_init_called = true;
-
 	apusys_devapc_init("APUAPC_CTRL_RCX", APU_CTRL_DAPC_RCX_BASE);
 	apusys_devapc_init("APUAPC_NOC_RCX", APU_NOC_DAPC_RCX_BASE);
 
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
index ef7134c..329a45e 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -18,7 +18,7 @@
 #define FORBIDDEN			(5)
 #define SEC_R_NSEC_RW			(6)
 
-#define LOCK				(1)
+#define LOCK				(1UL)
 #define UNLOCK				(0)
 
 #if (EMI_MPU_DGROUP_NUM == 1)
@@ -69,6 +69,7 @@
 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);
+int emi_mpu_clear_protection(unsigned int region);
 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 8810be3..1e732f0 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -39,13 +39,13 @@
 	}
 
 #if ENABLE_EMI_MPU_SW_LOCK
-	if (region_lock_state[region] == 1) {
+	if (region_lock_state[region] == LOCK) {
 		WARN("invalid region\n");
 		return -1;
 	}
 
 	if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
-		region_lock_state[region] = 1;
+		region_lock_state[region] = LOCK;
 	}
 
 	apc &= EMI_MPU_APC_SW_LOCK_MASK;
@@ -73,6 +73,50 @@
 	return 0;
 }
 
+int emi_mpu_clear_protection(unsigned int region)
+{
+	unsigned int dgroup;
+
+	if (region >= EMI_MPU_REGION_NUM) {
+		WARN("invalid region number\n");
+		return -1;
+	}
+
+#if ENABLE_EMI_MPU_SW_LOCK
+	if (region_lock_state[region] == LOCK) {
+		WARN("SW:region is locked\n");
+		return -1;
+	}
+#endif
+	if (mmio_read_32(EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+		WARN("HW:EMI-MPU region is locked\n");
+		return -1;
+	}
+
+#if defined(SUB_EMI_MPU_BASE)
+	if (mmio_read_32(SUB_EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+		WARN("HW:SUB EMI-MPU region is locked\n");
+		return -1;
+	}
+#endif
+
+	for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+		mmio_write_32(EMI_MPU_APC(region, dgroup), 0x0);
+
+	mmio_write_32(EMI_MPU_SA(region), 0x0);
+	mmio_write_32(EMI_MPU_EA(region), 0x0);
+
+#if defined(SUB_EMI_MPU_BASE)
+	for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+		mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), 0x0);
+
+	mmio_write_32(SUB_EMI_MPU_SA(region), 0);
+	mmio_write_32(SUB_EMI_MPU_EA(region), 0);
+#endif
+	return 0;
+}
+
+
 static void dump_emi_mpu_regions(void)
 {
 	int region, i;
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index e8882f0..f7ed5e6 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -14,11 +14,33 @@
 {
 	struct emi_region_info_t region_info;
 
+	/* BL31 address */
+	region_info.start = TZRAM_BASE;
+	region_info.end = TZRAM_BASE + TZRAM_SIZE - 1;
+	region_info.region = BL31_EMI_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+	emi_mpu_set_protection(&region_info);
+
+	/* BL32 address */
+	region_info.start = BL32_REGION_BASE;
+	region_info.end = BL32_REGION_BASE + BL32_REGION_SIZE - 1;
+	region_info.region = BL32_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
+	emi_mpu_set_protection(&region_info);
+
 	/* SCP core0 DRAM */
-	region_info.start = 0x50000000ULL;
-	region_info.end = 0x528FFFFFULL;
-	region_info.region = 2;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = SCP_CORE0_REGION_BASE;
+	region_info.end = SCP_CORE0_REGION_BASE + SCP_CORE0_REGION_SIZE - 1;
+	region_info.region = SCP_CORE0_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -26,10 +48,10 @@
 	emi_mpu_set_protection(&region_info);
 
 	/* SCP core1 DRAM */
-	region_info.start = 0x70000000ULL;
-	region_info.end = 0x729FFFFFULL;
-	region_info.region = 3;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = SCP_CORE1_REGION_BASE;
+	region_info.end = SCP_CORE1_REGION_BASE + SCP_CORE1_REGION_SIZE - 1;
+	region_info.region = SCP_CORE1_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -37,10 +59,10 @@
 	emi_mpu_set_protection(&region_info);
 
 	/* DSP protect address */
-	region_info.start = 0x60000000ULL;
-	region_info.end = 0x610FFFFFULL;
-	region_info.region = 4;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = DSP_PROTECT_REGION_BASE;
+	region_info.end = DSP_PROTECT_REGION_BASE + DSP_PROTECT_REGION_SIZE - 1;
+	region_info.region = DSP_PROTECT_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
@@ -48,10 +70,10 @@
 	emi_mpu_set_protection(&region_info);
 
 	/* All default settings */
-	region_info.start = 0x40000000ULL;
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 31;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = DRAM_START_ADDR;
+	region_info.end = DRAM_START_ADDR + DRAM_MAX_SIZE - 1;
+	region_info.region = ALL_DEFAULT_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
 			      NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN,
@@ -65,7 +87,7 @@
 
 	region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA;
 	region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1;
-	region_info.region = APUSYS_SEC_BUF_EMI_REGION;
+	region_info.region = APUSYS_SEC_BUF_EMI_REGION_ID;
 
 	SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
@@ -86,12 +108,18 @@
 	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
 }
 
+static inline uint32_t get_decoded_set_clear_info(uint32_t info)
+{
+	return (info & 0x0000FFFF);
+}
+
 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);
+	uint32_t is_set = get_decoded_set_clear_info(zone_info);
 
 	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
 	     encoded_addr, zone_size, zone_info);
@@ -101,17 +129,21 @@
 		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);
+	if (is_set > 0) {
+		/* SVP DRAM */
+		region_info.start = phys_addr;
+		region_info.end = phys_addr + zone_size - 1;
+		region_info.region = SVP_DRAM_REGION_ID;
+		SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
+					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, SEC_RW, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
 
-	emi_mpu_set_protection(&region_info);
+		emi_mpu_set_protection(&region_info);
+	} else { /* clear region protection */
+		emi_mpu_clear_protection(SVP_DRAM_REGION_ID);
+	}
 
 	return 0;
-}
\ No newline at end of file
+}
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
index cc7f7f1..18acb9c 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -7,7 +7,7 @@
 #ifndef EMI_MPU_PRIV_H
 #define EMI_MPU_PRIV_H
 
-#define ENABLE_EMI_MPU_SW_LOCK		(1)
+#define ENABLE_EMI_MPU_SW_LOCK		(0)
 
 #define EMI_MPU_CTRL			(EMI_MPU_BASE + 0x000)
 #define EMI_MPU_DBG			(EMI_MPU_BASE + 0x004)
@@ -38,13 +38,34 @@
 #define EMI_MPU_DOMAIN_NUM		(16)
 #define EMI_MPU_REGION_NUM		(32)
 #define EMI_MPU_ALIGN_BITS		(16)
-#define DRAM_OFFSET			(0x40000000 >> EMI_MPU_ALIGN_BITS)
+#define DRAM_START_ADDR                 (0x40000000ULL)
+#define DRAM_OFFSET			(DRAM_START_ADDR >> EMI_MPU_ALIGN_BITS)
+#define DRAM_MAX_SIZE			(0x200000000ULL)
+#define BL32_REGION_BASE		(0x43000000ULL)
+#define BL32_REGION_SIZE		(0x4600000ULL)
+#define SCP_CORE0_REGION_BASE		(0x50000000ULL)
+#define SCP_CORE0_REGION_SIZE		(0x800000ULL)
+#define SCP_CORE1_REGION_BASE		(0x70000000ULL)
+#define SCP_CORE1_REGION_SIZE		(0xa000000ULL)
+#define DSP_PROTECT_REGION_BASE		(0x60000000ULL)
+#define DSP_PROTECT_REGION_SIZE		(0x1100000ULL)
 
 #define EMI_MPU_DGROUP_NUM		(EMI_MPU_DOMAIN_NUM / 8)
 
 /* APU EMI MPU Setting */
-#define APUSYS_SEC_BUF_EMI_REGION	(21)
 #define APUSYS_SEC_BUF_PA		(0x55000000)
 #define APUSYS_SEC_BUF_SZ		(0x100000)
 
+enum region_ids {
+	BL31_EMI_REGION_ID = 0,
+	BL32_REGION_ID,
+	SCP_CORE0_REGION_ID,
+	SCP_CORE1_REGION_ID,
+	DSP_PROTECT_REGION_ID,
+	SVP_DRAM_REGION_ID,
+
+	APUSYS_SEC_BUF_EMI_REGION_ID = 21,
+
+	ALL_DEFAULT_REGION_ID = 31,
+};
 #endif
diff --git a/plat/mediatek/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c
index 85f9e37..2f9765c 100644
--- a/plat/mediatek/drivers/gic600/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +27,10 @@
 /* we save and restore the GICv3 context on system suspend */
 gicv3_dist_ctx_t dist_ctx;
 
+static const interrupt_prop_t mtk_interrupt_props[] = {
+	PLAT_MTK_G1S_IRQ_PROPS(INTR_GROUP1S)
+};
+
 static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr)
 {
 	return plat_core_pos_by_mpidr(mpidr);
@@ -35,6 +39,8 @@
 gicv3_driver_data_t mt_gicv3_data = {
 	.gicd_base = MT_GIC_BASE,
 	.gicr_base = MT_GIC_RDIST_BASE,
+	.interrupt_props = mtk_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(mtk_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
 	.rdistif_base_addrs = rdistif_base_addrs,
 	.mpidr_to_core_pos = mt_mpidr_to_core_pos,
diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h
index 850ce2f..98b88bd 100644
--- a/plat/mediatek/mt8186/include/platform_def.h
+++ b/plat/mediatek/mt8186/include/platform_def.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -83,6 +83,8 @@
 #define BASE_GICD_BASE		MT_GIC_BASE
 #define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
 
+#define PLAT_MTK_G1S_IRQ_PROPS(grp)
+
 #define SYS_CIRQ_BASE		(IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM		(11)
 #define CIRQ_IRQ_NUM		(326)
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index 71a4e97..8e0f5f9 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,6 +96,11 @@
 /* Base MTK_platform compatible GIC memory map */
 #define BASE_GICD_BASE		(MT_GIC_BASE)
 #define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID		580
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
 
 /*******************************************************************************
  * CIRQ related constants
diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h
index ec377b5..1b25e00 100644
--- a/plat/mediatek/mt8192/include/platform_def.h
+++ b/plat/mediatek/mt8192/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -82,6 +82,8 @@
 #define BASE_GICD_BASE        MT_GIC_BASE
 #define MT_GIC_RDIST_BASE     (MT_GIC_BASE + 0x40000)
 
+#define PLAT_MTK_G1S_IRQ_PROPS(grp)
+
 #define SYS_CIRQ_BASE         (IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM          14
 #define CIRQ_IRQ_NUM          439
diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h
index 8696f2a..a70abec 100644
--- a/plat/mediatek/mt8195/include/platform_def.h
+++ b/plat/mediatek/mt8195/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -95,6 +95,11 @@
 /* Base MTK_platform compatible GIC memory map */
 #define BASE_GICD_BASE			MT_GIC_BASE
 #define MT_GIC_RDIST_BASE		(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID			580
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
 
 #define SYS_CIRQ_BASE			(IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM			23
diff --git a/plat/nuvoton/common/nuvoton_helpers.S b/plat/nuvoton/common/nuvoton_helpers.S
index 09035a1..9c78815 100644
--- a/plat/nuvoton/common/nuvoton_helpers.S
+++ b/plat/nuvoton/common/nuvoton_helpers.S
@@ -151,9 +151,9 @@
 	 */
 	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 x8, x0
 	mov_imm	x2, PLAT_NPCM_TRUSTED_NOTIFICATION_BASE
 	add	x8, x8, x2
 	/*
diff --git a/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c b/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
index 08448db..4b29bbc 100644
--- a/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
+++ b/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
@@ -47,6 +47,20 @@
 					BL31_END - BL31_START, \
 					MT_MEMORY | MT_RW | EL3_PAS)
 
+#if RECLAIM_INIT_CODE
+IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
+
+#define	BL_INIT_CODE_END	((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
+					~(PAGE_SIZE - 1))
+
+#define MAP_BL_INIT_CODE	MAP_REGION_FLAT( \
+					BL_INIT_CODE_BASE, \
+					BL_INIT_CODE_END - \
+					BL_INIT_CODE_BASE, \
+					MT_CODE | MT_SECURE)
+#endif /* RECLAIM_INIT_CODE */
+
 #if SEPARATE_NOBITS_REGION
 #define MAP_BL31_NOBITS		MAP_REGION_FLAT( \
 					BL31_NOBITS_BASE, \
@@ -103,7 +117,10 @@
 
 unsigned int plat_get_syscnt_freq2(void)
 {
-	return (unsigned int)COUNTER_FREQUENCY;
+	/*
+	 * Do not overwrite the value set by BootBlock
+	 */
+	return (unsigned int)read_cntfrq_el0();
 }
 
 /******************************************************************************
@@ -117,6 +134,7 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+	arg0 = arg1 = arg2 = arg3 = 0;
 #if RESET_TO_BL31
 	void *from_bl2 = (void *)arg0;
 	void *plat_params_from_bl2 = (void *)arg3;
@@ -309,24 +327,11 @@
 {
 	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());
diff --git a/plat/nuvoton/npcm845x/platform.mk b/plat/nuvoton/npcm845x/platform.mk
index 92c7e2f..1959aac 100644
--- a/plat/nuvoton/npcm845x/platform.mk
+++ b/plat/nuvoton/npcm845x/platform.mk
@@ -12,6 +12,7 @@
 SPMD_SPM_AT_SEL2	:= 0
 #temporary until the RAM size is reduced
 USE_COHERENT_MEM	:=	1
+INIT_UNUSED_NS_EL2  := 1
 
 
 $(eval $(call add_define,RESET_TO_BL31))
@@ -21,12 +22,29 @@
 # Trusted DRAM (if available) or the TZC secured area of DRAM.
 # TZC secured DRAM is the default.
 
+ARM_TSP_RAM_LOCATION	?=	dram
+
+ifeq (${ARM_TSP_RAM_LOCATION}, tsram)
+ARM_TSP_RAM_LOCATION_ID	=	ARM_TRUSTED_SRAM_ID
+else ifeq (${ARM_TSP_RAM_LOCATION}, tdram)
+ARM_TSP_RAM_LOCATION_ID	=	ARM_TRUSTED_DRAM_ID
+else ifeq (${ARM_TSP_RAM_LOCATION}, dram)
+ARM_TSP_RAM_LOCATION_ID	=	ARM_DRAM_ID
+else
+$(error "Unsupported ARM_TSP_RAM_LOCATION value")
+endif
+
+# Process flags
 # 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))
+else
+ARM_TSP_RAM_LOCATION_ID	=	ARM_TRUSTED_SRAM_ID
 endif
 
+$(eval $(call add_define,ARM_TSP_RAM_LOCATION_ID))
+
 # 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.
@@ -140,11 +158,25 @@
 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 \
@@ -287,7 +319,8 @@
 
 # Pointer Authentication sources
 ifeq (${ENABLE_PAUTH}, 1)
-PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c \
+		lib/extensions/pauth/pauth_helpers.S
 endif
 
 ifeq (${SPD},spmd)
@@ -325,7 +358,11 @@
 $(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
 
@@ -336,6 +373,12 @@
 include ${IMG_PARSER_LIB_MK}
 endif
 
+ifeq (${RECLAIM_INIT_CODE}, 1)
+ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+$(error "To reclaim init code xlat tables v2 must be used")
+endif
+endif
+
 ifeq (${MEASURED_BOOT},1)
 MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk
 $(info Including ${MEASURED_BOOT_MK})
@@ -352,3 +395,6 @@
 
 DEBUG_CONSOLE	?=	0
 $(eval $(call add_define,DEBUG_CONSOLE))
+
+$(eval $(call add_define,ARM_TSP_RAM_LOCATION_ID))
+
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index e3068b6..09eda84 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
index 4e84d02..14ddefd 100644
--- a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
@@ -1,6 +1,6 @@
 #
 # Copyright 2018-2020 NXP
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -73,7 +73,7 @@
 ifeq (${FUSE_PROV_FILE},)
 else
 ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}: ${FUSE_PROV_FILE}
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${FUSE_INPUT_FILE}
 endif
@@ -81,7 +81,7 @@
 ifeq (${FUSE_UP_FILE},)
 else
 ${BUILD_PLAT}/${FUSE_UP_FILE_SB}: ${FUSE_UP_FILE}
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${FUSE_INPUT_FILE}
 endif
@@ -94,6 +94,6 @@
 endif
 	${FIPTOOL} create ${FUSE_FIP_ARGS} $@
 	${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
index 4aac9d6..000e419 100644
--- a/plat/nxp/common/tbbr/tbbr.mk
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -131,14 +131,14 @@
 
     certificates: $(ROT_KEY)
     $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
     $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 
 endif #MBEDTLS_DIR
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_console.h b/plat/nxp/s32/s32g274ardb2/include/plat_console.h
new file mode 100644
index 0000000..43c2bfd
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_console.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_CONSOLE_H
+#define PLAT_CONSOLE_H
+
+void console_s32g2_register(void);
+
+#endif
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_helpers.h b/plat/nxp/s32/s32g274ardb2/include/plat_helpers.h
new file mode 100644
index 0000000..18582ec
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_HELPERS_H
+#define PLAT_HELPERS_H
+
+unsigned int s32g2_core_pos_by_mpidr(u_register_t mpidr);
+
+#endif /* PLAT_HELPERS_H */
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h b/plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h
new file mode 100644
index 0000000..ea01300
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_IO_STORAGE_H
+#define PLAT_IO_STORAGE_H
+
+void plat_s32g2_io_setup(void);
+
+#endif
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_macros.S b/plat/nxp/s32/s32g274ardb2/include/plat_macros.S
new file mode 100644
index 0000000..8f0c472
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_macros.S
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant GIC and CCI registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * Clobbers: x0 - x10, x16, x17, sp
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+.endm
+
+#endif /* PLAT_MACROS_S */
+
diff --git a/plat/nxp/s32/s32g274ardb2/include/platform_def.h b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
new file mode 100644
index 0000000..bdfeee2
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/common/common_def.h>
+
+#define PLATFORM_STACK_SIZE		U(0x1000)
+
+/* Caches */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* CPU Topology */
+#define PLATFORM_CORE_COUNT		U(4)
+#define PLATFORM_SYSTEM_COUNT		U(1)
+#define PLATFORM_CLUSTER_COUNT		U(2)
+#define PLATFORM_PRIMARY_CPU		U(0)
+#define PLATFORM_MPIDR_CPU_MASK_BITS	U(1)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(2)
+
+/* Power Domains */
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_SYSTEM_COUNT + \
+					 PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_PWR_LVL_STATES		U(2)
+
+/* BL2 stage */
+#define BL2_BASE			UL(0x34078000)
+#define BL2_LIMIT			UL(0x34100000)
+
+/* BL31 stage */
+#define BL31_BASE			UL(0x34200000)
+#define BL31_LIMIT			UL(0x34300000)
+
+/* It is a dummy value for now, given the missing DDR */
+#define BL33_BASE			UL(0x34500000)
+#define BL33_LIMIT			UL(0x345FF000)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 36)
+/* We'll be doing a 1:1 mapping anyway */
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 36)
+
+#define MAX_MMAP_REGIONS		U(8)
+#define MAX_XLAT_TABLES			U(32)
+
+/* Console settings */
+#define UART_BASE			UL(0x401C8000)
+#define UART_BAUDRATE			U(115200)
+/* FIRC clock */
+#define UART_CLOCK_HZ			U(48000000)
+
+#define S32G_FIP_BASE			UL(0x34100000)
+#define S32G_FIP_SIZE			UL(0x100000)
+
+#define MAX_IO_HANDLES			U(2)
+#define MAX_IO_DEVICES			U(2)
+
+/* GIC settings */
+#define S32G_GIC_BASE			UL(0x50800000)
+#define PLAT_GICD_BASE			S32G_GIC_BASE
+#define PLAT_GICR_BASE			(S32G_GIC_BASE + UL(0x80000))
+
+/* Generic timer frequency; this goes directly into CNTFRQ_EL0.
+ * Its end-value is 5MHz; this is based on the assumption that
+ * GPR00[CA53_COUNTER_CLK_DIV_VAL] contains the reset value of 0x7, hence
+ * producing a divider value of 8, applied to the FXOSC frequency of 40MHz.
+ */
+#define COUNTER_FREQUENCY		U(5000000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
new file mode 100644
index 0000000..705832c
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <plat_console.h>
+#include <s32cc-clk-drv.h>
+#include <plat_io_storage.h>
+
+#define SIUL2_PC09_MSCR		UL(0x4009C2E4)
+#define SIUL2_PC10_MSCR		UL(0x4009C2E8)
+#define SIUL2_PC10_LIN0_IMCR	UL(0x4009CA40)
+
+#define LIN0_TX_MSCR_CFG	U(0x00214001)
+#define LIN0_RX_MSCR_CFG	U(0x00094000)
+#define LIN0_RX_IMCR_CFG	U(0x00000002)
+
+struct bl_load_info *plat_get_bl_image_load_info(void)
+{
+	return get_bl_load_info_from_mem_params_desc();
+}
+
+struct bl_params *plat_get_next_bl_params(void)
+{
+	return get_next_bl_params_from_mem_params_desc();
+}
+
+void plat_flush_next_bl_params(void)
+{
+	flush_bl_params_desc();
+}
+
+void bl2_platform_setup(void)
+{
+}
+
+static void linflex_config_pinctrl(void)
+{
+	/* set PC09 - MSCR[41] - for UART0 TXD */
+	mmio_write_32(SIUL2_PC09_MSCR, LIN0_TX_MSCR_CFG);
+	/* set PC10 - MSCR[42] - for UART0 RXD */
+	mmio_write_32(SIUL2_PC10_MSCR, LIN0_RX_MSCR_CFG);
+	/* set PC10 - MSCR[512]/IMCR[0] - for UART0 RXD */
+	mmio_write_32(SIUL2_PC10_LIN0_IMCR, LIN0_RX_IMCR_CFG);
+}
+
+void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	int ret;
+
+	ret = s32cc_init_early_clks();
+	if (ret != 0) {
+		panic();
+	}
+
+	linflex_config_pinctrl();
+	console_s32g2_register();
+
+	plat_s32g2_io_setup();
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+}
+
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c
new file mode 100644
index 0000000..1fc7794
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+				      entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS),
+		.ep_info.pc = BL31_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+				      image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+		.image_info.image_base = BL31_BASE,
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	{
+		.image_id = BL33_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+				      entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+				      image_info_t, 0),
+		.image_info.image_max_size = BL33_LIMIT - BL33_BASE,
+		.image_info.image_base = BL33_BASE,
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
new file mode 100644
index 0000000..03bf35c
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/gicv3.h>
+#include <plat/common/platform.h>
+#include <plat_console.h>
+
+static entry_point_info_t bl33_image_ep_info;
+
+static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr);
+
+static uint32_t get_spsr_for_bl33_entry(void)
+{
+	unsigned long mode = MODE_EL1;
+	uint32_t spsr;
+
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+
+	return spsr;
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	console_s32g2_register();
+
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	bl33_image_ep_info.pc = BL33_BASE;
+	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+}
+
+void bl31_plat_arch_setup(void)
+{
+}
+
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	return &bl33_image_ep_info;
+}
+
+void bl31_platform_setup(void)
+{
+	static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+	static gicv3_driver_data_t plat_gic_data = {
+		.gicd_base = PLAT_GICD_BASE,
+		.gicr_base = PLAT_GICR_BASE,
+		.rdistif_num = PLATFORM_CORE_COUNT,
+		.rdistif_base_addrs = rdistif_base_addrs,
+		.mpidr_to_core_pos = s32g2_mpidr_to_core_pos,
+	};
+
+	unsigned int pos = plat_my_core_pos();
+
+	gicv3_driver_init(&plat_gic_data);
+	gicv3_distif_init();
+	gicv3_rdistif_init(pos);
+	gicv3_cpuif_enable(pos);
+}
+
+static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr)
+{
+	int core;
+
+	core = plat_core_pos_by_mpidr(mpidr);
+	if (core < 0) {
+		return 0;
+	}
+
+	return (unsigned int)core;
+}
+
diff --git a/plat/nxp/s32/s32g274ardb2/plat_console.c b/plat/nxp/s32/s32g274ardb2/plat_console.c
new file mode 100644
index 0000000..542fa7b
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_console.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <linflex.h>
+#include <plat_console.h>
+#include <platform_def.h>
+
+void console_s32g2_register(void)
+{
+	static console_t s32g2_console = {
+		.next = NULL,
+		.flags = 0u,
+	};
+	int ret;
+
+	ret = console_linflex_register(UART_BASE, UART_CLOCK_HZ,
+				       UART_BAUDRATE, &s32g2_console);
+	if (ret == 0) {
+		panic();
+	}
+
+	console_set_scope(&s32g2_console,
+			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH |
+			  CONSOLE_FLAG_TRANSLATE_CRLF);
+}
diff --git a/plat/nxp/s32/s32g274ardb2/plat_helpers.S b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
new file mode 100644
index 0000000..193c884
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <platform_def.h>
+
+#define S32G_NCORE_CAIU0_BASE_ADDR		UL(0x50400000)
+#define S32G_NCORE_CAIUTC_OFF			U(0x0)
+#define S32G_NCORE_CAIUTC_ISOLEN_SHIFT		U(1)
+
+.globl	plat_crash_console_flush
+.globl	plat_crash_console_init
+.globl	plat_crash_console_putc
+.globl	plat_is_my_cpu_primary
+.globl	plat_my_core_pos
+.globl	plat_reset_handler
+.globl	plat_secondary_cold_boot_setup
+.globl	platform_mem_init
+.globl	s32g2_core_pos_by_mpidr
+
+/* int plat_crash_console_init(void); */
+func plat_crash_console_init
+	mov_imm	x0, UART_BASE
+	mov_imm	x1, UART_CLOCK_HZ
+	mov_imm	x2, UART_BAUDRATE
+	b	console_linflex_core_init
+endfunc plat_crash_console_init
+
+/* int plat_crash_console_putc(int); */
+func plat_crash_console_putc
+	mov_imm	x1, UART_BASE
+	b	console_linflex_core_putc
+	ret
+endfunc plat_crash_console_putc
+
+/* void plat_crash_console_flush(void); */
+func plat_crash_console_flush
+	ret
+endfunc plat_crash_console_flush
+
+/**
+ * unsigned int s32g2_core_pos_by_mpidr(u_register_t mpidr);
+ *
+ * In: x0 -  MPIDR_EL1
+ * Out: x0
+ * Clobber list: x0, x1
+ */
+func s32g2_core_pos_by_mpidr
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	lsr	x0, x0, #MPIDR_AFF1_SHIFT
+	add	x0, x1, x0, lsl #PLATFORM_MPIDR_CPU_MASK_BITS
+	ret
+endfunc s32g2_core_pos_by_mpidr
+
+/**
+ * unsigned int plat_my_core_pos(void);
+ *
+ * Out: x0
+ * Clobber list: x0, x1, x8
+ */
+func plat_my_core_pos
+	mov	x8, x30
+	mrs x0, mpidr_el1
+	bl	s32g2_core_pos_by_mpidr
+	mov	x30, x8
+	ret
+endfunc plat_my_core_pos
+
+/**
+ * unsigned int plat_is_my_cpu_primary(void);
+ *
+ * Clobber list: x0, x1, x7, x8
+ */
+func plat_is_my_cpu_primary
+	mov	x7, x30
+	bl	plat_my_core_pos
+	cmp	x0, #PLATFORM_PRIMARY_CPU
+	cset	x0, eq
+	mov	x30, x7
+	ret
+endfunc plat_is_my_cpu_primary
+
+
+/**
+ * void plat_secondary_cold_boot_setup (void);
+ */
+func plat_secondary_cold_boot_setup
+	ret
+endfunc plat_secondary_cold_boot_setup
+
+/**
+ * void plat_reset_handler(void);
+ *
+ * Set the CAIUTC[IsolEn] bit for the primary A53 cluster.
+ * This is so cache invalidate operations from the early TF-A boot code
+ * won't cause Ncore to crash.
+ *
+ * Clobber list: x0, x1, x2
+ */
+func plat_reset_handler
+	mov	x0, #S32G_NCORE_CAIU0_BASE_ADDR
+	ldr	w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+	movz	w2, #1
+	lsl	w2, w2, #S32G_NCORE_CAIUTC_ISOLEN_SHIFT
+	orr	w1, w1, w2
+	str	w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+	ret
+endfunc plat_reset_handler
+
+/* void platform_mem_init(void); */
+func platform_mem_init
+	mov	x10, x30
+	mov	x0, #BL31_BASE
+	mov	x1, #(BL31_LIMIT & 0xFFFFU)
+	movk	x1, #(BL31_LIMIT >> 16), lsl #16
+	sub	x1, x1, x0
+	bl	zeromem
+	mov	x0, #BL33_BASE
+	mov	x1, #(BL33_LIMIT & 0xFFFFU)
+	movk	x1, #(BL33_LIMIT >> 16), lsl #16
+	sub	x1, x1, x0
+	bl	zeromem
+	mov	x30, x10
+	ret
+endfunc platform_mem_init
+
diff --git a/plat/nxp/s32/s32g274ardb2/plat_io_storage.c b/plat/nxp/s32/s32g274ardb2/plat_io_storage.c
new file mode 100644
index 0000000..db6bcc5
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_io_storage.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <plat/common/platform.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat_io_storage.h>
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static int open_memmap(const uintptr_t spec);
+static int open_fip(const uintptr_t spec);
+
+static uintptr_t fip_dev_handle;
+
+static uintptr_t memmap_dev_handle;
+
+static int open_memmap(const uintptr_t spec)
+{
+	uintptr_t temp_handle = 0U;
+	int result;
+
+	result = io_dev_init(memmap_dev_handle, (uintptr_t)0);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_open(memmap_dev_handle, spec, &temp_handle);
+	if (result == 0) {
+		(void)io_close(temp_handle);
+	}
+
+	return result;
+}
+
+static int open_fip(const uintptr_t spec)
+{
+	uintptr_t temp_handle = 0U;
+	int result;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_open(fip_dev_handle, spec, &temp_handle);
+	if (result == 0) {
+		(void)io_close(temp_handle);
+	}
+
+	return result;
+}
+
+void plat_s32g2_io_setup(void)
+{
+	static const io_dev_connector_t *memmap_dev_con;
+	static const io_dev_connector_t *fip_dev_con;
+
+	int result __unused;
+
+	result = register_io_dev_memmap(&memmap_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(memmap_dev_con, (uintptr_t)0,
+			     &memmap_dev_handle);
+	assert(result == 0);
+
+	result = register_io_dev_fip(&fip_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(fip_dev_con, (uintptr_t)0,
+			     &fip_dev_handle);
+	assert(result == 0);
+}
+
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	static const io_block_spec_t fip_block_spec = {
+		.offset = S32G_FIP_BASE,
+		.length = S32G_FIP_SIZE,
+	};
+
+	static const io_uuid_spec_t bl31_uuid_spec = {
+		.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+	};
+
+	static const io_uuid_spec_t bl33_uuid_spec = {
+		.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+	};
+
+	static const struct plat_io_policy policies[BL33_IMAGE_ID + 1] = {
+		[FIP_IMAGE_ID] = {
+			.dev_handle = &memmap_dev_handle,
+			.image_spec = (uintptr_t)&fip_block_spec,
+			.check = open_memmap,
+		},
+		[BL31_IMAGE_ID] = {
+			.dev_handle = &fip_dev_handle,
+			.image_spec = (uintptr_t)&bl31_uuid_spec,
+			.check = open_fip,
+		},
+		[BL33_IMAGE_ID] = {
+			.dev_handle = &fip_dev_handle,
+			.image_spec = (uintptr_t)&bl33_uuid_spec,
+			.check = open_fip,
+		},
+	};
+	const struct plat_io_policy *policy;
+	int result;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	result = policy->check(policy->image_spec);
+	assert(result == 0);
+
+	*image_spec = policy->image_spec;
+	*dev_handle = *policy->dev_handle;
+
+	return result;
+}
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
new file mode 100644
index 0000000..316ed2c
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -0,0 +1,66 @@
+#
+# Copyright 2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_DRIVERS_PATH := drivers/nxp
+PLAT_COMMON_PATH  := plat/nxp/common
+PLAT_S32G274ARDB2 := plat/nxp/s32/s32g274ardb2
+
+CONSOLE           := LINFLEX
+
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+PLAT_INCLUDES = \
+	-I${PLAT_S32G274ARDB2}/include
+
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+COLD_BOOT_SINGLE_CPU := 0
+
+ENABLE_SVE_FOR_NS := 0
+
+RESET_TO_BL2 := 1
+
+INIT_UNUSED_NS_EL2 := 1
+
+ERRATA_A53_855873 := 1
+ERRATA_A53_836870 := 1
+ERRATA_A53_1530924 := 1
+ERRATA_SPECULATIVE_AT := 1
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,CLK_NEEDED,BL_COMM))
+
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+
+BL_COMMON_SOURCES += \
+	${PLAT_S32G274ARDB2}/plat_console.c \
+	${PLAT_S32G274ARDB2}/plat_helpers.S \
+
+BL2_SOURCES += \
+	${BL_COMMON_SOURCES} \
+	${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
+	${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
+	${PLAT_S32G274ARDB2}/plat_io_storage.c \
+	common/desc_image_load.c \
+	drivers/io/io_fip.c \
+	drivers/io/io_memmap.c \
+	drivers/io/io_storage.c \
+	lib/cpus/aarch64/cortex_a53.S \
+
+BL31_SOURCES += \
+	${GICV3_SOURCES} \
+	${PLAT_S32G274ARDB2}/plat_bl31_setup.c \
+	${PLAT_S32G274ARDB2}/s32g2_psci.c \
+	${PLAT_S32G274ARDB2}/s32g2_soc.c \
+	${XLAT_TABLES_LIB_SRCS} \
+	lib/cpus/aarch64/cortex_a53.S \
+	plat/common/plat_gicv3.c \
+	plat/common/plat_psci_common.c \
diff --git a/plat/nxp/s32/s32g274ardb2/s32g2_psci.c b/plat/nxp/s32/s32g274ardb2/s32g2_psci.c
new file mode 100644
index 0000000..2d02d94
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32g2_psci.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	static const plat_psci_ops_t s32g2_psci_ops = {
+	};
+
+	*psci_ops = &s32g2_psci_ops;
+
+	return 0;
+}
+
diff --git a/plat/nxp/s32/s32g274ardb2/s32g2_soc.c b/plat/nxp/s32/s32g274ardb2/s32g2_soc.c
new file mode 100644
index 0000000..0001352
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32g2_soc.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <plat_helpers.h>
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	static const unsigned char s32g_power_domain_tree_desc[] = {
+		PLATFORM_SYSTEM_COUNT,
+		PLATFORM_CLUSTER_COUNT,
+		PLATFORM_CORE_COUNT / U(2),
+		PLATFORM_CORE_COUNT / U(2),
+	};
+
+	return s32g_power_domain_tree_desc;
+}
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id, core_id;
+	u_register_t mpidr_priv = mpidr;
+
+	mpidr_priv &= MPIDR_AFFINITY_MASK;
+
+	if ((mpidr_priv & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0) {
+		return -1;
+	}
+
+	cluster_id = MPIDR_AFFLVL1_VAL(mpidr_priv);
+	cpu_id = MPIDR_AFFLVL0_VAL(mpidr_priv);
+
+	if ((cluster_id >= PLATFORM_CLUSTER_COUNT) ||
+	    (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)) {
+		return -1;
+	}
+
+	core_id = s32g2_core_pos_by_mpidr(mpidr_priv);
+	if (core_id >= PLATFORM_CORE_COUNT) {
+		return -1;
+	}
+
+	return (int)core_id;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return COUNTER_FREQUENCY;
+}
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
index f14a9e8..e717cbc 100644
--- a/plat/nxp/soc-lx2160a/ddr_fip.mk
+++ b/plat/nxp/soc-lx2160a/ddr_fip.mk
@@ -73,11 +73,11 @@
 
 ifneq (${GENERATE_COT},0)
 ddr_certificates: ${DDR_CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${DDR_CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "DDR certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${DDR_CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "DDR certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif
 endif
 endif
@@ -88,10 +88,10 @@
 
 ${BUILD_PLAT}/${DDR_FIP_NAME}: ${DDR_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_DDR_FIP_CMD})
-	${Q}${FIPTOOL} create ${DDR_FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${DDR_FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 fip_ddr: ${BUILD_PLAT}/${DDR_FIP_NAME}
diff --git a/plat/nxp/soc-lx2160a/ddr_sb.mk b/plat/nxp/soc-lx2160a/ddr_sb.mk
index c11651e..119fc08 100644
--- a/plat/nxp/soc-lx2160a/ddr_sb.mk
+++ b/plat/nxp/soc-lx2160a/ddr_sb.mk
@@ -36,7 +36,7 @@
 endif
 
 %.sb: %
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${DDR_INPUT_FILE}
 
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index 16187ef..ed95bc6 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -88,8 +88,8 @@
 #
 # We go v8.0 by default and will enable all features we want
 
-ARM_ARCH_MAJOR		:=	8
-ARM_ARCH_MINOR		:=	0
+ARM_ARCH_MAJOR		?=	8
+ARM_ARCH_MINOR		?=	0
 
 # 8.0
 ENABLE_FEAT_CSV2_2	:=	2
@@ -106,6 +106,7 @@
 # 8.4
 ENABLE_FEAT_SEL2	:=	2
 ENABLE_FEAT_DIT		:=	2
+ENABLE_TRF_FOR_NS	:=	2
 
 # 8.5
 ENABLE_FEAT_RNG		:=	2
@@ -114,6 +115,7 @@
 ENABLE_FEAT_SB		:=	0
 
 # 8.6
+ENABLE_FEAT_ECV		:=	2
 ENABLE_FEAT_FGT		:=	2
 
 # 8.7
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index cd83a98..d752b6c 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -173,7 +173,8 @@
 	 * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
 	 */
 	if (gpt_init_l0_tables(GPCCR_PPS_1TB, PLAT_QEMU_L0_GPT_BASE,
-			       PLAT_QEMU_L0_GPT_SIZE) < 0) {
+			       PLAT_QEMU_L0_GPT_SIZE +
+			       PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
 		ERROR("gpt_init_l0_tables() failed!\n");
 		panic();
 	}
@@ -217,7 +218,7 @@
 
 #if ENABLE_RME
 	/* BL2 runs in EL3 when RME enabled. */
-	assert(get_armv9_2_feat_rme_support() != 0U);
+	assert(is_feat_rme_present());
 	enable_mmu_el3(0);
 
 	/* Initialise and enable granule protection after MMU. */
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index eb88b12..0a70cc2 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -161,7 +161,7 @@
 
 unsigned int plat_get_syscnt_freq2(void)
 {
-	return SYS_COUNTER_FREQ_IN_TICKS;
+	return read_cntfrq_el0();
 }
 
 /*******************************************************************************
@@ -199,8 +199,6 @@
 
 void bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
 #if TRANSFER_LIST
 	if (bl31_tl) {
 		/*
@@ -210,4 +208,7 @@
 		memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
 	}
 #endif
+
+	console_flush();
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index cafee6f..068c69c 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <string.h>
+
 #include <platform_def.h>
 
 #include <arch_helpers.h>
@@ -226,46 +228,76 @@
 	uint64_t checksum;
 	uintptr_t base;
 	uint64_t size;
+	size_t num_banks = 1;
+	size_t num_consoles = 1;
 	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
 
 	assert(manifest != NULL);
 
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
-	manifest->plat_dram.num_banks = 1;
+	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
 
 	/*
-	 * Array ns_dram_banks[] follows ns_dram_info structure:
+	 * Boot manifest structure illustration:
 	 *
-	 * +-----------------------------------+
-	 * |  offset  |   field   |  comment   |
-	 * +----------+-----------+------------+
-	 * |    0     |  version  | 0x00000002 |
-	 * +----------+-----------+------------+
-	 * |    4     |  padding  | 0x00000000 |
-	 * +----------+-----------+------------+
-	 * |    8     | plat_data |    NULL    |
-	 * +----------+-----------+------------+
-	 * |    16    | num_banks |            |
-	 * +----------+-----------+            |
-	 * |    24    |   banks   | plat_dram  |
-	 * +----------+-----------+            |
-	 * |    32    | checksum  |            |
-	 * +----------+-----------+------------+
-	 * |    40    |  base 0   |            |
-	 * +----------+-----------+   bank[0]  |
-	 * |    48    |  size 0   |            |
-	 * +----------+-----------+------------+
+	 * +----------------------------------------+
+	 * |  offset  |   field      |  comment     |
+	 * +----------+--------------+--------------+
+	 * |    0     |  version     | 0x00000003   |
+	 * +----------+--------------+--------------+
+	 * |    4     |  padding     | 0x00000000   |
+	 * +----------+--------------+--------------+
+	 * |    8     | plat_data    |    NULL      |
+	 * +----------+--------------+--------------+
+	 * |    16    | num_banks    |              |
+	 * +----------+--------------+              |
+	 * |    24    |   banks      | plat_dram    |
+	 * +----------+--------------+              |
+	 * |    32    | checksum     |              |
+	 * +----------+--------------+--------------+
+	 * |    40    | num_consoles |              |
+	 * +----------+--------------+              |
+	 * |    48    | consoles     | plat_console |
+	 * +----------+--------------+              |
+	 * |    56    | checksum     |              |
+	 * +----------+--------------+--------------+
+	 * |    64    |  base 0      |              |
+	 * +----------+--------------+   bank[0]    |
+	 * |    72    |  size 0      |              |
+	 * +----------+--------------+--------------+
+	 * |    80    |  base        |              |
+	 * +----------+--------------+              |
+	 * |    88    |  map_pages   |              |
+	 * +----------+--------------+              |
+	 * |    96    |  name        |              |
+	 * +----------+--------------+  consoles[0] |
+	 * |   104    |  clk_in_hz   |              |
+	 * +----------+--------------+              |
+	 * |   112    |  baud_rate   |              |
+	 * +----------+--------------+              |
+	 * |   120    |  flags       |              |
+	 * +----------+--------------+--------------+
 	 */
 	bank_ptr = (struct ns_dram_bank *)
-			((uintptr_t)&manifest->plat_dram.checksum +
-			sizeof(manifest->plat_dram.checksum));
+		(((uintptr_t)manifest) + sizeof(*manifest));
+
+	console_ptr = (struct console_info *)
+		((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
 
 	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) * num_consoles) +
+		(sizeof(struct ns_dram_bank) * num_banks)) <= RMM_SHARED_SIZE);
 
 	/* Calculate checksum of plat_dram structure */
-	checksum = 1 + (uint64_t)bank_ptr;
+	checksum = num_banks + (uint64_t)bank_ptr;
 
 	base = NS_DRAM0_BASE;
 	size = NS_DRAM0_SIZE;
@@ -276,6 +308,26 @@
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;
 
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	memset((void *)console_ptr, 0, sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].map_pages = 1;
+	console_ptr[0].base = PLAT_QEMU_BOOT_UART_BASE;
+	console_ptr[0].clk_in_hz = PLAT_QEMU_BOOT_UART_CLK_IN_HZ;
+	console_ptr[0].baud_rate = PLAT_QEMU_CONSOLE_BAUDRATE;
+
+	strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
+
+	/* Update checksum */
+	checksum += console_ptr[0].base + console_ptr[0].map_pages +
+		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+
+	/* Checksum must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
 	return 0;
 }
 #endif  /* ENABLE_RME */
diff --git a/plat/qemu/common/qemu_plat_attest_token.c b/plat/qemu/common/qemu_plat_attest_token.c
index cf3376d..141ff57 100644
--- a/plat/qemu/common/qemu_plat_attest_token.c
+++ b/plat/qemu/common/qemu_plat_attest_token.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,96 +10,205 @@
 
 #include <plat/common/platform.h>
 
+/*
+ * This is the CBOR serialization of the CCA platform token described at
+ * https://git.trustedfirmware.org/TF-M/tf-m-tools/+/refs/heads/main/iat-verifier/tests/data/cca_example_platform_token.yaml
+ */
 static const uint8_t sample_platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
+	0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0,
+	0x59, 0x05, 0x7a, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+	0x61, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x43, 0x43, 0x41, 0x2d, 0x53, 0x53, 0x44, 0x2f,
+	0x31, 0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20,
+	0xb5, 0x97, 0x3c, 0xb6, 0x8b, 0xaa, 0x9f, 0xc5,
+	0x55, 0x58, 0x78, 0x6b, 0x7e, 0xc6, 0x7f, 0x69,
+	0xe4, 0x0d, 0xf5, 0xba, 0x5a, 0xa9, 0x21, 0xcd,
+	0x0c, 0x27, 0xf4, 0x05, 0x87, 0xa0, 0x11, 0xea,
+	0x19, 0x09, 0x5c, 0x58, 0x20, 0x7f, 0x45, 0x4c,
 	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e,
 	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
 	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
+	0x02, 0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b,
+	0x0a, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
+	0x12, 0x11, 0x10, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b,
+	0x1a, 0x19, 0x18, 0x19, 0x09, 0x61, 0x44, 0xcf,
+	0xcf, 0xcf, 0xcf, 0x19, 0x09, 0x5b, 0x19, 0x30,
+	0x03, 0x19, 0x09, 0x62, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0x19, 0x09, 0x60, 0x78,
+	0x3a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+	0x2f, 0x76, 0x65, 0x72, 0x61, 0x69, 0x73, 0x6f,
+	0x6e, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d,
+	0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x65,
+	0x72, 0x61, 0x69, 0x73, 0x6f, 0x6e, 0x2f, 0x76,
+	0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x19, 0x09, 0x5f, 0x8d, 0xa4,
+	0x01, 0x69, 0x52, 0x53, 0x45, 0x5f, 0x42, 0x4c,
+	0x31, 0x5f, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x9a, 0x27, 0x1f, 0x2a, 0x91, 0x6b, 0x0b,
+	0x6e, 0xe6, 0xce, 0xcb, 0x24, 0x26, 0xf0, 0xb3,
+	0x20, 0x6e, 0xf0, 0x74, 0x57, 0x8b, 0xe5, 0x5d,
+	0x9b, 0xc9, 0x4f, 0x6f, 0x3f, 0xe3, 0xab, 0x86,
+	0xaa, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x52, 0x53, 0x45,
+	0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x53, 0xc2, 0x34, 0xe5, 0xe8, 0x47,
+	0x2b, 0x6a, 0xc5, 0x1c, 0x1a, 0xe1, 0xca, 0xb3,
+	0xfe, 0x06, 0xfa, 0xd0, 0x53, 0xbe, 0xb8, 0xeb,
+	0xfd, 0x89, 0x77, 0xb0, 0x10, 0x65, 0x5b, 0xfd,
+	0xd3, 0xc3, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x65, 0x52, 0x53,
+	0x45, 0x5f, 0x53, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x11, 0x21, 0xcf, 0xcc, 0xd5, 0x91, 0x3f,
+	0x0a, 0x63, 0xfe, 0xc4, 0x0a, 0x6f, 0xfd, 0x44,
+	0xea, 0x64, 0xf9, 0xdc, 0x13, 0x5c, 0x66, 0x63,
+	0x4b, 0xa0, 0x01, 0xd1, 0x0b, 0xcf, 0x43, 0x02,
+	0xa2, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x15, 0x71, 0xb5, 0xec, 0x78, 0xbd, 0x68,
+	0x51, 0x2b, 0xf7, 0x83, 0x0b, 0xb6, 0xa2, 0xa4,
+	0x4b, 0x20, 0x47, 0xc7, 0xdf, 0x57, 0xbc, 0xe7,
+	0x9e, 0xb8, 0xa1, 0xc0, 0xe5, 0xbe, 0xa0, 0xa5,
+	0x01, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x10, 0x15, 0x9b, 0xaf, 0x26, 0x2b, 0x43,
+	0xa9, 0x2d, 0x95, 0xdb, 0x59, 0xda, 0xe1, 0xf7,
+	0x2c, 0x64, 0x51, 0x27, 0x30, 0x16, 0x61, 0xe0,
+	0xa3, 0xce, 0x4e, 0x38, 0xb2, 0x95, 0xa9, 0x7c,
+	0x58, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50,
+	0x5f, 0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x10, 0x12, 0x2e, 0x85, 0x6b, 0x3f,
+	0xcd, 0x49, 0xf0, 0x63, 0x63, 0x63, 0x17, 0x47,
+	0x61, 0x49, 0xcb, 0x73, 0x0a, 0x1a, 0xa1, 0xcf,
+	0xaa, 0xd8, 0x18, 0x55, 0x2b, 0x72, 0xf5, 0x6d,
+	0x6f, 0x68, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43,
+	0x50, 0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20,
+	0xf1, 0x4b, 0x49, 0x87, 0x90, 0x4b, 0xcb, 0x58,
+	0x14, 0xe4, 0x45, 0x9a, 0x05, 0x7e, 0xd4, 0xd2,
+	0x0f, 0x58, 0xa6, 0x33, 0x15, 0x22, 0x88, 0xa7,
+	0x61, 0x21, 0x4d, 0xcd, 0x28, 0x78, 0x0b, 0x56,
+	0x02, 0x58, 0x20, 0xaa, 0x67, 0xa1, 0x69, 0xb0,
+	0xbb, 0xa2, 0x17, 0xaa, 0x0a, 0xa8, 0x8a, 0x65,
+	0x34, 0x69, 0x20, 0xc8, 0x4c, 0x42, 0x44, 0x7c,
+	0x36, 0xba, 0x5f, 0x7e, 0xa6, 0x5f, 0x42, 0x2c,
+	0x1f, 0xe5, 0xd8, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x41,
+	0x50, 0x5f, 0x42, 0x4c, 0x33, 0x31, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x2e, 0x6d, 0x31, 0xa5,
+	0x98, 0x3a, 0x91, 0x25, 0x1b, 0xfa, 0xe5, 0xae,
+	0xfa, 0x1c, 0x0a, 0x19, 0xd8, 0xba, 0x3c, 0xf6,
+	0x01, 0xd0, 0xe8, 0xa7, 0x06, 0xb4, 0xcf, 0xa9,
+	0x66, 0x1a, 0x6b, 0x8a, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x63,
+	0x52, 0x4d, 0x4d, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0xa1, 0xfb, 0x50, 0xe6, 0xc8, 0x6f, 0xae,
+	0x16, 0x79, 0xef, 0x33, 0x51, 0x29, 0x6f, 0xd6,
+	0x71, 0x34, 0x11, 0xa0, 0x8c, 0xf8, 0xdd, 0x17,
+	0x90, 0xa4, 0xfd, 0x05, 0xfa, 0xe8, 0x68, 0x81,
+	0x64, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x69, 0x48, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x1a, 0x25, 0x24, 0x02,
+	0x97, 0x2f, 0x60, 0x57, 0xfa, 0x53, 0xcc, 0x17,
+	0x2b, 0x52, 0xb9, 0xff, 0xca, 0x69, 0x8e, 0x18,
+	0x31, 0x1f, 0xac, 0xd0, 0xf3, 0xb0, 0x6e, 0xca,
+	0xae, 0xf7, 0x9e, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x69,
+	0x46, 0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
+	0x47, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79, 0x63,
+	0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15,
+	0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d,
+	0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa,
+	0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20, 0x9a,
+	0x92, 0xad, 0xbc, 0x0c, 0xee, 0x38, 0xef, 0x65,
+	0x8c, 0x71, 0xce, 0x1b, 0x1b, 0xf8, 0xc6, 0x56,
+	0x68, 0xf1, 0x66, 0xbf, 0xb2, 0x13, 0x64, 0x4c,
+	0x89, 0x5c, 0xcb, 0x1a, 0xd0, 0x7a, 0x25, 0x06,
+	0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35, 0x36,
+	0xa4, 0x01, 0x6c, 0x54, 0x42, 0x5f, 0x46, 0x57,
+	0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05,
+	0x58, 0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53,
+	0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2,
+	0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60,
+	0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f,
+	0x7a, 0xa3, 0x02, 0x58, 0x20, 0x23, 0x89, 0x03,
+	0x18, 0x0c, 0xc1, 0x04, 0xec, 0x2c, 0x5d, 0x8b,
+	0x3f, 0x20, 0xc5, 0xbc, 0x61, 0xb3, 0x89, 0xec,
+	0x0a, 0x96, 0x7d, 0xf8, 0xcc, 0x20, 0x8c, 0xdc,
+	0x7c, 0xd4, 0x54, 0x17, 0x4f, 0x06, 0x67, 0x73,
+	0x68, 0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01,
+	0x6d, 0x53, 0x4f, 0x43, 0x5f, 0x46, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0xe6, 0xc2, 0x1e, 0x8d,
+	0x26, 0x0f, 0xe7, 0x18, 0x82, 0xde, 0xbd, 0xb3,
+	0x39, 0xd2, 0x40, 0x2a, 0x2c, 0xa7, 0x64, 0x85,
+	0x29, 0xbc, 0x23, 0x03, 0xf4, 0x86, 0x49, 0xbc,
+	0xe0, 0x38, 0x00, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0x58, 0x60, 0x21,
+	0x51, 0x20, 0x92, 0xd6, 0xd0, 0x2a, 0xe6, 0xbe,
+	0x2f, 0xe3, 0x93, 0x0e, 0xa5, 0x1f, 0xd6, 0x98,
+	0x96, 0x32, 0x24, 0x56, 0xe9, 0xdf, 0xc7, 0x32,
+	0x5e, 0x0b, 0x78, 0x68, 0xb6, 0x90, 0x73, 0x2a,
+	0x0c, 0x0f, 0x07, 0x77, 0xc1, 0x15, 0x40, 0x4b,
+	0xe1, 0xfc, 0x83, 0x9b, 0x7d, 0x30, 0x4f, 0x4f,
+	0xe6, 0xfa, 0x46, 0xae, 0x12, 0xa3, 0x08, 0x3a,
+	0xcf, 0x24, 0x06, 0x67, 0x91, 0x06, 0xbf, 0xae,
+	0x50, 0x31, 0x79, 0xdd, 0x50, 0x33, 0x49, 0x12,
+	0xbf, 0xc6, 0xda, 0x33, 0x6d, 0xd6, 0x18, 0x25,
+	0x43, 0x54, 0x4d, 0xb5, 0x88, 0xd6, 0xae, 0x67,
+	0x35, 0x7a, 0xfd, 0xb0, 0x5f, 0x95, 0xb7
 };
 
 /*
  * Get the hardcoded platform attestation token as QEMU does not support
- * RSS.
+ * RSE.
  */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
 				   uintptr_t hash, size_t hash_size)
diff --git a/plat/qemu/common/qemu_realm_attest_key.c b/plat/qemu/common/qemu_realm_attest_key.c
index abd569b..7da04d1 100644
--- a/plat/qemu/common/qemu_realm_attest_key.c
+++ b/plat/qemu/common/qemu_realm_attest_key.c
@@ -19,7 +19,7 @@
 
 /*
  * Get the hardcoded delegated realm attestation key as QEMU
- * does not support RSS.
+ * does not support RSE.
  */
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type)
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 4e0b50a..db9d65a 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -302,11 +302,6 @@
 #define PLAT_SDEI_SGI_PRIVATE		QEMU_IRQ_SEC_SGI_0
 
 /*
- * System counter
- */
-#define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
-
-/*
  * Maximum size of Event Log buffer used in Measured Boot Event Log driver
  */
 #define	PLAT_EVENT_LOG_MAX_SIZE		UL(0x400)
@@ -347,8 +342,11 @@
  * Tables
  */
 #define PLAT_QEMU_L0_GPT_BASE		(PLAT_QEMU_L1_GPT_BASE -	\
-					 PLAT_QEMU_L0_GPT_SIZE)
+					 (PLAT_QEMU_L0_GPT_SIZE +	\
+					  PLAT_QEMU_GPT_BITLOCK_SIZE))
 #define PLAT_QEMU_L0_GPT_SIZE		(2 * PAGE_SIZE)
+/* Two pages so the L0 GPT is naturally aligned.  */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE	(2 * PAGE_SIZE)
 
 #define PLAT_QEMU_L1_GPT_BASE		(SEC_DRAM_BASE + SEC_DRAM_SIZE - \
 					 PLAT_QEMU_L1_GPT_SIZE)
@@ -358,7 +356,8 @@
 
 #define RME_GPT_DRAM_BASE		PLAT_QEMU_L0_GPT_BASE
 #define RME_GPT_DRAM_SIZE		(PLAT_QEMU_L1_GPT_SIZE +	\
-					 PLAT_QEMU_L0_GPT_SIZE)
+					 PLAT_QEMU_L0_GPT_SIZE +	\
+					 PLAT_QEMU_GPT_BITLOCK_SIZE)
 
 #ifndef __ASSEMBLER__
 /* L0 table greater than 4KB must be naturally aligned */
diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h
index c108920..bcbea21 100644
--- a/plat/qemu/qemu/include/qemu_pas_def.h
+++ b/plat/qemu/qemu/include/qemu_pas_def.h
@@ -22,7 +22,7 @@
  *             | 1GB     |L0 GPT|ANY   |Flash            |
  *    00000000 |         |      |      |IO               |
  * ---------------------------------------------------------------------------
- *       224MB | 1KB     |L0 GPT|ANY   |Secure RAM (EL3) |
+ *       224MB | 1KB     |L1 GPT|ANY   |Secure RAM (EL3) |
  *    0e000000 |         |      |      |  (shared)       |
  * ---------------------------------------------------------------------------
  *             | 1MB-1KB |L1 GPT|ROOT  |Secure RAM (EL3) |
@@ -31,10 +31,10 @@
  *       225MB | 14MB    |L1 GPT|SECURE|Secure RAM       |
  *    0e100000 |         |      |      |  (EL2, EL1)     |
  * ---------------------------------------------------------------------------
- *             | 1MB+8KB |L1 GPT|ROOT  |L0 and L1 GPTs   |
- *    0eefe000 |         |      |      |                 |
+ *             | 2MB     |L1 GPT|ROOT  |L0 and L1 GPTs,  |
+ *    0edfc000 |  +16KB  |      |      | bitlocks        |
  * ---------------------------------------------------------------------------
- *       240MB | 800MB   |L0 GPT|ANY   |IO               |
+ *       240MB | 800MB   |L1 GPT|ANY   |IO               |
  *    0f000000 |         |      |      |                 |
  * ---------------------------------------------------------------------------
  *         1GB | 1MB     |L1 GPT|NS    |DRAM             |
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 436e425..066554a 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -79,12 +79,12 @@
     certificates: $(ROT_KEY)
 
     $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
     $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
@@ -226,14 +226,14 @@
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
 qemu_fw.bios: bl1 fip
-	$(ECHO) "  DD      $@"
-	$(Q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
-	$(Q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
+	$(s)echo "  DD      $@"
+	$(q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
+	$(q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
 
 qemu_fw.rom: qemu_fw.bios
-	$(ECHO) "  DD      $@"
-	$(Q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
-	$(Q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
+	$(s)echo "  DD      $@"
+	$(q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
+	$(q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
 
 ifneq (${BL33},)
 all: qemu_fw.bios qemu_fw.rom
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 077f7a4..76a4da1 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <tools_share/tbbr_oid.h>
@@ -20,16 +21,16 @@
 
 /* QEMU table with platform specific image IDs, names and PCRs */
 static const event_log_metadata_t qemu_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
-	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
-	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
-	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
-	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
-	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
 
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index e8f0344..d230095 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -266,11 +266,6 @@
 #define PLAT_QEMU_DT_BASE		NS_DRAM0_BASE
 #define PLAT_QEMU_DT_MAX_SIZE		0x100000
 
-/*
- * System counter
- */
-#define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
-
 #if SPM_MM
 #define PLAT_QEMU_SP_IMAGE_BASE		BL_RAM_BASE
 #define PLAT_QEMU_SP_IMAGE_SIZE		ULL(0x300000)
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index 535f0eb..83e66f3 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -30,6 +30,7 @@
 #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
 #define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200)
 #define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201)
+#define SIP_SVC_GET_CPU_TOPOLOGY SIP_FUNCTION_ID(202)
 #define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
 #define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
 
@@ -46,10 +47,24 @@
 	uint64_t addr_size;
 } memory_data;
 
+/*
+ * sockets: the number of sockets on sbsa-ref platform.
+ * clusters: the number of clusters in one socket.
+ * cores: the number of cores in one cluster.
+ * threads: the number of threads in one core.
+ */
+typedef struct {
+	uint32_t sockets;
+	uint32_t clusters;
+	uint32_t cores;
+	uint32_t threads;
+} cpu_topology;
+
 static struct {
 	uint32_t num_cpus;
 	uint32_t num_memnodes;
 	cpu_data cpu[PLATFORM_CORE_COUNT];
+	cpu_topology cpu_topo;
 	memory_data memory[PLAT_MAX_MEM_NODES];
 } dynamic_platform_info;
 
@@ -71,12 +86,46 @@
  * cope.
  */
 
+static void read_cpu_topology_from_dt(void *dtb)
+{
+	int node;
+
+	/*
+	 * QEMU gives us this DeviceTree node when we config:
+	 * -smp 16,sockets=2,clusters=2,cores=2,threads=2
+	 *
+	 * topology {
+	 *	threads = <0x02>;
+	 *	cores = <0x02>;
+	 *	clusters = <0x02>;
+	 *	sockets = <0x02>;
+	 * };
+	 */
+
+	node = fdt_path_offset(dtb, "/cpus/topology");
+	if (node > 0) {
+		dynamic_platform_info.cpu_topo.sockets =
+			fdt_read_uint32_default(dtb, node, "sockets", 0);
+		dynamic_platform_info.cpu_topo.clusters =
+			fdt_read_uint32_default(dtb, node, "clusters", 0);
+		dynamic_platform_info.cpu_topo.cores =
+			fdt_read_uint32_default(dtb, node, "cores", 0);
+		dynamic_platform_info.cpu_topo.threads =
+			fdt_read_uint32_default(dtb, node, "threads", 0);
+	}
+
+	INFO("Cpu topology: sockets: %d, clusters: %d, cores: %d, threads: %d\n",
+		dynamic_platform_info.cpu_topo.sockets,
+		dynamic_platform_info.cpu_topo.clusters,
+		dynamic_platform_info.cpu_topo.cores,
+		dynamic_platform_info.cpu_topo.threads);
+}
+
 void read_cpuinfo_from_dt(void *dtb)
 {
 	int node;
 	int prev;
 	int cpu = 0;
-	uint32_t nodeid = 0;
 	uintptr_t mpidr;
 
 	/*
@@ -118,14 +167,12 @@
 			panic();
 		}
 
-		if (fdt_getprop(dtb, node, "numa-node-id", NULL))  {
-			fdt_read_uint32(dtb, node, "numa-node-id", &nodeid);
-		}
-
-		dynamic_platform_info.cpu[cpu].nodeid = nodeid;
 		dynamic_platform_info.cpu[cpu].mpidr = mpidr;
+		dynamic_platform_info.cpu[cpu].nodeid =
+			fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
 
-		INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu, nodeid, mpidr);
+		INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
+				dynamic_platform_info.cpu[cpu].nodeid, mpidr);
 
 		cpu++;
 
@@ -135,6 +182,8 @@
 
 	dynamic_platform_info.num_cpus = cpu;
 	INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
+
+	read_cpu_topology_from_dt(dtb);
 }
 
 void read_meminfo_from_dt(void *dtb)
@@ -143,7 +192,6 @@
 	const char *type;
 	int prev, node;
 	int len;
-	uint32_t nodeid = 0;
 	uint32_t memnode = 0;
 	uint32_t higher_value, lower_value;
 	uint64_t cur_base, cur_size;
@@ -172,11 +220,8 @@
 
 		type = fdt_getprop(dtb, node, "device_type", &len);
 		if (type && strncmp(type, "memory", len) == 0) {
-			if (fdt_getprop(dtb, node, "numa-node-id", NULL)) {
-				fdt_read_uint32(dtb, node, "numa-node-id", &nodeid);
-			}
-
-			dynamic_platform_info.memory[memnode].nodeid = nodeid;
+			dynamic_platform_info.memory[memnode].nodeid =
+				fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
 
 			/*
 			 * Get the 'reg' property of this node and
@@ -274,10 +319,10 @@
 
 	node = fdt_path_offset(dtb, "/");
 	if (node >= 0) {
-		platform_version_major = fdt32_ld(fdt_getprop(dtb, node,
-							      "machine-version-major", NULL));
-		platform_version_minor = fdt32_ld(fdt_getprop(dtb, node,
-							      "machine-version-minor", NULL));
+		platform_version_major =
+			fdt_read_uint32_default(dtb, node, "machine-version-major", 0);
+		platform_version_minor =
+			fdt_read_uint32_default(dtb, node, "machine-version-minor", 0);
 	}
 }
 
@@ -354,6 +399,18 @@
 			SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
 		}
 
+	case SIP_SVC_GET_CPU_TOPOLOGY:
+		if (dynamic_platform_info.cpu_topo.cores > 0) {
+			SMC_RET5(handle, NULL,
+			dynamic_platform_info.cpu_topo.sockets,
+			dynamic_platform_info.cpu_topo.clusters,
+			dynamic_platform_info.cpu_topo.cores,
+			dynamic_platform_info.cpu_topo.threads);
+		} else {
+			/* we do not know topology so we report SMC as unknown */
+			SMC_RET1(handle, SMC_UNK);
+		}
+
 	case SIP_SVC_GET_MEMORY_NODE_COUNT:
 		SMC_RET2(handle, NULL, dynamic_platform_info.num_memnodes);
 
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 5718478..4813949 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -351,13 +351,13 @@
 LAYOUT_TOOLPATH ?= tools/renesas/rcar_layout_create
 
 clean_layout_tool:
-	@echo "clean layout tool"
-	${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+	$(s)echo "clean layout tool"
+	$(q)${MAKE} -C ${LAYOUT_TOOLPATH} clean
 
 .PHONY: rcar_layout_tool
 rcar_layout_tool:
-	@echo "generating layout srecs"
-	${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+	$(s)echo "generating layout srecs"
+	$(q)${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
 
 # srecords
 SREC_PATH	= ${BUILD_PLAT}
@@ -365,12 +365,16 @@
 BL31_ELF_SRC	= ${SREC_PATH}/bl31/bl31.elf
 
 clean_srecord:
-	@echo "clean bl2 and bl31 srecs"
+	$(s)echo "clean bl2 and bl31 srecs"
 	rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
 
+$(SREC_PATH)/bl2.srec: $(BL2_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl2.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
+
+$(SREC_PATH)/bl31.srec: $(BL31_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl31.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
+
 .PHONY: rcar_srecord
-rcar_srecord: $(BL2_ELF_SRC) $(BL31_ELF_SRC)
-	@echo "generating srec: ${SREC_PATH}/bl2.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 ${BL2_ELF_SRC}  ${SREC_PATH}/bl2.srec
-	@echo "generating srec: ${SREC_PATH}/bl31.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 ${BL31_ELF_SRC} ${SREC_PATH}/bl31.srec
+rcar_srecord: $(SREC_PATH)/bl2.srec $(SREC_PATH)/bl31.srec
diff --git a/plat/renesas/rzg/platform.mk b/plat/renesas/rzg/platform.mk
index 89ca227..5da6052 100644
--- a/plat/renesas/rzg/platform.mk
+++ b/plat/renesas/rzg/platform.mk
@@ -249,13 +249,13 @@
 LAYOUT_TOOLPATH ?= tools/renesas/rzg_layout_create
 
 clean_layout_tool:
-	@echo "clean layout tool"
-	${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+	$(s)echo "clean layout tool"
+	$(q)${MAKE} -C ${LAYOUT_TOOLPATH} clean
 
 .PHONY: rzg_layout_create
 rzg_layout_create:
-	@echo "generating layout srecs"
-	${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+	$(s)echo "generating layout srecs"
+	$(q)${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
 
 # srecords
 SREC_PATH	= ${BUILD_PLAT}
@@ -263,12 +263,16 @@
 BL31_ELF_SRC	= ${SREC_PATH}/bl31/bl31.elf
 
 clean_srecord:
-	@echo "clean bl2 and bl31 srecs"
+	$(s)echo "clean bl2 and bl31 srecs"
 	rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
 
+$(SREC_PATH)/bl2.srec: $(BL2_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl2.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
+
+$(SREC_PATH)/bl31.srec: $(BL31_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl31.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
+
 .PHONY: rzg_srecord
-rzg_srecord: $(BL2_ELF_SRC) $(BL31_ELF_SRC)
-	@echo "generating srec: ${SREC_PATH}/bl2.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 ${BL2_ELF_SRC}  ${SREC_PATH}/bl2.srec
-	@echo "generating srec: ${SREC_PATH}/bl31.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 ${BL31_ELF_SRC} ${SREC_PATH}/bl31.srec
+rzg_srecord: $(SREC_PATH)/bl2.srec $(SREC_PATH)/bl31.srec
diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c
index 9030951..25ee964 100644
--- a/plat/rockchip/common/aarch32/platform_common.c
+++ b/plat/rockchip/common/aarch32/platform_common.c
@@ -12,7 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 #include <plat_private.h>
 
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index c4c0dec..dde66aa 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -150,7 +150,12 @@
 	 * Per-CPU Secure entry point - resume or power up
 	 * --------------------------------------------------------------------
 	 */
+
+#if USE_COHERENT_MEM
 	.section .tzfw_coherent_mem, "a"
+#else
+	.data
+#endif
 	.align  3
 cpuson_entry_point:
 	.rept	PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index 81e8520..df51d89 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/cci.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 #include <plat_private.h>
 
@@ -42,9 +42,10 @@
 		mmap_add_region(ro_start, ro_start,			\
 				ro_limit - ro_start,			\
 				MT_MEMORY | MT_RO | MT_SECURE);		\
-		mmap_add_region(coh_start, coh_start,			\
-				coh_limit - coh_start,			\
-				MT_DEVICE | MT_RW | MT_SECURE);		\
+		if ((coh_limit - coh_start) != 0)			\
+			mmap_add_region(coh_start, coh_start,		\
+					coh_limit - coh_start,		\
+					MT_DEVICE | MT_RW | MT_SECURE);	\
 		mmap_add(plat_rk_mmap);					\
 		rockchip_plat_mmu_el##_el();				\
 		init_xlat_tables();					\
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 59db3d8..6214722 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.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
  */
@@ -93,10 +93,19 @@
 {
 	plat_cci_init();
 	plat_cci_enable();
+#if USE_COHERENT_MEM
 	plat_configure_mmu_el3(BL_CODE_BASE,
 			       BL_COHERENT_RAM_END - BL_CODE_BASE,
 			       BL_CODE_BASE,
 			       BL_CODE_END,
 			       BL_COHERENT_RAM_BASE,
 			       BL_COHERENT_RAM_END);
+#else
+	plat_configure_mmu_el3(BL31_START,
+			       BL31_END - BL31_START,
+			       BL_CODE_BASE,
+			       BL_CODE_END,
+			       0,
+			       0);
+#endif
 }
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 990d106..44a0c46 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
-#include <lib/psci/psci.h>
-#include <lib/xlat_tables/xlat_tables.h>
 #include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat_params.h>
 
 #define __sramdata __attribute__((section(".sram.data")))
@@ -49,7 +49,7 @@
 #endif
 
 #ifndef BITS_SHIFT
-#define BITS_SHIFT(bits, shift)	(bits << (shift))
+#define BITS_SHIFT(bits, shift)	((bits) << (shift))
 #endif
 
 #ifndef BITS_WITH_WMASK
@@ -135,7 +135,6 @@
 extern void *pmu_cpuson_entrypoint;
 extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
 extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
-
 extern const mmap_region_t plat_rk_mmap[];
 
 uint32_t rockchip_get_uart_base(void);
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index 2abcc18..e742591 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -6,6 +6,7 @@
 
 toolchains := rk3399-m0
 
+include ../../../../../make_helpers/common.mk
 include ../../../../../make_helpers/toolchain.mk
 
 # Cross Compile
@@ -18,13 +19,6 @@
 PLAT_M0		?= rk3399m0
 PLAT_M0_PMU	?= rk3399m0pmu
 
-ifeq (${V},0)
-	Q=@
-else
-	Q=
-endif
-export Q
-
 .SUFFIXES:
 
 INCLUDES		+= -Iinclude/ \
@@ -71,16 +65,16 @@
 -include $(patsubst %.o,%.d,$(OBJ))
 
 $(OBJ) : $(2)
-	@echo "  CC      $$<"
-	$$(Q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
+	$(s)echo "  CC      $$<"
+	$$(q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
 endef
 
 define MAKE_S
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 
 $(OBJ) : $(2)
-	@echo "  AS      $$<"
-	$$(Q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
+	$(s)echo "  AS      $$<"
+	$$(q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
 endef
 
 define MAKE_OBJS
@@ -105,16 +99,16 @@
 -include $(LINKERFILE).d
 
 $(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE)
-	@echo "  LD      $@"
-	$(Q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
+	$(s)echo "  LD      $@"
+	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
 
 %.bin : %.elf
-	@echo "  BIN     $@"
-	$(Q)$(rk3399-m0-oc) -O binary $< $@
+	$(s)echo "  BIN     $@"
+	$(q)$(rk3399-m0-oc) -O binary $< $@
 
 $(ELF_PMU) : $(OBJS_COMMON) $(OBJS_PMU) $(LINKERFILE)
-	@echo "  LD      $@"
-	$(Q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
+	$(s)echo "  LD      $@"
+	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
 
 $(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES_COMMON),$(1)))
 $(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES),$(1)))
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
new file mode 100644
index 0000000..26f3313
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* convoluted way to make sure that the define is pasted just the right way */
+.macro INCBIN file sym sec
+	.section \sec
+	.global \sym
+	.type \sym, @object
+	.align 4
+\sym :
+	.incbin \file
+	.size \sym , .-\sym
+	.global \sym\()_end
+\sym\()_end :
+.endm
+
+INCBIN ""RK3399M0FW"", "rk3399m0_bin", ".sram.incbin"
+INCBIN ""RK3399M0PMUFW"", "rk3399m0pmu_bin", ".pmusram.incbin"
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
deleted file mode 100644
index 25596b1..0000000
--- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* convoluted way to make sure that the define is pasted just the right way */
-#define INCBIN(file, sym, sec) \
-	__asm__( \
-		".section " sec "\n" \
-		".global " sym "\n" \
-		".type " sym ", %object\n" \
-		".align 4\n" \
-		sym ":\n" \
-		".incbin \"" file "\"\n" \
-		".size " sym ", .-" sym "\n" \
-		".global " sym "_end\n" \
-		sym "_end:\n" \
-	)
-
-INCBIN(RK3399M0FW, "rk3399m0_bin", ".sram.incbin");
-INCBIN(RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin");
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index aba67c2..2394dce 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -61,7 +61,7 @@
 			${RK_PLAT_SOC}/plat_sip_calls.c			\
 			${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c	\
 			${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
-			${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c		\
+			${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S		\
 			${RK_PLAT_SOC}/drivers/pmu/m0_ctl.c		\
 			${RK_PLAT_SOC}/drivers/pwm/pwm.c		\
 			${RK_PLAT_SOC}/drivers/secure/secure.c		\
@@ -102,7 +102,7 @@
 # CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin
 export CCACHE_EXTRAFILES
 ${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW)
-${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW)
+${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S: $(RK3399M0FW)
 
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT}))
 .PHONY: $(RK3399M0FW)
diff --git a/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..8ddea0e
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.macro	func_rockchip_clst_warmboot
+	/* Nothing to do for rk3568 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+	/* Nothing to do for rk3568 */
+.endm
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.c b/plat/rockchip/rk3568/drivers/pmu/pmu.c
new file mode 100644
index 0000000..970caec
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * The power management unit (PMU) is designed for controlling power resources.
+ * The PMU is dedicated for managing the power of the whole chip.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bakery_lock.h>
+#include <cortex_a55.h>
+#include <dsu_def.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_private.h>
+#include <soc.h>
+
+/*
+ * Use this macro to instantiate lock before it is used in below
+ * rockchip_pd_lock_xxx() macros
+ */
+DECLARE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t grf_ddr_con3;
+static struct psram_data_t *psram_sleep_cfg =
+	(struct psram_data_t *)&sys_sleep_flag_sram;
+
+/*
+ * These are wrapper macros to the powe domain Bakery Lock API.
+ */
+#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
+#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
+#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+	uint64_t ctrl;
+
+	__asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl));
+	ctrl |= 0x01;
+	__asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl));
+	isb();
+
+	while (1)
+		wfi();
+}
+
+static void pmu_pmic_sleep_mode_config(void)
+{
+	/* pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0),  WRITE_MASK_SET(BIT(7)));
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN);
+}
+
+static void pmu_wakeup_source_config(void)
+{
+	/* config wakeup source */
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN)));
+
+	INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n",
+	     mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON);
+}
+
+static void pmu_pll_powerdown_config(void)
+{
+	uint32_t pll_id;
+
+	/* PLL power down by PMU */
+	pll_id = BIT(APLL_PD_ENA) |
+		BIT(CPLL_PD_ENA) |
+		BIT(GPLL_PD_ENA) |
+		BIT(MPLL_PD_ENA) |
+		BIT(NPLL_PD_ENA) |
+		BIT(HPLL_PD_ENA) |
+		BIT(PPLL_PD_ENA) |
+		BIT(VPLL_PD_ENA);
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id));
+	INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n",
+	     PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+}
+
+static void pmu_stable_count_config(void)
+{
+	mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180);
+}
+
+static void pmu_pd_powerdown_config(void)
+{
+	uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0;
+	uint32_t pmu_bus_idle_con1;
+
+	/* Pd power down by PMU */
+	pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST);
+	pwr_gate_con = ~pwr_dwn_st & 0x3ff;
+
+	if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU);
+	}
+
+	if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU);
+	}
+
+	if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC);
+	}
+
+	if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC);
+	}
+
+	if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA);
+	}
+
+	if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI);
+	}
+
+	if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO);
+	}
+
+	if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE);
+	}
+
+	pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) |
+		BIT(IDLE_REQ_MSCH) |
+		BIT(IDLE_REQ_PHP) |
+		BIT(IDLE_REQ_SECURE_FLASH) |
+		BIT(IDLE_REQ_PERIMID) |
+		BIT(IDLE_REQ_USB) |
+		BIT(IDLE_REQ_BUS);
+
+	/* Enable power down PD by PMU automatically */
+	pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) |
+		BIT(PD_NPU_DWN_ENA) |
+		BIT(PD_VPU_DWN_ENA) |
+		BIT(PD_RKVENC_DWN_ENA) |
+		BIT(PD_RKVDEC_DWN_ENA) |
+		BIT(PD_RGA_DWN_ENA) |
+		BIT(PD_VI_DWN_ENA) |
+		BIT(PD_VO_DWN_ENA) |
+		BIT(PD_PIPE_DWN_ENA)) << 16;
+
+	pmu_bus_idle_con1 = 0;
+
+	mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0));
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1));
+
+	/* When perform idle operation,
+	 * corresponding clock can be opened or gated automatically
+	 */
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+	mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA)));
+
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS)));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS)));
+
+	INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n",
+	     PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST));
+	INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n",
+	     PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON));
+	INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n",
+	     PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0));
+	INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n",
+	     PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1));
+	INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n",
+	     PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_ddr_suspend_config(void)
+{
+	uint32_t pmu_ddr_pwr_con;
+
+	pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) |
+		BIT(DDRIO_RET_ENTER_ENA) |
+		BIT(DDRIO_RET_EXIT_ENA) |
+		BIT(DDRPHY_AUTO_GATING_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con));
+	/* DPLL power down by PMU */
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA)));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS)));
+
+	grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3);
+
+	mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020);
+
+	pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON);
+
+	INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n",
+	     PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+	INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n",
+	     PMU_DDR_PWR_CON, pmu_ddr_pwr_con);
+
+	if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) {
+		INFO("\t DDR_SREF_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) {
+		INFO("\t DDRIO_RET_ENTER_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) {
+		INFO("\t DDRIO_RET_EXIT_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) {
+		INFO("\t DDRPHY_AUTO_GATING_ENA\n");
+	}
+}
+
+static void pmu_dsu_suspend_config(void)
+{
+	uint32_t pmu_dsu_pwr_con;
+
+	pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS)));
+	dsu_pwr_dwn();
+
+	INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n",
+	     PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON));
+	INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n",
+	     PMU_CLUSTER_IDLE_CON,  mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON));
+	INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n",
+	     PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_cpu_powerdown_config(void)
+{
+	uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass;
+
+	pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+	cpus_state = pmu_cluster_pwr_st & 0x0f;
+
+	cpus_bypass = cpus_state << CPU0_BYPASS;
+
+	INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n",
+	     PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass);
+
+	INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n",
+	     PMU_PWR_CON,  mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pvtm_32k_config(void)
+{
+	uint32_t pmu_cru_pwr_con;
+	uint32_t pvtm_freq_khz, pvtm_div;
+
+	mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000);
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002);
+	dsb();
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000);
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT);
+	dsb();
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001);
+	dsb();
+
+	while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) {
+		;
+	}
+
+	dsb();
+	while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) {
+		;
+	}
+
+	pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 +
+		PVTM_CALC_CNT / 2) / PVTM_CALC_CNT;
+	pvtm_div = (pvtm_freq_khz + 16) / 32;
+
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div);
+
+	mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000);
+
+	pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10);
+
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+	INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+	     PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_cru_suspendmode_config(void)
+{
+	uint32_t pmu_cru_pwr_con;
+
+	pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+	INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+	     PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_suspend_cru_fsm(void)
+{
+	pmu_pmic_sleep_mode_config();
+
+	/* Global interrupt disable */
+	mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE);
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS);
+
+	pmu_stable_count_config();
+	pmu_wakeup_source_config();
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000);
+	/* default cru config */
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA)));
+
+	pmu_cru_suspendmode_config();
+	pmu_cpu_powerdown_config();
+	pmu_pll_powerdown_config();
+	pmu_pd_powerdown_config();
+	pmu_ddr_suspend_config();
+	pmu_dsu_suspend_config();
+	pvtm_32k_config();
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001);
+}
+
+static void pmu_reinit(void)
+{
+	mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	psram_sleep_cfg->pm_flag = 0;
+	flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+			   sizeof(uint32_t));
+	pmu_suspend_cru_fsm();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	pmu_reinit();
+	plat_rockchip_gic_cpuif_enable();
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+	flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+			   sizeof(uint32_t));
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+	uint32_t apm_value, offset, idx;
+
+	apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk);
+
+	if (pd_cfg == core_pwr_wfi_int) {
+		apm_value |= BIT(core_pm_int_wakeup_en);
+	}
+
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BITS_WITH_WMASK(apm_value, 0xf, offset));
+	dsb();
+
+	return 0;
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	uint32_t offset, idx;
+
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      WMSK_BIT(core_pm_en + offset));
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset));
+	dsb();
+
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+
+	cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+	cpuson_entry_point[cpu_id] = entrypoint;
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+
+	cpus_power_domain_on(cpu_id);
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_off(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	cpus_power_domain_off(cpu_id,
+			      core_pwr_wfi);
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	uint32_t offset, idx;
+
+	/* Disable core_pm */
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BITS_WITH_WMASK(0, 0xf, offset));
+
+	return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+	uint32_t tmp;
+
+	cpus_power_domain_off(1, 0);
+	cpus_power_domain_off(2, 0);
+	cpus_power_domain_off(3, 0);
+
+	mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf);
+	mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi);
+	sev();
+
+	do {
+		tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+	} while ((tmp & 0xe) != 0xe);
+}
+
+void plat_rockchip_pmu_init(void)
+{
+	uint32_t cpu;
+
+	rockchip_pd_lock_init();
+	nonboot_cpus_off();
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+		cpuson_flags[cpu] = PMU_CPU_HOTPLUG;
+
+	psram_sleep_cfg->ddr_data = (uint64_t)0;
+	psram_sleep_cfg->sp = PSRAM_SP_TOP;
+	psram_sleep_cfg->ddr_flag = 0x00;
+	psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+	/*
+	 * When perform idle operation, corresponding clock can be
+	 * opened or gated automatically.
+	 */
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+	/* grf_con_pmic_sleep_sel
+	 * pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080);
+
+	/*
+	 * force jtag control
+	 * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status
+	 * 1'b0: CPU debug port IO mux IS controlled by GRF
+	 */
+	mmio_write_32(SGRF_BASE + 0x008, 0x00100000);
+
+	/*
+	 * remap
+	 * 2'b00: Boot from boot-rom.
+	 * 2'b01: Boot from pmu mem.
+	 * 2'b10: Boot from sys mem.
+	 */
+	mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800);
+}
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.h b/plat/rockchip/rk3568/drivers/pmu/pmu.h
new file mode 100644
index 0000000..5821514
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#define PMU_VERSION			0x0000
+#define PMU_PWR_CON			0x0004
+#define PMU_MAIN_PWR_STATE		0x0008
+#define PMU_INT_MASK_CON		0x000C
+#define PMU_WAKEUP_INT_CON		0x0010
+#define PMU_WAKEUP_INT_ST		0x0014
+#define PMU_WAKEUP_EDGE_CON		0x0018
+#define PMU_WAKEUP_EDGE_ST		0x001C
+#define PMU_BUS_IDLE_CON0		0x0040
+#define PMU_BUS_IDLE_CON1		0x0044
+#define PMU_BUS_IDLE_SFTCON0		0x0050
+#define PMU_BUS_IDLE_SFTCON1		0x0054
+#define PMU_BUS_IDLE_ACK		0x0060
+#define PMU_BUS_IDLE_ST			0x0068
+#define PMU_NOC_AUTO_CON0		0x0070
+#define PMU_NOC_AUTO_CON1		0x0074
+#define PMU_DDR_PWR_CON			0x0080
+#define PMU_DDR_PWR_SFTCON		0x0084
+#define PMU_DDR_PWR_STATE		0x0088
+#define PMU_DDR_PWR_ST			0x008C
+#define PMU_PWR_GATE_CON		0x0090
+#define PMU_PWR_GATE_STATE		0x0094
+#define PMU_PWR_DWN_ST			0x0098
+#define PMU_PWR_GATE_SFTCON		0x00A0
+#define PMU_VOL_GATE_SFTCON		0x00A8
+#define PMU_CRU_PWR_CON			0x00B0
+#define PMU_CRU_PWR_SFTCON		0x00B4
+#define PMU_CRU_PWR_STATE		0x00B8
+#define PMU_PLLPD_CON			0x00C0
+#define PMU_PLLPD_SFTCON		0x00C4
+#define PMU_INFO_TX_CON			0x00D0
+#define PMU_DSU_STABLE_CNT		0x0100
+#define PMU_PMIC_STABLE_CNT		0x0104
+#define PMU_OSC_STABLE_CNT		0x0108
+#define PMU_WAKEUP_RSTCLR_CNT		0x010C
+#define PMU_PLL_LOCK_CNT		0x0110
+#define PMU_DSU_PWRUP_CNT		0x0118
+#define PMU_DSU_PWRDN_CNT		0x011C
+#define PMU_GPU_VOLUP_CNT		0x0120
+#define PMU_GPU_VOLDN_CNT		0x0124
+#define PMU_WAKEUP_TIMEOUT_CNT		0x0128
+#define PMU_PWM_SWITCH_CNT		0x012C
+#define PMU_DBG_RST_CNT			0x0130
+#define PMU_SYS_REG0			0x0180
+#define PMU_SYS_REG1			0x0184
+#define PMU_SYS_REG2			0x0188
+#define PMU_SYS_REG3			0x018C
+#define PMU_SYS_REG4			0x0190
+#define PMU_SYS_REG5			0x0194
+#define PMU_SYS_REG6			0x0198
+#define PMU_SYS_REG7			0x019C
+#define PMU_DSU_PWR_CON			0x0300
+#define PMU_DSU_PWR_SFTCON		0x0304
+#define PMU_DSU_AUTO_CON		0x0308
+#define PMU_DSU_PWR_STATE		0x030C
+#define PMU_CPU_AUTO_PWR_CON0		0x0310
+#define PMU_CPU_AUTO_PWR_CON1		0x0314
+#define PMU_CPU_PWR_SFTCON		0x0318
+#define PMU_CLUSTER_PWR_ST		0x031C
+#define PMU_CLUSTER_IDLE_CON		0x0320
+#define PMU_CLUSTER_IDLE_SFTCON		0x0324
+#define PMU_CLUSTER_IDLE_ACK		0x0328
+#define PMU_CLUSTER_IDLE_ST		0x032C
+#define PMU_DBG_PWR_CON			0x0330
+
+/* PMU_SGRF */
+#define PMU_SGRF_SOC_CON1		0x0004
+#define PMU_SGRF_FAST_BOOT_ADDR		0x0180
+
+/* sys grf */
+#define GRF_CPU_STATUS0			0x0420
+
+#define CRU_SOFTRST_CON00		0x0400
+
+#define CORES_PM_DISABLE		0x0
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+
+#define PMUSGRF_SOC_CON(i)		((i) * 0x4)
+/* Needed aligned 16 bytes for sp stack top */
+#define PSRAM_SP_TOP			((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define PMU_CPUAPM_CON(cpu)		(0x0310 + (cpu) * 0x4)
+
+#define PMIC_SLEEP_FUN			0x07000100
+#define PMIC_SLEEP_GPIO			0x07000000
+#define GPIO_SWPORT_DR_L		0x0000
+#define GPIO_SWPORT_DR_H		0x0004
+#define GPIO_SWPORT_DDR_L		0x0008
+#define GPIO_SWPORT_DDR_H		0x000C
+#define PMIC_SLEEP_HIGH_LEVEL		0x00040004
+#define PMIC_SLEEP_LOW_LEVEL		0x00040000
+#define PMIC_SLEEP_OUT			0x00040004
+#define CPUS_BYPASS			0x007e4f7e
+#define CLB_INT_DISABLE			0x00010001
+#define WRITE_MASK_SET(value)		((value << 16) | value)
+#define WRITE_MASK_CLR(value)		((value << 16))
+
+enum pmu_cores_pm_by_wfi {
+	core_pm_en = 0,
+	core_pm_int_wakeup_en,
+	core_pm_int_wakeup_glb_msk,
+	core_pm_sft_wakeup_en,
+};
+
+/* The ways of cores power domain contorlling */
+enum cores_pm_ctr_mode {
+	core_pwr_pd = 0,
+	core_pwr_wfi = 1,
+	core_pwr_wfi_int = 2
+};
+
+/* PMU_PWR_DWN_ST */
+enum pmu_pdid {
+	PD_GPU,
+	PD_NPU,
+	PD_VPU,
+	PD_RKVENC,
+	PD_RKVDEC,
+	PD_RGA,
+	PD_VI,
+	PD_VO,
+	PD_PIPE,
+	PD_CENTER,
+	PD_END
+};
+
+/* PMU_PWR_CON */
+enum pmu_pwr_con {
+	POWRMODE_EN,
+	DSU_BYPASS,
+	BUS_BYPASS = 4,
+	DDR_BYPASS,
+	PWRDN_BYPASS,
+	CRU_BYPASS,
+	CPU0_BYPASS,
+	CPU1_BYPASS,
+	CPU2_BYPASS,
+	CPU3_BYPASS,
+	PMU_SLEEP_LOW = 15,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu_cru_pwr_con {
+	ALIVE_32K_ENA,
+	OSC_DIS_ENA,
+	WAKEUP_RST_ENA,
+	INPUT_CLAMP_ENA,
+
+	ALIVE_OSC_ENA,
+	POWER_OFF_ENA,
+	PWM_SWITCH_ENA,
+	PWM_GPIO_IOE_ENA,
+
+	PWM_SWITCH_IOUT,
+	PD_BUS_CLK_SRC_GATE_ENA,
+	PD_PERI_CLK_SRC_GATE_ENA,
+	PD_PMU_CLK_SRC_GATE_ENA,
+
+	PMUMEM_CLK_SRC_GATE_ENA,
+	PWR_CON_END
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+	APLL_PD_ENA,
+	DPLL_PD_ENA,
+	CPLL_PD_ENA,
+	GPLL_PD_ENA,
+	MPLL_PD_ENA,
+	NPLL_PD_ENA,
+	HPLL_PD_ENA,
+	PPLL_PD_ENA,
+	VPLL_PD_ENA,
+	PLL_PD_END
+};
+
+/* PMU_DSU_PWR_CON */
+enum pmu_dsu_pwr_con {
+	DSU_PWRDN_ENA = 2,
+	DSU_PWROFF_ENA,
+	DSU_RET_ENA = 6,
+	CLUSTER_CLK_SRC_GATE_ENA,
+	DSU_PWR_CON_END
+};
+
+enum cpu_power_state {
+	CPU_POWER_ON,
+	CPU_POWER_OFF,
+	CPU_EMULATION_OFF,
+	CPU_RETENTION,
+	CPU_DEBUG
+};
+
+enum dsu_power_state {
+	DSU_POWER_ON,
+	CLUSTER_TRANSFER_IDLE,
+	DSU_POWER_DOWN,
+	DSU_OFF,
+	DSU_WAKEUP,
+	DSU_POWER_UP,
+	CLUSTER_TRANSFER_RESUME,
+	DSU_FUNCTION_RETENTION
+};
+
+enum pmu_wakeup_int_con {
+	WAKEUP_CPU0_INT_EN,
+	WAKEUP_CPU1_INT_EN,
+	WAKEUP_CPU2_INT_EN,
+	WAKEUP_CPU3_INT_EN,
+	WAKEUP_GPIO0_INT_EN,
+	WAKEUP_UART0_EN,
+	WAKEUP_SDMMC0_EN,
+	WAKEUP_SDMMC1_EN,
+	WAKEUP_SDMMC2_EN,
+	WAKEUP_USB_EN,
+	WAKEUP_PCIE_EN,
+	WAKEUP_VAD_EN,
+	WAKEUP_TIMER_EN,
+	WAKEUP_PWM0_EN,
+	WAKEUP_TIMEROUT_EN,
+	WAKEUP_MCU_SFT_EN,
+};
+
+enum pmu_wakeup_int_st {
+	WAKEUP_CPU0_INT_ST,
+	WAKEUP_CPU1_INT_ST,
+	WAKEUP_CPU2_INT_ST,
+	WAKEUP_CPU3_INT_ST,
+	WAKEUP_GPIO0_INT_ST,
+	WAKEUP_UART0_ST,
+	WAKEUP_SDMMC0_ST,
+	WAKEUP_SDMMC1_ST,
+	WAKEUP_SDMMC2_ST,
+	WAKEUP_USB_ST,
+	WAKEUP_PCIE_ST,
+	WAKEUP_VAD_ST,
+	WAKEUP_TIMER_ST,
+	WAKEUP_PWM0_ST,
+	WAKEUP_TIMEOUT_ST,
+	WAKEUP_SYS_INT_ST,
+};
+
+enum pmu_bus_idle_con0 {
+	IDLE_REQ_MSCH,
+	IDLE_REQ_GPU,
+	IDLE_REQ_NPU,
+	IDLE_REQ_VI,
+	IDLE_REQ_VO,
+	IDLE_REQ_RGA,
+	IDLE_REQ_VPU,
+	IDLE_REQ_RKVENC,
+	IDLE_REQ_RKVDEC,
+	IDLE_REQ_GIC_AUDIO,
+	IDLE_REQ_PHP,
+	IDLE_REQ_PIPE,
+	IDLE_REQ_SECURE_FLASH,
+	IDLE_REQ_PERIMID,
+	IDLE_REQ_USB,
+	IDLE_REQ_BUS,
+};
+
+enum pmu_bus_idle_con1 {
+	IDLE_REQ_TOP1,
+	IDLE_REQ_TOP2,
+	IDLE_REQ_PMU,
+};
+
+enum pmu_pwr_gate_con {
+	PD_GPU_DWN_ENA,
+	PD_NPU_DWN_ENA,
+	PD_VPU_DWN_ENA,
+	PD_RKVENC_DWN_ENA,
+
+	PD_RKVDEC_DWN_ENA,
+	PD_RGA_DWN_ENA,
+	PD_VI_DWN_ENA,
+	PD_VO_DWN_ENA,
+
+	PD_PIPE_DWN_ENA,
+	PD_CENTER_DWN_ENA,
+};
+
+enum pmu_ddr_pwr_con {
+	DDR_SREF_ENA,
+	DDRIO_RET_ENTER_ENA,
+	DDRIO_RET_EXIT_ENA = 2,
+	DDRPHY_AUTO_GATING_ENA = 4,
+};
+
+enum pmu_vol_gate_soft_con {
+	VD_GPU_ENA,
+	VD_NPU_ENA,
+};
+
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.c b/plat/rockchip/rk3568/drivers/soc/soc.c
new file mode 100644
index 0000000..2af3887
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(RKFPGA_DEV_RNG0_BASE, RKFPGA_DEV_RNG0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+
+	{ 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+static void secure_timer_init(void)
+{
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_DIS);
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+static void sgrf_init(void)
+{
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(0), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(1), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(2), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(3), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(4), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(5), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(6), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(7), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(8), 0xffff0000);
+
+	mmio_write_32(DDRSGRF_BASE + FIREWALL_DDR_FW_DDR_CON_REG, 0xffff0000);
+}
+
+static void set_pll_slow_mode(uint32_t clk_pll)
+{
+	mmio_write_32(CRU_BASE + CRU_MODE_CON00, 0x03 << (16 + clk_pll * 2));
+}
+
+static void __dead2 soc_global_soft_reset(void)
+{
+	set_pll_slow_mode(CLK_CPLL);
+	set_pll_slow_mode(CLK_GPLL);
+	set_pll_slow_mode(CLK_NPLL);
+	set_pll_slow_mode(CLK_VPLL);
+	set_pll_slow_mode(CLK_USBPLL);
+	set_pll_slow_mode(CLK_APLL);
+	mmio_write_32(PMUCRU_BASE + PMUCRU_MODE_CON00, 0x000f0000);
+
+	dsb();
+	mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
+	/*
+	 * Maybe the HW needs some times to reset the system,
+	 * so we do not hope the core to excute valid codes.
+	 */
+	while (1) {
+		;
+	}
+}
+
+static void rockchip_system_reset_init(void)
+{
+	mmio_write_32(GRF_BASE + 0x0508, 0x00100010);
+	mmio_write_32(CRU_BASE + 0x00dc, 0x01030103);
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	soc_global_soft_reset();
+}
+
+void plat_rockchip_soc_init(void)
+{
+	secure_timer_init();
+	sgrf_init();
+	rockchip_system_reset_init();
+	NOTICE("BL31: Rockchip release version: v%d.%d\n",
+		MAJOR_VERSION, MINOR_VERSION);
+}
+
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.h b/plat/rockchip/rk3568/drivers/soc/soc.h
new file mode 100644
index 0000000..41a2586
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+#define RKFPGA_DEV_RNG0_BASE		0xf8000000
+#define RKFPGA_DEV_RNG0_SIZE		0x07fff000
+
+#define CRU_MODE_CON00			0x00c0
+#define PMUCRU_MODE_CON00		0x0080
+
+#define CRU_GLB_SRST_FST		0x00d4
+#define GLB_SRST_FST_CFG_VAL		0xfdb9
+
+#define PMU_GRF_GPIO0A_IOMUX_L		0x00
+#define PMU_GRF_SOC_CON(i)		(0x0100 + i * 4)
+
+#define CRU_SOFTRST_CON			0x300
+#define CRU_SOFTRSTS_CON(n)		(CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT		26
+#define GRF_DDR_CON3			0x000c
+#define SGRF_FIREWALL_SLV_CON(i)	(0x240 + i * 4)
+
+#define FIREWALL_DDR_FW_DDR_CON_REG	0x80
+
+ /* low 32 bits */
+#define TIMER_LOAD_COUNT0		0x00
+#define TIMER_LOAD_COUNT1		0x04
+#define TIMER_CURRENT_VALUE0		0x08
+#define TIMER_CURRENT_VALUE1		0x0c
+#define TIMER_CONTROL_REG		0x10
+#define TIMER_INTSTATUS			0x18
+#define TIMER_DIS			0x0
+#define TIMER_EN			0x1
+#define STIMER0_CHN_BASE(n)		(STIME_BASE + 0x20 * (n))
+
+#define PMU_GRF_GPIO0B_IOMUX_L		0x0008
+#define PMUCRU_PMUCLKSEL_CON00		0x0100
+#define PMUPVTM_BASE			0xfdd80000
+#define PVTM_CON0			0x0004
+#define PVTM_CON1			0x0008
+#define PVTM_STATUS0			0x0080
+#define PVTM_STATUS1			0x0084
+#define PMUCRU_PMUGATE_CON01		0x0184
+#define PVTM_CALC_CNT			0x200
+#define PMU_GRF_DLL_CON0		0x0180
+
+enum cru_mode_con00 {
+	CLK_APLL,
+	CLK_DPLL,
+	CLK_CPLL,
+	CLK_GPLL,
+	CLK_REVSERVED,
+	CLK_NPLL,
+	CLK_VPLL,
+	CLK_USBPLL,
+};
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3568/include/plat.ld.S b/plat/rockchip/rk3568/include/plat.ld.S
new file mode 100644
index 0000000..ddd584d
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat.ld.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+MEMORY {
+    PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+	. = PMUSRAM_BASE;
+
+	/*
+	 * pmu_cpuson_entrypoint request address
+	 * align 64K when resume, so put it in the
+	 * start of pmusram
+	 */
+	.pmusram : {
+		ASSERT(. == ALIGN(64 * 1024),
+			".pmusram.entry request 64K aligned.");
+		KEEP(*(.pmusram.entry))
+
+		__bl31_pmusram_text_start = .;
+		*(.pmusram.text)
+		*(.pmusram.rodata)
+		__bl31_pmusram_text_end = .;
+		__bl31_pmusram_data_start = .;
+		*(.pmusram.data)
+		__bl31_pmusram_data_end = .;
+	} >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3568/include/plat_sip_calls.h b/plat/rockchip/rk3568/include/plat_sip_calls.h
new file mode 100644
index 0000000..6acb876
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS	0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3568/include/platform_def.h b/plat/rockchip/rk3568/include/platform_def.h
new file mode 100644
index 0000000..19363a4
--- /dev/null
+++ b/plat/rockchip/rk3568/include/platform_def.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3568_def.h>
+
+#define DEBUG_XLAT_TABLE 0
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+#define PLATFORM_SYSTEM_COUNT		1
+#define PLATFORM_CLUSTER_COUNT		1
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+
+#define PLATFORM_CLUSTER1_CORE_COUNT	0
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT +	\
+					 PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT +	\
+					 PLATFORM_CLUSTER_COUNT +	\
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT	8
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE		1
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		2
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 512KB */
+#define TZRAM_BASE		(0x0)
+#define TZRAM_SIZE		(0x100000)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted RAM
+ */
+#define BL31_BASE		(TZRAM_BASE + 0x40000)
+#define BL31_LIMIT		(TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+
+#define ADDR_SPACE_SIZE			(1ull << 32)
+#define MAX_XLAT_TABLES			18
+#define MAX_MMAP_REGIONS		27
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * 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. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT	6
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Define GICD and GICC and GICR base
+ */
+#define PLAT_RK_GICD_BASE	PLAT_GICD_BASE
+#define PLAT_RK_GICC_BASE	PLAT_GICC_BASE
+#define PLAT_RK_GICR_BASE	PLAT_GICR_BASE
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+
+#define PLAT_RK_GICV3_G1S_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+		       INTR_GROUP1S, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_GICV3_G0_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+		       INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_UART_BASE		FPGA_UART_BASE
+#define PLAT_RK_UART_CLOCK		FPGA_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE	FPGA_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU	0x0
+
+#define ATAGS_PHYS_SIZE		0x2000
+#define ATAGS_PHYS_BASE		(0x200000 - ATAGS_PHYS_SIZE)/* [2M-8K, 2M] */
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3568/plat_sip_calls.c b/plat/rockchip/rk3568/plat_sip_calls.c
new file mode 100644
index 0000000..b0f3a03
--- /dev/null
+++ b/plat/rockchip/rk3568/plat_sip_calls.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t 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)
+{
+	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/rockchip/rk3568/platform.mk b/plat/rockchip/rk3568/platform.mk
new file mode 100644
index 0000000..1155ff8
--- /dev/null
+++ b/plat/rockchip/rk3568/platform.mk
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RK_PLAT			:=	plat/rockchip
+RK_PLAT_SOC		:=	${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON		:=	${RK_PLAT}/common
+
+DISABLE_BIN_GENERATION	:=	1
+GICV3_SUPPORT_GIC600	:=	1
+include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+# GIC-600 configuration
+GICV3_IMPL		:=	GIC600
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iinclude/bl31					\
+				-Iinclude/common				\
+				-Iinclude/drivers				\
+				-Iinclude/drivers/arm				\
+				-Iinclude/drivers/auth				\
+				-Iinclude/drivers/io				\
+				-Iinclude/drivers/ti/uart			\
+				-Iinclude/lib					\
+				-Iinclude/lib/cpus/${ARCH}			\
+				-Iinclude/lib/el3_runtime			\
+				-Iinclude/lib/pmf				\
+				-Iinclude/lib/psci				\
+				-Iinclude/plat/common				\
+				-Iinclude/services				\
+				-Iinclude/plat/common/				\
+				-Idrivers/arm/gic/v3/				\
+				-I${RK_PLAT_COMMON}/				\
+				-I${RK_PLAT_COMMON}/pmusram/			\
+				-I${RK_PLAT_COMMON}/include/			\
+				-I${RK_PLAT_COMMON}/drivers/pmu/		\
+				-I${RK_PLAT_COMMON}/drivers/parameter/		\
+				-I${RK_PLAT_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/soc/			\
+				-I${RK_PLAT_SOC}/include/
+
+RK_GIC_SOURCES		:=	${GICV3_SOURCES}				\
+				plat/common/plat_gicv3.c			\
+				${RK_PLAT}/common/rockchip_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	:=	${XLAT_TABLES_LIB_SRCS}				\
+				common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
+				lib/bl_aux_params/bl_aux_params.c		\
+				plat/common/plat_psci_common.c
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES	+=	${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
+BL31_SOURCES		+=	${RK_GIC_SOURCES}				\
+				drivers/arm/cci/cci.c				\
+				lib/cpus/aarch64/cortex_a55.S			\
+				drivers/ti/uart/aarch64/16550_console.S		\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				$(LIBFDT_SRCS)					\
+				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
+				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
+				${RK_PLAT_COMMON}/params_setup.c		\
+				${RK_PLAT_COMMON}/plat_pm.c			\
+				${RK_PLAT_COMMON}/plat_topology.c		\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
+				${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c	\
+				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
+				${RK_PLAT_SOC}/drivers/soc/soc.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c
+
+ENABLE_PLAT_COMPAT	:=	0
+MULTI_CONSOLE_API	:=	1
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+#Enable errata for cortex_a55
+ERRATA_A55_1530923	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS	:=	0
diff --git a/plat/rockchip/rk3568/rk3568_def.h b/plat/rockchip/rk3568/rk3568_def.h
new file mode 100644
index 0000000..0d1e5d1
--- /dev/null
+++ b/plat/rockchip/rk3568/rk3568_def.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define MAJOR_VERSION		(1)
+#define MINOR_VERSION		(0)
+
+#define SIZE_K(n)		((n) * 1024)
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define GIC600_BASE		0xfd400000
+#define GIC600_SIZE		SIZE_K(64)
+
+#define PMUSGRF_BASE		0xfdc00000
+#define SYSSGRF_BASE		0xfdc10000
+#define PMUGRF_BASE		0xfdc20000
+#define CPUGRF_BASE		0xfdc30000
+#define DDRGRF_BASE		0xfdc40000
+#define PIPEGRF_BASE		0xfdc50000
+#define GRF_BASE		0xfdc60000
+#define PIPEPHY_GRF0		0xfdc70000
+#define PIPEPHY_GRF1		0xfdc80000
+#define PIPEPHY_GRF2		0xfdc90000
+#define USBPHY_U3_GRF		0xfdca0000
+#define USB2PHY_U2_GRF		0xfdca8000
+#define EDPPHY_GRF		0xfdcb0000
+#define SYSSRAM_BASE		0xfdcc0000
+#define PCIE30PHY_GRF		0xfdcb8000
+#define USBGRF_BASE		0xfdcf0000
+
+#define PMUCRU_BASE		0xfdd00000
+#define SCRU_BASE		0xfdd10000
+#define SGRF_BASE		0xfdd18000
+#define STIME_BASE		0xfdd1c000
+#define CRU_BASE		0xfdd20000
+#define PMUSCRU_BASE		0xfdd30000
+#define I2C0_BASE		0xfdd40000
+
+#define UART0_BASE		0xfdd50000
+#define GPIO0_BASE		0xfdd60000
+#define PMUPVTM_BASE		0xfdd80000
+#define PMU_BASE		0xfdd90000
+#define PMUSRAM_BASE		0xfdcd0000
+#define PMUSRAM_SIZE		SIZE_K(128)
+#define PMUSRAM_RSIZE		SIZE_K(8)
+
+#define DDRSGRF_BASE		0xfe200000
+#define UART1_BASE		0xfe650000
+#define UART2_BASE		0xfe660000
+#define GPIO1_BASE		0xfe740000
+#define GPIO2_BASE		0xfe750000
+#define GPIO3_BASE		0xfe760000
+#define GPIO4_BASE		0xfe770000
+
+#define REMAP_BASE		0xffff0000
+#define REMAP_SIZE		SIZE_K(64)
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define FPGA_UART_BASE		UART2_BASE
+#define FPGA_BAUDRATE		1500000
+#define FPGA_UART_CLOCK		24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS	24000000
+#define SYS_COUNTER_FREQ_IN_MHZ		24
+
+/******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE		GIC600_BASE
+#define PLAT_GICC_BASE		0
+#define PLAT_GICR_BASE		(GIC600_BASE + 0x60000)
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER	29
+
+#define RK_IRQ_SEC_SGI_0	8
+#define RK_IRQ_SEC_SGI_1	9
+#define RK_IRQ_SEC_SGI_2	10
+#define RK_IRQ_SEC_SGI_3	11
+#define RK_IRQ_SEC_SGI_4	12
+#define RK_IRQ_SEC_SGI_5	13
+#define RK_IRQ_SEC_SGI_6	14
+#define RK_IRQ_SEC_SGI_7	15
+
+#define SHARE_MEM_BASE		0x100000/* [1MB, 1MB+60K]*/
+#define SHARE_MEM_PAGE_NUM	15
+#define SHARE_MEM_SIZE		SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 8034fa4..eaaff7d 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -73,13 +73,13 @@
 # This target concatenates BL1 and the FIP so that the base addresses match the
 # ones defined in the memory map
 armstub: bl1 fip
-	@echo "  CAT     $@"
-	${Q}cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
-	${Q}truncate --size=131072 ${RPI3_BL1_PAD_BIN}
-	${Q}cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  CAT     $@"
+	$(q)cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
+	$(q)truncate --size=131072 ${RPI3_BL1_PAD_BIN}
+	$(q)cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 # Build config flags
 # ------------------
@@ -213,11 +213,11 @@
     certificates: $(ROT_KEY)
 
     $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
     $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index a6d9bef..a5ab4f7 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -72,12 +72,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 
 endif	# TRUSTED_BOARD_BOOT
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index 967437b..e46d877 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index d466aa1..ebb9b8c 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -106,12 +106,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 
 endif
@@ -136,5 +136,5 @@
 .PHONY: bl2_gzip
 bl2_gzip: $(BUILD_PLAT)/bl2.bin.gz
 %.gz: %
-	@echo "  GZIP    $@"
-	$(Q)gzip -n -f -9 $< --stdout > $@
+	$(s)echo "  GZIP    $@"
+	$(q)gzip -n -f -9 $< --stdout > $@
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 86795d7..c17ac7e 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,6 +47,7 @@
 uintptr_t storage_dev_handle;
 
 static const io_dev_connector_t *fip_dev_con;
+static uint32_t nand_block_sz __maybe_unused;
 
 #ifndef DECRYPTION_SUPPORT_none
 static const io_dev_connector_t *enc_dev_con;
@@ -310,11 +311,55 @@
 }
 #endif /* STM32MP_SPI_NOR */
 
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+/*
+ * This function returns 0 if it can find an alternate
+ * image to be loaded or a negative errno otherwise.
+ */
+static int try_nand_backup_partitions(unsigned int image_id)
+{
+	static unsigned int backup_id;
+	static unsigned int backup_block_nb;
+
+	/* Check if NAND storage used */
+	if (nand_block_sz == 0U) {
+		return -ENODEV;
+	}
+
+	if (backup_id != image_id) {
+		backup_block_nb = PLATFORM_MTD_MAX_PART_SIZE / nand_block_sz;
+		backup_id = image_id;
+	}
+
+	if (backup_block_nb-- == 0U) {
+		return -ENOSPC;
+	}
+
+#if PSA_FWU_SUPPORT
+	if (((image_block_spec.offset < STM32MP_NAND_FIP_B_OFFSET) &&
+	     ((image_block_spec.offset + nand_block_sz) >= STM32MP_NAND_FIP_B_OFFSET)) ||
+	    (image_block_spec.offset + nand_block_sz >= STM32MP_NAND_FIP_B_MAX_OFFSET)) {
+		return 0;
+	}
+#endif
+
+	image_block_spec.offset += nand_block_sz;
+
+	return 0;
+}
+
+static const struct plat_try_images_ops try_img_ops = {
+	.next_instance = try_nand_backup_partitions,
+};
+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
+
 #if STM32MP_RAW_NAND
 static void boot_fmc2_nand(boot_api_context_t *boot_context)
 {
 	int io_result __maybe_unused;
 
+	plat_setup_try_img_ops(&try_img_ops);
+
 	io_result = stm32_fmc2_init();
 	assert(io_result == 0);
 
@@ -326,6 +371,8 @@
 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
 				&storage_dev_handle);
 	assert(io_result == 0);
+
+	nand_block_sz = nand_dev_spec.erase_size;
 }
 #endif /* STM32MP_RAW_NAND */
 
@@ -334,6 +381,8 @@
 {
 	int io_result __maybe_unused;
 
+	plat_setup_try_img_ops(&try_img_ops);
+
 	io_result = stm32_qspi_init();
 	assert(io_result == 0);
 
@@ -345,6 +394,8 @@
 				(uintptr_t)&spi_nand_dev_spec,
 				&storage_dev_handle);
 	assert(io_result == 0);
+
+	nand_block_sz = spi_nand_dev_spec.erase_size;
 }
 #endif /* STM32MP_SPI_NAND */
 
@@ -493,12 +544,10 @@
  */
 #if !PSA_FWU_SUPPORT
 			const partition_entry_t *entry;
-			const struct efi_guid img_type_guid = STM32MP_FIP_GUID;
-			uuid_t img_type_uuid;
+			const struct efi_guid fip_guid = STM32MP_FIP_GUID;
 
-			guidcpy(&img_type_uuid, &img_type_guid);
 			partition_init(GPT_IMAGE_ID);
-			entry = get_partition_entry_by_type(&img_type_uuid);
+			entry = get_partition_entry_by_type(&fip_guid);
 			if (entry == NULL) {
 				entry = get_partition_entry(FIP_IMAGE_NAME);
 				if (entry == NULL) {
@@ -532,7 +581,14 @@
 #if STM32MP_SPI_NAND
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
 #endif
+/*
+ * 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_NAND_FIP_OFFSET;
+#endif
 		break;
 #endif
 
@@ -598,7 +654,7 @@
 	return rc;
 }
 
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if 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.
@@ -613,8 +669,6 @@
  *     - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
  * we select the previous_active_index.
  */
-#define INVALID_BOOT_IDX		0xFFFFFFFFU
-
 uint32_t plat_fwu_get_boot_idx(void)
 {
 	/*
@@ -622,32 +676,38 @@
 	 * even if this function is called several times.
 	 */
 	static uint32_t boot_idx = INVALID_BOOT_IDX;
-	const struct fwu_metadata *data;
-
-	data = fwu_get_metadata();
 
 	if (boot_idx == INVALID_BOOT_IDX) {
+		const struct fwu_metadata *data = fwu_get_metadata();
+
 		boot_idx = data->active_index;
-		if (fwu_is_trial_run_state()) {
+
+		if (data->bank_state[boot_idx] == FWU_BANK_STATE_VALID) {
 			if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
 				WARN("Trial FWU fails %u times\n",
 				     FWU_MAX_TRIAL_REBOOT);
-				boot_idx = data->previous_active_index;
+				boot_idx = fwu_get_alternate_boot_bank();
 			}
-		} else {
+		} else if (data->bank_state[boot_idx] ==
+			   FWU_BANK_STATE_ACCEPTED) {
 			stm32_set_max_fwu_trial_boot_cnt();
+		} else {
+			ERROR("The active bank(%u) of the platform is in Invalid State.\n",
+				boot_idx);
+			boot_idx = fwu_get_alternate_boot_bank();
+			stm32_clear_fwu_trial_boot_cnt();
 		}
 	}
 
 	return boot_idx;
 }
 
-static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
+static void *stm32_get_image_spec(const struct efi_guid *img_type_guid)
 {
 	unsigned int i;
 
 	for (i = 0U; i < MAX_NUMBER_IDS; i++) {
-		if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) {
+		if ((guidcmp(&policies[i].img_type_guid, img_type_guid)) == 0) {
 			return (void *)policies[i].image_spec;
 		}
 	}
@@ -660,20 +720,23 @@
 	unsigned int i;
 	uint32_t boot_idx;
 	const partition_entry_t *entry __maybe_unused;
-	const uuid_t *img_type_uuid;
-	const uuid_t *img_uuid __maybe_unused;
+	const struct fwu_image_entry *img_entry;
+	const void *img_type_guid;
+	const void *img_guid;
 	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);
+	VERBOSE("Selecting to boot from bank %u\n", boot_idx);
 
+	img_entry = (void *)&metadata->fw_desc.img_entry;
 	for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
-		img_type_uuid = &metadata->img_entry[i].img_type_uuid;
+		img_type_guid = &img_entry[i].img_type_guid;
 
-		img_uuid = &metadata->img_entry[i].img_props[boot_idx].img_uuid;
+		img_guid = &img_entry[i].img_bank_info[boot_idx].img_guid;
 
-		image_spec = stm32_get_image_spec(img_type_uuid);
+		image_spec = stm32_get_image_spec(img_type_guid);
 		if (image_spec == NULL) {
 			ERROR("Unable to get image spec for the image in the metadata\n");
 			panic();
@@ -683,7 +746,7 @@
 #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);
+			entry = get_partition_entry_by_guid(img_guid);
 			if (entry == NULL) {
 				ERROR("No partition with the uuid mentioned in metadata\n");
 				panic();
@@ -695,9 +758,9 @@
 #endif
 #if STM32MP_SPI_NOR
 		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI:
-			if (guidcmp(img_uuid, &STM32MP_NOR_FIP_A_GUID) == 0) {
+			if (guidcmp(img_guid, &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) {
+			} else if (guidcmp(img_guid, &STM32MP_NOR_FIP_B_GUID) == 0) {
 				image_spec->offset = STM32MP_NOR_FIP_B_OFFSET;
 			} else {
 				ERROR("Invalid uuid mentioned in metadata\n");
@@ -705,6 +768,19 @@
 			}
 			break;
 #endif
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+			if (guidcmp(img_guid, &STM32MP_NAND_FIP_A_GUID) == 0) {
+				image_spec->offset = STM32MP_NAND_FIP_A_OFFSET;
+			} else if (guidcmp(img_guid, &STM32MP_NAND_FIP_B_GUID) == 0) {
+				image_spec->offset = STM32MP_NAND_FIP_B_OFFSET;
+			} else {
+				ERROR("Invalid uuid mentioned in metadata\n");
+				panic();
+			}
+			break;
+#endif
 		default:
 			panic();
 			break;
@@ -712,9 +788,9 @@
 	}
 }
 
-static int plat_set_image_source(unsigned int image_id,
-				 uintptr_t *handle,
-				 uintptr_t *image_spec)
+static int set_metadata_image_source(unsigned int image_id,
+				     uintptr_t *handle,
+				     uintptr_t *image_spec)
 {
 	struct plat_io_policy *policy;
 	io_block_spec_t *spec __maybe_unused;
@@ -757,6 +833,19 @@
 		spec->length = sizeof(struct fwu_metadata);
 		break;
 #endif
+
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+		if (image_id == FWU_METADATA_IMAGE_ID) {
+			spec->offset = STM32MP_NAND_METADATA1_OFFSET;
+		} else {
+			spec->offset = STM32MP_NAND_METADATA2_OFFSET;
+		}
+
+		spec->length = sizeof(struct fwu_metadata);
+		break;
+#endif
 	default:
 		panic();
 		break;
@@ -775,6 +864,6 @@
 	assert((image_id == FWU_METADATA_IMAGE_ID) ||
 	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
 
-	return plat_set_image_source(image_id, handle, image_spec);
+	return set_metadata_image_source(image_id, handle, image_spec);
 }
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index f49112d..7395a36 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -1,12 +1,11 @@
 #
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 RESET_TO_BL2			:=	1
 
-STM32MP_EARLY_CONSOLE		?=	0
 STM32MP_RECONFIGURE_CONSOLE	?=	0
 STM32MP_UART_BAUDRATE		?=	115200
 
@@ -29,6 +28,24 @@
 TF_CFLAGS			+=	-Wsign-compare
 TF_CFLAGS			+=	-Wformat-signedness
 
+# Number of TF-A copies in the device
+STM32_TF_A_COPIES		:=	2
+
+# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
+PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + $(STM32_EXTRA_PARTS))))
+
+ifeq (${PSA_FWU_SUPPORT},1)
+# Number of banks of updatable firmware
+NR_OF_FW_BANKS			:=	2
+NR_OF_IMAGES_IN_FW_BANK		:=	1
+
+FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
+ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
+$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
+$(PLAT_PARTITION_MAX_ENTRIES)")
+endif
+endif
+
 # Boot devices
 STM32MP_EMMC			?=	0
 STM32MP_SDMMC			?=	0
@@ -82,7 +99,6 @@
 $(eval $(call assert_booleans,\
 	$(sort \
 		PLAT_XLAT_TABLES_DYNAMIC \
-		STM32MP_EARLY_CONSOLE \
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
@@ -104,7 +120,6 @@
 	$(sort \
 		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_TF_VERSION \
-		STM32MP_EARLY_CONSOLE \
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
@@ -123,6 +138,9 @@
 include lib/fconf/fconf.mk
 include lib/libfdt/libfdt.mk
 include lib/zlib/zlib.mk
+ifeq (${PSA_FWU_SUPPORT},1)
+include drivers/fwu/fwu.mk
+endif
 
 PLAT_BL_COMMON_SOURCES		+=	common/uuid.c					\
 					plat/st/common/stm32mp_common.c
@@ -183,12 +201,10 @@
 MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
 ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
 
-ifeq (${MBEDTLS_MAJOR}, 2)
-MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-2.h>"
-endif
-
 ifeq (${MBEDTLS_MAJOR}, 3)
 MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-3.h>"
+else
+$(error Error: TF-A only supports MbedTLS versions > 3.x)
 endif
 endif
 
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
index 212a67d..8b81c7f 100644
--- a/plat/st/common/common_rules.mk
+++ b/plat/st/common/common_rules.mk
@@ -15,7 +15,7 @@
 bl2: check_boot_device
 
 check_boot_device:
-	@if [ ${STM32MP_EMMC} != 1 ] && \
+	$(q)if [ ${STM32MP_EMMC} != 1 ] && \
 	    [ ${STM32MP_SDMMC} != 1 ] && \
 	    [ ${STM32MP_RAW_NAND} != 1 ] && \
 	    [ ${STM32MP_SPI_NAND} != 1 ] && \
@@ -29,55 +29,55 @@
 stm32image: ${STM32IMAGE}
 
 ${STM32IMAGE}: ${STM32IMAGE_SRC}
-	${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
+	$(q)${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
 
 clean_stm32image:
-	${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
 
 check_dtc_version:
-	@if [ ${DTC_VERSION} -lt 10407 ]; then \
+	$(q)if [ ${DTC_VERSION} -lt 10407 ]; then \
 		echo "dtc version too old (${DTC_V}), you need at least version 1.4.7"; \
 		false; \
 	fi
 
 # Create DTB file for BL2
 ${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL2_DTSI}"' >> $@
+	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "${BL2_DTSI}"' >> $@
 
 ${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
 
 ${BUILD_PLAT}/$(PLAT)-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb $(STM32_BINARY_MAPPING) bl2
-	@echo "  AS      $${PLAT}.S"
-	${Q}$($(ARCH)-as) -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) ${ASFLAGS} ${TF_CFLAGS} \
+	$(s)echo "  AS      $${PLAT}.S"
+	$(q)$($(ARCH)-as) -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) ${ASFLAGS} ${TF_CFLAGS} \
 		-DDTB_BIN_PATH=\"$<\" \
 		-c $(word 2,$^) -o $@
 
 $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},$(STM32_LD_FILE),bl2))
 
 tf-a-%.elf: $(PLAT)-%.o ${STM32_TF_LINKERFILE}
-	@echo "  LDS     $<"
+	$(s)echo "  LDS     $<"
 ifeq ($($(ARCH)-ld-id),gnu-gcc)
-	${Q}$($(ARCH)-ld) -o $@ $(subst --,-Wl$(comma)--,${STM32_TF_ELF_LDFLAGS}) -nostartfiles -Wl,-Map=$(@:.elf=.map) -Wl,-dT ${STM32_TF_LINKERFILE} $<
+	$(q)$($(ARCH)-ld) -o $@ $(subst --,-Wl$(comma)--,${STM32_TF_ELF_LDFLAGS}) -nostartfiles -Wl,-Map=$(@:.elf=.map) -Wl,-dT ${STM32_TF_LINKERFILE} $<
 else
-	${Q}$($(ARCH)-ld) -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
+	$(q)$($(ARCH)-ld) -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
 endif
 
 tf-a-%.bin: tf-a-%.elf
-	${Q}$($(ARCH)-oc) -O binary $< $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
+	$(q)$($(ARCH)-oc) -O binary $< $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 tf-a-%.stm32: tf-a-%.bin ${STM32_DEPS}
-	@echo
-	@echo "Generate $@"
+	$(s)echo
+	$(s)echo "Generate $@"
 	$(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep '^RAM' | awk '{print $$2}'))
 	$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
-	${Q}${STM32IMAGE} -s $< -d $@ \
+	$(q)${STM32IMAGE} -s $< -d $@ \
 		-l $(LOADADDR) -e ${ENTRY} \
 		-v ${STM32_TF_VERSION} \
 		-m ${STM32_HEADER_VERSION_MAJOR} \
 		-n ${STM32_HEADER_VERSION_MINOR} \
 		-b ${STM32_HEADER_BL2_BINARY_TYPE}
-	@echo
+	$(s)echo
diff --git a/plat/st/common/include/plat_def_fip_uuid.h b/plat/st/common/include/plat_def_fip_uuid.h
new file mode 100644
index 0000000..096fd95
--- /dev/null
+++ b/plat/st/common/include/plat_def_fip_uuid.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_FIP_UUID_H
+#define PLAT_DEF_FIP_UUID_H
+
+#define UUID_DDR_FW \
+	{{0xb1, 0x12, 0x49, 0xbe}, {0x92, 0xdd}, {0x4b, 0x10}, 0x86, 0x7c, \
+	 {0x2c, 0x6a, 0x4b, 0x47, 0xa7, 0xfb} }
+
+#define UUID_STM32MP_CONFIG_CERT \
+	{{0x50, 0x1d, 0x8d, 0xd2}, {0x8b, 0xce}, {0x49, 0xa5}, 0x84, 0xeb, \
+	 {0x55, 0x9a, 0x9f, 0x2e, 0xae, 0xaf} }
+#endif /* PLAT_DEF_FIP_UUID_H */
+
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 0ff6092..9af221c 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -77,14 +77,6 @@
 /* Setup the UART console */
 int stm32mp_uart_console_setup(void);
 
-#if STM32MP_EARLY_CONSOLE
-void stm32mp_setup_early_console(void);
-#else
-static inline void stm32mp_setup_early_console(void)
-{
-}
-#endif
-
 /*
  * Platform util functions for the GPIO driver
  * @bank: Target GPIO bank ID as per DT bindings
@@ -139,9 +131,11 @@
 void stm32_display_board_info(uint32_t board_id);
 
 #if PSA_FWU_SUPPORT
-void stm32mp1_fwu_set_boot_idx(void);
+uintptr_t stm32_get_bkpr_fwu_info_addr(void);
+void stm32_fwu_set_boot_idx(void);
 uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
 void stm32_set_max_fwu_trial_boot_cnt(void);
+void stm32_clear_fwu_trial_boot_cnt(void);
 #endif /* PSA_FWU_SUPPORT */
 
 #endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/include/stm32mp_mbedtls_config-2.h b/plat/st/common/include/stm32mp_mbedtls_config-2.h
deleted file mode 100644
index 66ff346..0000000
--- a/plat/st/common/include/stm32mp_mbedtls_config-2.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-/*
- * Key algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_USE_RSA	0
-#define TF_MBEDTLS_USE_ECDSA	1
-
-/*
- * Hash algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_SHA256		1
-#define TF_MBEDTLS_SHA384		2
-#define TF_MBEDTLS_SHA512		3
-
-/*
- * Configuration file to build mbed TLS with the required features for
- * Trusted Boot
- */
-
-#define MBEDTLS_PLATFORM_MEMORY
-#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
-#define MBEDTLS_PLATFORM_SNPRINTF_ALT
-
-#define MBEDTLS_PKCS1_V21
-
-#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_ASN1_WRITE_C
-
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_BIGNUM_C
-
-#define MBEDTLS_ERROR_C
-#define MBEDTLS_MD_C
-
-#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
-#define MBEDTLS_OID_C
-
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-
-#define MBEDTLS_PLATFORM_C
-
-#if TF_MBEDTLS_USE_ECDSA
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_NO_INTERNAL_RNG
-#endif
-#if TF_MBEDTLS_USE_RSA
-#define MBEDTLS_RSA_C
-#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-#endif
-
-#define MBEDTLS_SHA256_C
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
-#define MBEDTLS_SHA512_C
-#endif
-
-#define MBEDTLS_VERSION_C
-
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-
-#if TF_MBEDTLS_USE_AES_GCM
-#define MBEDTLS_AES_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_GCM_C
-#endif
-
-/* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
-
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define MBEDTLS_MPI_MAX_SIZE			256
-#else
-#define MBEDTLS_MPI_MAX_SIZE			512
-#endif
-#else
-#define MBEDTLS_MPI_MAX_SIZE			256
-#endif
-
-/* Memory buffer allocator options */
-#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
-
-/*
- * Prevent the use of 128-bit division which
- * creates dependency on external libraries.
- */
-#define MBEDTLS_NO_UDBL_DIVISION
-
-#ifndef __ASSEMBLER__
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-#include <mbedtls/check_config.h>
-#endif
-
-/*
- * Mbed TLS heap size is smal as we only use the asn1
- * parsing functions
- * digest, signature and crypto algorithm are done by
- * other library.
- */
-
-#define TF_MBEDTLS_HEAP_SIZE           U(5120)
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/plat/st/common/include/stm32mp_mbedtls_config-3.h b/plat/st/common/include/stm32mp_mbedtls_config-3.h
index a812671..2dbf068 100644
--- a/plat/st/common/include/stm32mp_mbedtls_config-3.h
+++ b/plat/st/common/include/stm32mp_mbedtls_config-3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -102,7 +102,6 @@
 #ifndef __ASSEMBLER__
 /* System headers required to build mbed TLS with the current configuration */
 #include <stdlib.h>
-#include <mbedtls/check_config.h>
 #endif
 
 /*
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index a1d1c49..d2f8784 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -55,6 +55,12 @@
 #define BOOT_INST_MASK			GENMASK_32(11, 8)
 #define BOOT_INST_SHIFT			8
 
+/* Layout for fwu update information. */
+#define FWU_INFO_IDX_MSK		GENMASK(3, 0)
+#define FWU_INFO_IDX_OFF		U(0)
+#define FWU_INFO_CNT_MSK		GENMASK(7, 4)
+#define FWU_INFO_CNT_OFF		U(4)
+
 static console_t console;
 
 uintptr_t plat_get_ns_image_entrypoint(void)
@@ -269,8 +275,8 @@
 	return 0;
 }
 
-#if STM32MP_EARLY_CONSOLE
-void stm32mp_setup_early_console(void)
+#if EARLY_CONSOLE
+void plat_setup_early_console(void)
 {
 #if defined(IMAGE_BL2) || STM32MP_RECONFIGURE_CONSOLE
 	plat_crash_console_init();
@@ -278,7 +284,7 @@
 	set_console(STM32MP_DEBUG_USART_BASE, STM32MP_DEBUG_USART_CLK_FRQ);
 	NOTICE("Early console setup\n");
 }
-#endif /* STM32MP_EARLY_CONSOLE */
+#endif /* EARLY_CONSOLE */
 
 /*****************************************************************************
  * plat_is_smccc_feature_available() - This function checks whether SMCCC
@@ -378,3 +384,53 @@
 	*interface = (itf & BOOT_ITF_MASK) >> BOOT_ITF_SHIFT;
 	*instance = (itf & BOOT_INST_MASK) >> BOOT_INST_SHIFT;
 }
+
+#if PSA_FWU_SUPPORT
+void stm32_fwu_set_boot_idx(void)
+{
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrsetbits_32(stm32_get_bkpr_fwu_info_addr(),
+			   FWU_INFO_IDX_MSK,
+			   (plat_fwu_get_boot_idx() << FWU_INFO_IDX_OFF) &
+			   FWU_INFO_IDX_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+	uint32_t try_cnt;
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & FWU_INFO_CNT_MSK) >> FWU_INFO_CNT_OFF;
+
+	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
+
+	if (try_cnt != 0U) {
+		mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
+				   (try_cnt - 1U) << FWU_INFO_CNT_OFF);
+	}
+	clk_disable(TAMP_BKP_REG_CLK);
+
+	return try_cnt;
+}
+
+void stm32_set_max_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
+			   (FWU_MAX_TRIAL_REBOOT << FWU_INFO_CNT_OFF) & FWU_INFO_CNT_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+void stm32_clear_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 5514c09..6ed09d9 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,12 +27,12 @@
 };
 #endif
 
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 };
 
 #define DEFAULT_UUID_NUMBER	U(7)
diff --git a/plat/st/common/stm32mp_gic.c b/plat/st/common/stm32mp_gic.c
index d02b635..a4cc4a5 100644
--- a/plat/st/common/stm32mp_gic.c
+++ b/plat/st/common/stm32mp_gic.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
@@ -45,25 +46,29 @@
 	int node;
 	void *fdt;
 	const fdt32_t *cuint;
-	struct dt_node_info dt_gic;
+	uintptr_t addr;
+	int err;
 
 	if (fdt_get_address(&fdt) == 0) {
 		panic();
 	}
 
-	node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
+	node = fdt_node_offset_by_compatible(fdt, -1, "arm,cortex-a7-gic");
 	if (node < 0) {
 		panic();
 	}
 
-	platform_gic_data.gicd_base = dt_gic.base;
-
-	cuint = fdt_getprop(fdt, node, "reg", NULL);
-	if (cuint == NULL) {
+	err = fdt_get_reg_props_by_index(fdt, node, 0, &addr, NULL);
+	if (err < 0) {
 		panic();
 	}
+	platform_gic_data.gicd_base = addr;
 
-	platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
+	err = fdt_get_reg_props_by_index(fdt, node, 1, &addr, NULL);
+	if (err < 0) {
+		panic();
+	}
+	platform_gic_data.gicc_base = addr;
 
 	cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
 	if (cuint == NULL) {
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index fd86020..2ade242 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -142,8 +142,6 @@
 				  u_register_t arg2 __unused,
 				  u_register_t arg3 __unused)
 {
-	stm32mp_setup_early_console();
-
 	stm32mp_save_boot_ctx_address(arg0);
 }
 
@@ -255,11 +253,6 @@
 		mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
 	}
 
-#if STM32MP15
-	/* Disable MCKPROT */
-	mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
-#endif
-
 	/*
 	 * Set minimum reset pulse duration to 31ms for discrete power
 	 * supplied boards.
@@ -447,8 +440,7 @@
 				paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
 				if (paged_mem_params != NULL) {
 					paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
-						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
-						 STM32MP_DDR_SHMEM_SIZE);
+						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE);
 					paged_mem_params->image_info.image_max_size =
 						STM32MP_DDR_S_SIZE;
 				}
@@ -515,7 +507,7 @@
 		assert(bl32_mem_params != NULL);
 		bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
 #if PSA_FWU_SUPPORT
-		stm32mp1_fwu_set_boot_idx();
+		stm32_fwu_set_boot_idx();
 #endif /* PSA_FWU_SUPPORT */
 		break;
 
diff --git a/plat/st/stm32mp1/cert_create_tbbr.mk b/plat/st/stm32mp1/cert_create_tbbr.mk
index e747e39..fb9e5ec 100644
--- a/plat/st/stm32mp1/cert_create_tbbr.mk
+++ b/plat/st/stm32mp1/cert_create_tbbr.mk
@@ -11,7 +11,7 @@
 PLAT_INCLUDE	+= -I${PLAT_DIR}include
 
 src/stm32mp1_tbb_cert.o: ${PLAT_DIR}stm32mp1_tbb_cert.c
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 PLAT_OBJECTS	= src/stm32mp1_tbb_cert.o
 
diff --git a/plat/st/stm32mp1/include/plat_def_fip_uuid.h b/plat/st/stm32mp1/include/plat_def_fip_uuid.h
deleted file mode 100644
index e5fbc2d..0000000
--- a/plat/st/stm32mp1/include/plat_def_fip_uuid.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_DEF_FIP_UUID_H
-#define PLAT_DEF_FIP_UUID_H
-
-#define UUID_STM32MP_CONFIG_CERT \
-	{{0x50, 0x1d, 0x8d, 0xd2}, {0x8b, 0xce}, {0x49, 0xa5}, 0x84, 0xeb, \
-	 {0x55, 0x9a, 0x9f, 0x2e, 0xae, 0xaf} }
-#endif /* PLAT_DEF_FIP_UUID_H */
-
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index ddc5289..a1f44e8 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,9 +1,13 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Extra partitions used to find FIP, contains:
+# metadata (2) and the FIP partitions (default is 2).
+STM32_EXTRA_PARTS	:=	4
+
 include plat/st/common/common.mk
 
 ARM_CORTEX_A7		:=	yes
@@ -60,11 +64,6 @@
 # STM32 image header version v1.0
 STM32_HEADER_VERSION_MAJOR:=	1
 STM32_HEADER_VERSION_MINOR:=	0
-
-# Add OP-TEE reserved shared memory area in mapping
-STM32MP15_OPTEE_RSV_SHM	:=	0
-$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
-
 STM32MP_CRYPTO_ROM_LIB :=	1
 
 # Decryption support
@@ -85,25 +84,6 @@
 WORKAROUND_CVE_2017_5715:=	0
 WORKAROUND_CVE_2022_23960:=	0
 
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES		:=	2
-
-# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
-# such as metadata (2) to find all the FIP partitions (default is 2).
-PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
-
-ifeq (${PSA_FWU_SUPPORT},1)
-# Number of banks of updatable firmware
-NR_OF_FW_BANKS			:=	2
-NR_OF_IMAGES_IN_FW_BANK		:=	1
-
-FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
-ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
-$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
-$(PLAT_PARTITION_MAX_ENTRIES)")
-endif
-endif
-
 ifeq ($(STM32MP13),1)
 STM32_HASH_VER		:=	4
 STM32_RNG_VER		:=	4
@@ -233,10 +213,6 @@
 BL2_SOURCES		+=	plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
 				plat/st/stm32mp1/stm32mp1_fconf_firewall.c
 
-ifeq (${PSA_FWU_SUPPORT},1)
-include drivers/fwu/fwu.mk
-endif
-
 BL2_SOURCES		+=	drivers/st/crypto/stm32_hash.c				\
 				plat/st/stm32mp1/bl2_plat_setup.c
 
@@ -280,8 +256,8 @@
 ifeq ($(AARCH32_SP),sp_min)
 # Create DTB file for BL32
 ${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL32_DTSI}"' >> $@
+	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "${BL32_DTSI}"' >> $@
 
 ${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts
 endif
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index b46f4af..7bfe6ba 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -116,8 +116,6 @@
 	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
 	uintptr_t dt_addr = arg1;
 
-	stm32mp_setup_early_console();
-
 	/* Imprecise aborts can be masked in NonSecure */
 	write_scr(read_scr() | SCR_AW_BIT);
 
@@ -182,6 +180,9 @@
 
 	stm32mp_gic_init();
 
+	/* Disable MCU subsystem protection */
+	stm32mp1_clk_mcuss_protect(false);
+
 	if (stm32_iwdg_init() < 0) {
 		panic();
 	}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 0d401f9..824563f 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -10,6 +10,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/st/stm32mp1_rcc.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
 #include <dt-bindings/reset/stm32mp1-resets.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
@@ -231,21 +232,7 @@
 #endif
 #define GPIO_BANK_OFFSET		U(0x1000)
 
-/* Bank IDs used in GPIO driver API */
-#define GPIO_BANK_A			U(0)
-#define GPIO_BANK_B			U(1)
-#define GPIO_BANK_C			U(2)
-#define GPIO_BANK_D			U(3)
-#define GPIO_BANK_E			U(4)
-#define GPIO_BANK_F			U(5)
-#define GPIO_BANK_G			U(6)
-#define GPIO_BANK_H			U(7)
-#define GPIO_BANK_I			U(8)
 #if STM32MP15
-#define GPIO_BANK_J			U(9)
-#define GPIO_BANK_K			U(10)
-#define GPIO_BANK_Z			U(25)
-
 #define STM32MP_GPIOZ_PIN_MAX_COUNT	8
 #endif
 
@@ -634,6 +621,11 @@
 #define PLAT_NB_FIXED_REGUS		U(2)
 
 /*******************************************************************************
+ * STM32MP1 CLOCKS
+ ******************************************************************************/
+#define PLL1_NOMINAL_FREQ_IN_KHZ	U(650000) /* 650MHz */
+
+/*******************************************************************************
  * Device Tree defines
  ******************************************************************************/
 #if STM32MP13
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index e37e2e6..165f152 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,7 @@
 #ifndef STM32MP1_FIP_DEF_H
 #define STM32MP1_FIP_DEF_H
 
-#if STM32MP15_OPTEE_RSV_SHM
-#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
-#else
 #define STM32MP_DDR_S_SIZE		U(0x02000000)	/* 32 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0)		/* empty */
-#endif
 
 #if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP
 #if STM32MP15
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 0e69513..189f83d 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -29,10 +29,6 @@
  * (so it should be in Zone 2).
  */
 #define TAMP_BOOT_FWU_INFO_REG_ID	U(10)
-#define TAMP_BOOT_FWU_INFO_IDX_MSK	GENMASK(3, 0)
-#define TAMP_BOOT_FWU_INFO_IDX_OFF	U(0)
-#define TAMP_BOOT_FWU_INFO_CNT_MSK	GENMASK(7, 4)
-#define TAMP_BOOT_FWU_INFO_CNT_OFF	U(4)
 
 #if defined(IMAGE_BL2)
 #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
@@ -115,14 +111,14 @@
 uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ_BASE;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
@@ -131,14 +127,14 @@
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return 0;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return bank * GPIO_BANK_OFFSET;
@@ -161,14 +157,14 @@
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return GPIOA + (bank - GPIO_BANK_A);
@@ -674,44 +670,8 @@
 }
 
 #if PSA_FWU_SUPPORT
-void stm32mp1_fwu_set_boot_idx(void)
+uintptr_t stm32_get_bkpr_fwu_info_addr(void)
 {
-	clk_enable(RTCAPB);
-	mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
-			   TAMP_BOOT_FWU_INFO_IDX_MSK,
-			   (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
-			   TAMP_BOOT_FWU_INFO_IDX_MSK);
-	clk_disable(RTCAPB);
-}
-
-uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
-{
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-	uint32_t try_cnt;
-
-	clk_enable(RTCAPB);
-	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
-		TAMP_BOOT_FWU_INFO_CNT_OFF;
-
-	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
-
-	if (try_cnt != 0U) {
-		mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
-				   (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
-	}
-	clk_disable(RTCAPB);
-
-	return try_cnt;
-}
-
-void stm32_set_max_fwu_trial_boot_cnt(void)
-{
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-
-	clk_enable(RTCAPB);
-	mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
-			   (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
-			   TAMP_BOOT_FWU_INFO_CNT_MSK);
-	clk_disable(RTCAPB);
+	return tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
 }
 #endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index a7cce62..724209a 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -18,7 +18,6 @@
 				  u_register_t arg2 __unused,
 				  u_register_t arg3 __unused)
 {
-	stm32mp_setup_early_console();
 }
 
 void bl2_platform_setup(void)
@@ -28,7 +27,7 @@
 void bl2_el3_plat_arch_setup(void)
 {
 	if (stm32_otp_probe() != 0U) {
-		ERROR("OTP probe failed\n");
+		EARLY_ERROR("OTP probe failed\n");
 		panic();
 	}
 }
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index bf2952d..11b1138 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Extra partitions used to find FIP, contains:
+# metadata (2) and fsbl-m (2) and the FIP partitions (default is 2).
+STM32_EXTRA_PARTS		:=	6
+
 include plat/st/common/common.mk
 
 CRASH_REPORTING			:=	1
@@ -19,13 +23,6 @@
 STM32_HEADER_VERSION_MAJOR	:=	2
 STM32_HEADER_VERSION_MINOR	:=	2
 
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES		:=	2
-
-# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
-# such as metadata (2) and fsbl-m (2) to find all the FIP partitions (default is 2).
-PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 6)))
-
 # Set load address for serial boot devices
 DWL_BUFFER_BASE 	?=	0x87000000
 
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 56c62e1..e3662ad 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -14,6 +14,7 @@
 #include <drivers/st/stm32mp25_rcc.h>
 #include <dt-bindings/clock/stm32mp25-clks.h>
 #include <dt-bindings/clock/stm32mp25-clksrc.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
 #include <dt-bindings/reset/stm32mp25-resets.h>
 
 #ifndef __ASSEMBLER__
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index 3fcb62f..ffee805 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -53,9 +53,6 @@
 				      uint32_t flag);
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
 				      uint32_t flag);
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag);
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag);
 uint32_t pm_get_shutdown_scope(void);
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index a87923f..e9c36c3 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,6 @@
 
 #if defined(PLAT_zynqmp)
 enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
-const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
 #endif /* PLAT_zynqmp */
 
 #endif /* PM_CLIENT_H */
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index c1872d0..055fa3d 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -95,8 +95,6 @@
 	IOCTL_GET_LAST_RESET_REASON = 23,
 	/* AI engine NPI ISR clear */
 	IOCTL_AIE_ISR_CLEAR = 24,
-	/* Register SGI to TF-A */
-	IOCTL_SET_SGI = 25,
 };
 
 /**
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 36ea8ed..0a6e810 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -287,112 +287,6 @@
 }
 
 /**
- * pm_pll_set_param() - Set PLL parameter.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Value to set for PLL parameter.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
-				    uint32_t value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
-			 clk_id, param, value);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_param() - Get PLL parameter value.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Buffer to store PLL parameter value.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
-				    uint32_t *value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
-			 clk_id, param);
-
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pll_set_mode() - Set PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: PLL mode.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
-			 clk_id, mode);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_mode() - Get PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: Buffer to store PLL mode.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, mode, 1);
-}
-
-/**
  * pm_force_powerdown() - PM call to request for another PU or subsystem to
  *                        be powered down forcefully.
  * @target: Device ID of the PU node to be forced powered down.
@@ -448,110 +342,6 @@
 }
 
 /**
- * pm_query_data() -  PM API for querying firmware data.
- * @qid: The type of data to query.
- * @arg1: Argument 1 to requested query data call.
- * @arg2: Argument 2 to requested query data call.
- * @arg3: Argument 3 to requested query data call.
- * @data: Returned output data.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: 0 if success else non-zero error code of type
- *         enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
-				 uint32_t arg3, uint32_t *data, uint32_t flag)
-{
-	uint32_t ret;
-	uint32_t version[PAYLOAD_ARG_CNT] = {0};
-	uint32_t payload[PAYLOAD_ARG_CNT];
-	uint32_t fw_api_version;
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
-			 arg1, arg2, arg3);
-
-	ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
-	if (ret == PM_RET_SUCCESS) {
-		fw_api_version = version[0] & 0xFFFFU;
-		if ((fw_api_version == 2U) &&
-		    ((qid == XPM_QID_CLOCK_GET_NAME) ||
-		     (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-			if (ret == PM_RET_SUCCESS) {
-				ret = data[0];
-				data[0] = data[1];
-				data[1] = data[2];
-				data[2] = data[3];
-			}
-		} else {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-		}
-	}
-	return ret;
-}
-/**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs.
- * @device_id: Device ID.
- * @ioctl_id: ID of the requested IOCTL.
- * @arg1: Argument 1 to requested IOCTL call.
- * @arg2: Argument 2 to requested IOCTL call.
- * @arg3: Argument 3 to requested IOCTL call.
- * @value: Returned output value.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * This function calls IOCTL to firmware for device control and configuration.
- *
- * Return: Returns status, either 0 on success or non-zero error code
- *         of type enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag)
-{
-	enum pm_ret_status ret;
-
-	switch (ioctl_id) {
-	case IOCTL_SET_PLL_FRAC_MODE:
-		ret =  pm_pll_set_mode(arg1, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_MODE:
-		ret =  pm_pll_get_mode(arg1, value, flag);
-		break;
-	case IOCTL_SET_PLL_FRAC_DATA:
-		ret =  pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_DATA:
-		ret =  pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
-		break;
-	case IOCTL_SET_SGI:
-		/* Get the sgi number */
-		ret = pm_register_sgi(arg1, arg2);
-		if (ret != 0) {
-			return PM_RET_ERROR_ARGS;
-		}
-		ret = PM_RET_SUCCESS;
-		break;
-	default:
-		return PM_RET_ERROR_NOTSUPPORTED;
-	}
-
-	return ret;
-}
-
-/**
  * pm_set_wakeup_source() - PM call to specify the wakeup source while
  *                          suspended.
  * @target: Device id of the targeted PU or subsystem
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index f9917a0..7ac0ac1 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,6 +34,8 @@
 #define PM_INIT_SUSPEND_CB	(30U)
 #define PM_NOTIFY_CB		(32U)
 #define EVENT_CPU_PWRDWN	(4U)
+#define MBOX_SGI_SHARED_IPI	(7U)
+
 /* 1 sec of wait timeout for secondary core down */
 #define PWRDWN_WAIT_TIMEOUT	(1000U)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
@@ -97,12 +99,32 @@
 {
 	uint32_t payload[4] = {0};
 	enum pm_ret_status ret;
+	int ipi_status, i;
 
 	VERBOSE("Received IPI FIQ from firmware\n");
 
 	console_flush();
 	(void)plat_ic_acknowledge_interrupt();
 
+	/* Check status register for each IPI except PMC */
+	for (i = IPI_ID_APU; i <= IPI_ID_5; i++) {
+		ipi_status = ipi_mb_enquire_status(IPI_ID_APU, i);
+
+		/* If any agent other than PMC has generated IPI FIQ then send SGI to mbox driver */
+		if (ipi_status & IPI_MB_STATUS_RECV_PENDING) {
+			plat_ic_raise_ns_sgi(MBOX_SGI_SHARED_IPI, read_mpidr_el1());
+			break;
+		}
+	}
+
+	/* If PMC has not generated interrupt then end ISR */
+	ipi_status = ipi_mb_enquire_status(IPI_ID_APU, IPI_ID_PMC);
+	if ((ipi_status & IPI_MB_STATUS_RECV_PENDING) == 0) {
+		plat_ic_end_of_interrupt(id);
+		return 0;
+	}
+
+	/* Handle PMC case */
 	ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
 	if (ret != PM_RET_SUCCESS) {
 		payload[0] = ret;
@@ -127,6 +149,9 @@
 				}
 			}
 			notify_os();
+		} else if (payload[2] == EVENT_CPU_PWRDWN) {
+			request_cpu_pwrdwn();
+			(void)psci_cpu_off();
 		}
 		break;
 	case PM_RET_ERROR_INVALID_CRC:
@@ -218,6 +243,14 @@
 	}
 
 	gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
+
+	/* Register for idle callback during force power down/restart */
+	ret = pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
+				   0x0U, 0x1U, SECURE_FLAG);
+	if (ret != 0) {
+		WARN("BL31: registering idle callback for restart/force power down failed\n");
+	}
+
 	return ret;
 }
 
@@ -243,30 +276,6 @@
 
 	switch (api_id) {
 
-	case (uint32_t)PM_IOCTL:
-	{
-		uint32_t value = 0U;
-
-		ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
-				   pm_arg[3], pm_arg[4],
-				   &value, security_flag);
-		if (ret == PM_RET_ERROR_NOTSUPPORTED)
-			return (uintptr_t)0;
-
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
-	}
-
-	case (uint32_t)PM_QUERY_DATA:
-	{
-		uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
-
-		ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
-				    pm_arg[3], data, security_flag);
-
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32U),
-			 (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
-	}
-
 	case (uint32_t)PM_FEATURE_CHECK:
 	{
 		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index d19a263..594784f 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
  * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
@@ -118,19 +118,6 @@
 		panic();
 	} else {
 		INFO("BL31: PLM to TF-A handover success %u\n", ret);
-
-		/*
-		 * The BL32 load address is indicated as 0x0 in the handoff
-		 * parameters, which is different from the default/user-provided
-		 * load address of 0x60000000 but the flags are correctly
-		 * configured. Consequently, in this scenario, set the PC
-		 * to the requested BL32_BASE address.
-		 */
-
-		/* TODO: Remove the following check once this is fixed from PLM */
-		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
-			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
-		}
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
@@ -206,8 +193,6 @@
 	if (rc != 0) {
 		panic();
 	}
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 45b1f1c..4cf1ed1 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,6 +36,9 @@
 	}
 
 	proc = pm_get_proc((uint32_t)cpu_id);
+	if (proc == NULL) {
+		return PSCI_E_INTERN_FAIL;
+	}
 
 	/* Send request to PMC to wake up selected ACPU core */
 	(void)pm_req_wakeup(proc->node_id, (versal_sec_entry & 0xFFFFFFFFU) | 0x1U,
@@ -59,6 +62,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -96,6 +103,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -190,6 +201,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 614d6d2..5af2b1d 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
  * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
@@ -59,6 +59,20 @@
 					DISABLE_ALL_EXCEPTIONS);
 }
 
+/* Define read and write function for clusterbusqos register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(cluster_bus_qos, S3_0_C15_C4_4)
+
+static void versal_net_setup_qos(void)
+{
+	int ret;
+
+	ret = read_cluster_bus_qos();
+	INFO("BL31: default cluster bus qos: 0x%x\n", ret);
+	write_cluster_bus_qos(0);
+	ret = read_cluster_bus_qos();
+	INFO("BL31: cluster bus qos written: 0x%x\n", ret);
+}
+
 /*
  * Perform any BL31 specific platform actions. Here is an opportunity to copy
  * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
@@ -103,6 +117,8 @@
 	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
 
+	versal_net_setup_qos();
+
 	/* Initialize the platform config for future decision making */
 	versal_net_config_setup();
 
@@ -137,18 +153,6 @@
 
 		INFO("BL31: PLM to TF-A handover success\n");
 
-		/*
-		 * The BL32 load address is indicated as 0x0 in the handoff
-		 * parameters, which is different from the default/user-provided
-		 * load address of 0x60000000 but the flags are correctly
-		 * configured. Consequently, in this scenario, set the PC
-		 * to the requested BL32_BASE address.
-		 */
-
-		/* TODO: Remove the following check once this is fixed from PLM */
-		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
-			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
-		}
 	} else {
 		INFO("BL31: setting up default configs\n");
 
@@ -231,8 +235,6 @@
 	if (rc != 0) {
 		panic();
 	}
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 94cb7f5..e5a5235 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,7 +38,7 @@
 	}
 
 	proc = pm_get_proc(cpu_id);
-	if (!proc) {
+	if (proc == NULL) {
 		return PSCI_E_INTERN_FAIL;
 	}
 
@@ -63,6 +63,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	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]);
@@ -143,6 +147,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	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]);
@@ -186,6 +194,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	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]);
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index baf6717..0a34f72 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -190,8 +190,6 @@
 #endif
 
 	custom_runtime_setup();
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index c6c6c4b..1e7df05 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,7 +42,11 @@
 	if (cpu_id == -1) {
 		return PSCI_E_INTERN_FAIL;
 	}
+
 	proc = pm_get_proc(cpu_id);
+	if (proc == NULL) {
+		return PSCI_E_INTERN_FAIL;
+	}
 
 	/* Check the APU proc status before wakeup */
 	ret = pm_get_node_status(proc->node_id, buff);
@@ -64,6 +68,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	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]);
@@ -89,6 +97,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	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]);
@@ -121,6 +133,10 @@
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	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]);
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index e266615..3a752b2 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -2,7 +2,7 @@
 # Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
 # Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
 # Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
-# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -16,6 +16,7 @@
 IPI_CRC_CHECK := 0
 override RESET_TO_BL31 := 1
 override WARMBOOT_ENABLE_DCACHE_EARLY := 1
+ENABLE_LTO := 1
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 4afa01d..9d0e2c4 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -245,23 +245,6 @@
 }
 
 /**
- * pm_get_proc_by_node() - returns pointer to the proc structure.
- * @nid: node id of the processor.
- *
- * Return: pointer to a proc structure if proc is found, otherwise NULL.
- *
- */
-const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
-{
-	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
-		if (nid == pm_procs_all[i].node_id) {
-			return &pm_procs_all[i];
-		}
-	}
-	return NULL;
-}
-
-/**
  * pm_get_cpuid() - get the local cpu ID for a global node ID.
  * @nid: node id of the processor.
  *
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 6b42055..3d546b3 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -272,6 +272,11 @@
 	uint32_t cpuid = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpuid);
 
+	if (proc == NULL) {
+		WARN("Failed to get proc %d\n", cpuid);
+		return PM_RET_ERROR_INTERNAL;
+	}
+
 	/*
 	 * Do client specific suspend operations
 	 * (e.g. set powerdown request bit)
diff --git a/pyproject.toml b/pyproject.toml
index 0fe2383..7814497 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "trusted-firmware-a"
-version = "2.10.0"
+version = "2.11.0"
 description = "Trusted Firmware-A (TF-A) Python dependencies."
 authors = ["Arm Ltd."]
 license = "BSD-3-Clause"
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 57d211e..5456164 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-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,7 +54,7 @@
 		 * If architectural SSBS is available on this PE, no firmware
 		 * mitigation via SMCCC_ARCH_WORKAROUND_2 is required.
 		 */
-		if (ssbs != SSBS_UNAVAILABLE)
+		if (ssbs != SSBS_NOT_IMPLEMENTED)
 			return 1;
 
 		/*
diff --git a/services/el3/ven_el3_svc.c b/services/el3/ven_el3_svc.c
new file mode 100644
index 0000000..32a3dc2
--- /dev/null
+++ b/services/el3/ven_el3_svc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/debugfs.h>
+#include <lib/pmf/pmf.h>
+#include <services/ven_el3_svc.h>
+#include <tools_share/uuid.h>
+
+/* vendor-specific EL3 UUID */
+DEFINE_SVC_UUID2(ven_el3_svc_uid,
+	0xb6011dca, 0x57c4, 0x407e, 0x83, 0xf0,
+	0xa7, 0xed, 0xda, 0xf0, 0xdf, 0x6c);
+
+static int ven_el3_svc_setup(void)
+{
+#if USE_DEBUGFS
+	if (debugfs_smc_setup() != 0) {
+		return 1;
+	}
+#endif /* USE_DEBUGFS */
+
+#if ENABLE_PMF
+	if (pmf_setup() != 0) {
+		return 1;
+	}
+#endif /* ENABLE_PMF */
+
+	return 0;
+}
+
+/*
+ * This function handles Arm defined vendor-specific EL3 Service Calls.
+ */
+static uintptr_t ven_el3_svc_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)
+{
+#if USE_DEBUGFS
+	/*
+	 * Dispatch debugfs calls to debugfs SMC handler and return its
+	 * return value.
+	 */
+	if (is_debugfs_fid(smc_fid)) {
+		return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+			handle, flags);
+	}
+#endif /* USE_DEBUGFS */
+
+#if ENABLE_PMF
+
+	/*
+	 * Dispatch PMF calls to PMF SMC handler and return its return
+	 * value
+	 */
+	if (is_pmf_fid(smc_fid)) {
+		return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+				handle, flags);
+	}
+
+#endif /* ENABLE_PMF */
+
+	switch (smc_fid) {
+	case VEN_EL3_SVC_UID:
+		/* Return UID to the caller */
+		SMC_UUID_RET(handle, ven_el3_svc_uid);
+		break;
+	case VEN_EL3_SVC_VERSION:
+		SMC_RET2(handle, VEN_EL3_SVC_VERSION_MAJOR, VEN_EL3_SVC_VERSION_MINOR);
+		break;
+	default:
+		WARN("Unimplemented vendor-specific EL3 Service call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+		break;
+	}
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	ven_el3_svc,
+	OEN_VEN_EL3_START,
+	OEN_VEN_EL3_END,
+	SMC_TYPE_FAST,
+	ven_el3_svc_setup,
+	ven_el3_svc_handler
+);
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 83b001a..d6c0040 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -87,6 +87,13 @@
 	uint32_t linear_id;
 	optee_context_t *optee_ctx;
 
+#if OPTEE_ALLOW_SMC_LOAD
+	if (optee_vector_table == NULL) {
+		/* OPTEE is not loaded yet, ignore this interrupt */
+		SMC_RET0(handle);
+	}
+#endif
+
 	/* Check the security state when the exception was generated */
 	assert(get_interrupt_src_ss(flags) == NON_SECURE);
 
@@ -115,6 +122,24 @@
 	SMC_RET1(&optee_ctx->cpu_ctx, read_elr_el3());
 }
 
+/*
+ * Registers an interrupt handler for S-EL1 interrupts when generated during
+ * code executing in the non-secure state. Panics if it fails to do so.
+ */
+static void register_opteed_interrupt_handler(void)
+{
+	u_register_t flags;
+	uint64_t rc;
+
+	flags = 0;
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+			opteed_sel1_interrupt_handler,
+			flags);
+	if (rc)
+		panic();
+}
+
 /*******************************************************************************
  * OPTEE Dispatcher setup. The OPTEED finds out the OPTEE entrypoint and type
  * (aarch32/aarch64) if not already known and initialises the context for entry
@@ -125,6 +150,11 @@
 #if OPTEE_ALLOW_SMC_LOAD
 	opteed_allow_load = true;
 	INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
+	/*
+	 * We must register the interrupt handler now so that the interrupt
+	 * priorities are not changed after starting the linux kernel.
+	 */
+	register_opteed_interrupt_handler();
 	return 0;
 #else
 	entry_point_info_t *optee_ep_info;
@@ -575,7 +605,6 @@
 	cpu_context_t *ns_cpu_context;
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
-	uint64_t rc;
 
 	/*
 	 * Determine which security state this SMC originated from
@@ -709,18 +738,9 @@
 			 */
 			psci_register_spd_pm_hook(&opteed_pm);
 
-			/*
-			 * Register an interrupt handler for S-EL1 interrupts
-			 * when generated during code executing in the
-			 * non-secure state.
-			 */
-			flags = 0;
-			set_interrupt_rm_flag(flags, NON_SECURE);
-			rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
-						opteed_sel1_interrupt_handler,
-						flags);
-			if (rc)
-				panic();
+#if !OPTEE_ALLOW_SMC_LOAD
+			register_opteed_interrupt_handler();
+#endif
 		}
 
 		/*
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index 3acf683..b9c83fa 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -211,7 +211,7 @@
 	running_on_single_core = psci_is_last_on_cpu_safe();
 	if (!running_on_single_core) {
 		ERROR("DRTM: invalid launch due to non-boot PE not being turned off\n");
-		return DENIED;
+		return SECONDARY_PE_NOT_OFF;
 	}
 
 	return SUCCESS;
@@ -658,7 +658,7 @@
 	drtm_dl_prepare_eret_to_dlme(&args, dlme_el);
 
 	/*
-	 * As per DRTM beta0 spec table #28 invalidate the instruction cache
+	 * As per DRTM 1.0 spec table #30 invalidate the instruction cache
 	 * before jumping to the DLME. This is required to defend against
 	 * potentially-malicious cache contents.
 	 */
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index 6005163..a7d053f 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -55,6 +55,12 @@
 	NOT_FOUND = -4,
 	INTERNAL_ERROR = -5,
 	MEM_PROTECT_INVALID = -6,
+	COPROCESSOR_ERROR = -7,
+	OUT_OF_RESOURCE = -8,
+	INVALID_DATA = -9,
+	SECONDARY_PE_NOT_OFF = -10,
+	ALREADY_CLOSED = -11,
+	TPM_ERROR = -12
 };
 
 typedef struct {
@@ -89,6 +95,7 @@
 	uint64_t dlme_addr_map_size;
 	uint64_t dlme_tpm_log_size;
 	uint64_t dlme_tcb_hashes_table_size;
+	uint64_t dlme_acpi_tables_region_size;
 	uint64_t dlme_impdef_region_size;
 } __aligned(__alignof(uint16_t /* First member's type, `uint16_t version'. */));
 
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 02dd3a8..61e1076 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,42 +11,25 @@
 #include <arch_helpers.h>
 
 #if __aarch64__
-#include <cortex_a35.h>
-#include <cortex_a510.h>
-#include <cortex_a520.h>
-#include <cortex_a53.h>
-#include <cortex_a57.h>
-#include <cortex_a55.h>
 #include <cortex_a710.h>
-#include <cortex_a72.h>
-#include <cortex_a73.h>
-#include <cortex_a75.h>
-#include <cortex_a76.h>
-#include <cortex_a77.h>
 #include <cortex_a78.h>
 #include <cortex_a78_ae.h>
 #include <cortex_a78c.h>
-#include <cortex_a715.h>
-#include <cortex_x1.h>
 #include <cortex_x2.h>
 #include <cortex_x3.h>
-#include <neoverse_n1.h>
+#include <cortex_x4.h>
 #include <neoverse_n2.h>
 #include <neoverse_v1.h>
 #include <neoverse_v2.h>
-#else
-#include <cortex_a15.h>
-#include <cortex_a17.h>
-#include <cortex_a57.h>
-#include <cortex_a9.h>
 #endif
 
-#define MAX_ERRATA_ENTRIES	32
+/* Max number of platform based errata with no workaround in EL3 */
+#define MAX_PLAT_CPU_ERRATA_ENTRIES	2
 
-#define ERRATA_LIST_END		(MAX_ERRATA_ENTRIES - 1)
+#define ERRATA_LIST_END		(MAX_PLAT_CPU_ERRATA_ENTRIES - 1)
 
 /* Default values for unused memory in the array */
-#define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX, false, false}
+#define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX}
 
 #define EXTRACT_PARTNUM(x)	((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
 
@@ -59,15 +42,11 @@
 	unsigned int em_errata_id;
 	unsigned char em_rxpx_lo;	/* lowest revision of errata applicable for the cpu */
 	unsigned char em_rxpx_hi;	/* highest revision of errata applicable for the cpu */
-	bool errata_enabled;		/* indicate if errata enabled */
-	/* flag to indicate if errata query is based out of non-arm interconnect */
-	bool non_arm_interconnect;
 };
 
 struct em_cpu_list{
-	/* field to hold cpu specific part number defined in midr reg */
-	unsigned long cpu_partnumber;
-	struct   em_cpu cpu_errata_list[MAX_ERRATA_ENTRIES];
+	unsigned long cpu_midr;	/* cpu specific part number is bit[15:4] of midr value */
+	struct   em_cpu cpu_errata_list[MAX_PLAT_CPU_ERRATA_ENTRIES];
 };
 
 int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag);
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 811adcb..0d0ecc3 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -6,6 +6,8 @@
 
 #include <assert.h>
 #include "cpu_errata_info.h"
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 #include <lib/smccc.h>
 #include <lib/utils_def.h>
 #include <services/errata_abi_svc.h>
@@ -17,541 +19,192 @@
  */
 struct em_cpu_list *cpu_ptr;
 
-extern uint8_t cpu_get_rev_var(void);
-
 /* Structure array that holds CPU specific errata information */
 struct em_cpu_list cpu_list[] = {
-#if CORTEX_A9_H_INC
-{
-	.cpu_partnumber = CORTEX_A9_MIDR,
-	.cpu_errata_list = {
-		[0] = {794073, 0x00, 0xFF, ERRATA_A9_794073},
-		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A9_H_INC */
-
-#if CORTEX_A15_H_INC
-{
-	.cpu_partnumber = CORTEX_A15_MIDR,
-	.cpu_errata_list = {
-		[0] = {816470, 0x30, 0xFF, ERRATA_A15_816470},
-		[1] = {827671, 0x30, 0xFF, ERRATA_A15_827671},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A15_H_INC */
-
-#if CORTEX_A17_H_INC
-{
-	.cpu_partnumber = CORTEX_A17_MIDR,
-	.cpu_errata_list = {
-		[0] = {852421, 0x00, 0x12, ERRATA_A17_852421},
-		[1] = {852423, 0x00, 0x12, ERRATA_A17_852423},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A17_H_INC */
-
-#if CORTEX_A35_H_INC
-{
-	.cpu_partnumber = CORTEX_A35_MIDR,
-	.cpu_errata_list = {
-		[0] = {855472, 0x00, 0x00, ERRATA_A35_855472},
-		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A35_H_INC */
-
-#if CORTEX_A53_H_INC
-{
-	.cpu_partnumber = CORTEX_A53_MIDR,
-	.cpu_errata_list = {
-		[0] = {819472, 0x00, 0x01, ERRATA_A53_819472},
-		[1] = {824069, 0x00, 0x02, ERRATA_A53_824069},
-		[2] = {826319, 0x00, 0x02, ERRATA_A53_826319},
-		[3] = {827319, 0x00, 0x02, ERRATA_A53_827319},
-		[4] = {835769, 0x00, 0x04, ERRATA_A53_835769},
-		[5] = {836870, 0x00, 0x03, ERRATA_A53_836870},
-		[6] = {843419, 0x00, 0x04, ERRATA_A53_843419},
-		[7] = {855873, 0x03, 0xFF, ERRATA_A53_855873},
-		[8] = {1530924, 0x00, 0xFF, ERRATA_A53_1530924},
-		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A53_H_INC */
-
-#if CORTEX_A55_H_INC
-{
-	.cpu_partnumber = CORTEX_A55_MIDR,
-	.cpu_errata_list = {
-		[0] = {768277, 0x00, 0x00, ERRATA_A55_768277},
-		[1] = {778703, 0x00, 0x00, ERRATA_A55_778703},
-		[2] = {798797, 0x00, 0x00, ERRATA_A55_798797},
-		[3] = {846532, 0x00, 0x01, ERRATA_A55_846532},
-		[4] = {903758, 0x00, 0x01, ERRATA_A55_903758},
-		[5] = {1221012, 0x00, 0x10, ERRATA_A55_1221012},
-		[6] = {1530923, 0x00, 0xFF, ERRATA_A55_1530923},
-		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A55_H_INC */
-
-#if CORTEX_A57_H_INC
-{
-	.cpu_partnumber = CORTEX_A57_MIDR,
-	.cpu_errata_list = {
-		[0] = {806969, 0x00, 0x00, ERRATA_A57_806969},
-		[1] = {813419, 0x00, 0x00, ERRATA_A57_813419},
-		[2] = {813420, 0x00, 0x00, ERRATA_A57_813420},
-		[3] = {814670, 0x00, 0x00, ERRATA_A57_814670},
-		[4] = {817169, 0x00, 0x01, ERRATA_A57_817169},
-		[5] = {826974, 0x00, 0x11, ERRATA_A57_826974},
-		[6] = {826977, 0x00, 0x11, ERRATA_A57_826977},
-		[7] = {828024, 0x00, 0x11, ERRATA_A57_828024},
-		[8] = {829520, 0x00, 0x12, ERRATA_A57_829520},
-		[9] = {833471, 0x00, 0x12, ERRATA_A57_833471},
-		[10] = {859972, 0x00, 0x13, ERRATA_A57_859972},
-		[11] = {1319537, 0x00, 0xFF, ERRATA_A57_1319537},
-		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A57_H_INC */
-
-#if CORTEX_A72_H_INC
-{
-	.cpu_partnumber = CORTEX_A72_MIDR,
-	.cpu_errata_list = {
-		[0] = {859971, 0x00, 0x03, ERRATA_A72_859971},
-		[1] = {1319367, 0x00, 0xFF, ERRATA_A72_1319367},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A72_H_INC */
-
-#if CORTEX_A73_H_INC
-{
-	.cpu_partnumber = CORTEX_A73_MIDR,
-	.cpu_errata_list = {
-		[0] = {852427, 0x00, 0x00, ERRATA_A73_852427},
-		[1] = {855423, 0x00, 0x01, ERRATA_A73_855423},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A73_H_INC */
-
-#if CORTEX_A75_H_INC
-{
-	.cpu_partnumber = CORTEX_A75_MIDR,
-	.cpu_errata_list = {
-		[0] = {764081, 0x00, 0x00, ERRATA_A75_764081},
-		[1] = {790748, 0x00, 0x00, ERRATA_A75_790748},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A75_H_INC */
-
-#if CORTEX_A76_H_INC
-{
-	.cpu_partnumber = CORTEX_A76_MIDR,
-	.cpu_errata_list = {
-		[0] = {1073348, 0x00, 0x10, ERRATA_A76_1073348},
-		[1] = {1130799, 0x00, 0x20, ERRATA_A76_1130799},
-		[2] = {1165522, 0x00, 0xFF, ERRATA_A76_1165522},
-		[3] = {1220197, 0x00, 0x20, ERRATA_A76_1220197},
-		[4] = {1257314, 0x00, 0x30, ERRATA_A76_1257314},
-		[5] = {1262606, 0x00, 0x30, ERRATA_A76_1262606},
-		[6] = {1262888, 0x00, 0x30, ERRATA_A76_1262888},
-		[7] = {1275112, 0x00, 0x30, ERRATA_A76_1275112},
-		[8] = {1286807, 0x00, 0x30, ERRATA_A76_1286807},
-		[9] = {1791580, 0x00, 0x40, ERRATA_A76_1791580},
-		[10] = {1868343, 0x00, 0x40, ERRATA_A76_1868343},
-		[11] = {1946160, 0x30, 0x41, ERRATA_A76_1946160},
-		[12] = {2743102, 0x00, 0x41, ERRATA_A76_2743102},
-		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A76_H_INC */
-
-#if CORTEX_A77_H_INC
-{
-	.cpu_partnumber = CORTEX_A77_MIDR,
-	.cpu_errata_list = {
-		[0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412},
-		[1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578},
-		[2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714},
-		[3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769},
-		[4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167},
-		[5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587},
-		[6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100},
-		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A77_H_INC */
-
 #if CORTEX_A78_H_INC
 {
-	.cpu_partnumber = CORTEX_A78_MIDR,
+	.cpu_midr = CORTEX_A78_MIDR,
 	.cpu_errata_list = {
-		[0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305},
-		[1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534},
-		[2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498},
-		[3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500},
-		[4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683},
-		[5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060},
-		[6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635},
-		[7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745},
-		[8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406},
-		[9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426},
-		[11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019},
-		[12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479},
-		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2712571, 0x00, 0x12},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78_H_INC */
 
 #if CORTEX_A78_AE_H_INC
 {
-	.cpu_partnumber = CORTEX_A78_AE_MIDR,
+	.cpu_midr = CORTEX_A78_AE_MIDR,
 	.cpu_errata_list = {
-		[0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500},
-		[1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502},
-		[2] = {2376748, 0x00, 0x02, ERRATA_A78_AE_2376748},
-		[3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408},
-		[4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[5 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2712574, 0x00, 0x02},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78_AE_H_INC */
 
 #if CORTEX_A78C_H_INC
 {
-	.cpu_partnumber = CORTEX_A78C_MIDR,
+	.cpu_midr = CORTEX_A78C_MIDR,
 	.cpu_errata_list = {
-		[0] = {1827430, 0x00, 0x00, ERRATA_A78C_1827430},
-		[1] = {1827440, 0x00, 0x00, ERRATA_A78C_1827440},
-		[2] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064},
-		[3] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
-		[4] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
-		[5] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
-		[6] = {2683027, 0x01, 0x02, ERRATA_A78C_2683027},
-		[7] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[8] = {2743232, 0x01, 0x02, ERRATA_A78C_2743232},
-		[9] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
-		[10] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
-		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2712575, 0x01, 0x02},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78C_H_INC */
 
-#if CORTEX_X1_H_INC
-{
-	.cpu_partnumber = CORTEX_X1_MIDR,
-	.cpu_errata_list = {
-		[0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305},
-		[1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534},
-		[2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429},
-		[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_X1_H_INC */
-
-#if NEOVERSE_N1_H_INC
-{
-	.cpu_partnumber = NEOVERSE_N1_MIDR,
-	.cpu_errata_list = {
-		[0] = {1043202, 0x00, 0x10, ERRATA_N1_1043202},
-		[1] = {1073348, 0x00, 0x10, ERRATA_N1_1073348},
-		[2] = {1130799, 0x00, 0x20, ERRATA_N1_1130799},
-		[3] = {1165347, 0x00, 0x20, ERRATA_N1_1165347},
-		[4] = {1207823, 0x00, 0x20, ERRATA_N1_1207823},
-		[5] = {1220197, 0x00, 0x20, ERRATA_N1_1220197},
-		[6] = {1257314, 0x00, 0x30, ERRATA_N1_1257314},
-		[7] = {1262606, 0x00, 0x30, ERRATA_N1_1262606},
-		[8] = {1262888, 0x00, 0x30, ERRATA_N1_1262888},
-		[9] = {1275112, 0x00, 0x30, ERRATA_N1_1275112},
-		[10] = {1315703, 0x00, 0x30, ERRATA_N1_1315703},
-		[11] = {1542419, 0x30, 0x40, ERRATA_N1_1542419},
-		[12] = {1868343, 0x00, 0x40, ERRATA_N1_1868343},
-		[13] = {1946160, 0x30, 0x41, ERRATA_N1_1946160},
-		[14] = {2743102, 0x00, 0x41, ERRATA_N1_2743102},
-		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* NEOVERSE_N1_H_INC */
-
 #if NEOVERSE_V1_H_INC
 {
-	.cpu_partnumber = NEOVERSE_V1_MIDR,
+	.cpu_midr = NEOVERSE_V1_MIDR,
 	.cpu_errata_list = {
-		[0] = {1618635, 0x00, 0x00, ERRATA_V1_1618635},
-		[1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420},
-		[2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573},
-		[3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267},
-		[4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756},
-		[5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577},
-		[6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096},
-		[7] = {2108267, 0x00, 0x12, ERRATA_V1_2108267},
-		[8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242},
-		[9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392},
-		[10] = {2294912, 0x00, 0x12, ERRATA_V1_2294912},
-		[11] = {2348377, 0x00, 0x11, ERRATA_V1_2348377},
-		[12] = {2372203, 0x00, 0x11, ERRATA_V1_2372203},
-		[13] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[14] = {2743093, 0x00, 0x12, ERRATA_V1_2743093},
-		[15] = {2743233, 0x00, 0x12, ERRATA_V1_2743233},
-		[16] = {2779461, 0x00, 0x12, ERRATA_V1_2779461},
-		[17 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701953, 0x00, 0x11},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V1_H_INC */
 
 #if CORTEX_A710_H_INC
 {
-	.cpu_partnumber = CORTEX_A710_MIDR,
+	.cpu_midr = CORTEX_A710_MIDR,
 	.cpu_errata_list = {
-		[0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031},
-		[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
-		[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
-		[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
-		[4] = {2058056, 0x00, 0x21, ERRATA_A710_2058056},
-		[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
-		[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
-		[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
-		[8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715},
-		[9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384},
-		[10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065},
-		[11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622},
-		[12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219},
-		[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
-		[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[15] = {2742423, 0x00, 0x21, ERRATA_A710_2742423},
-		[16] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
-		[17] = {2778471, 0x00, 0x21, ERRATA_A710_2778471},
-		[18 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701952, 0x00, 0x21},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A710_H_INC */
 
 #if NEOVERSE_N2_H_INC
 {
-	.cpu_partnumber = NEOVERSE_N2_MIDR,
+	.cpu_midr = NEOVERSE_N2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655},
-		[1] = {2009478, 0x00, 0x00, ERRATA_N2_2009478},
-		[2] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
-		[3] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
-		[4] = {2138953, 0x00, 0x03, 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] = {2340933, 0x00, 0x00, ERRATA_N2_2340933},
-		[13] = {2346952, 0x00, 0x02, ERRATA_N2_2346952},
-		[14] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
-		[15] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
-		[16] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[17] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
-		[18] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
-		[19] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
-		[20 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2728475, 0x00, 0x02},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_N2_H_INC */
 
 #if CORTEX_X2_H_INC
 {
-	.cpu_partnumber = CORTEX_X2_MIDR,
+	.cpu_midr = CORTEX_X2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765},
-		[1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096},
-		[2] = {2058056, 0x00, 0x21, ERRATA_X2_2058056},
-		[3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180},
-		[4] = {2083908, 0x20, 0x20, ERRATA_X2_2083908},
-		[5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715},
-		[6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384},
-		[7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622},
-		[8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105},
-		[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[10] = {2742423, 0x00, 0x21, ERRATA_X2_2742423},
-		[11] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
-		[12] = {2778471, 0x00, 0x21, ERRATA_X2_2778471},
-		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701952, 0x00, 0x21},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_X2_H_INC */
 
-#if CORTEX_A510_H_INC
-{
-	.cpu_partnumber = CORTEX_A510_MIDR,
-	.cpu_errata_list = {
-		[0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240},
-		[1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909},
-		[2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739},
-		[3] = {2080326, 0x02, 0x02, ERRATA_A510_2080326},
-		[4] = {2172148, 0x00, 0x10, ERRATA_A510_2172148},
-		[5] = {2218950, 0x00, 0x10, ERRATA_A510_2218950},
-		[6] = {2250311, 0x00, 0x10, ERRATA_A510_2250311},
-		[7] = {2288014, 0x00, 0x10, ERRATA_A510_2288014},
-		[8] = {2347730, 0x00, 0x11, ERRATA_A510_2347730},
-		[9] = {2371937, 0x00, 0x11, ERRATA_A510_2371937},
-		[10] = {2666669, 0x00, 0x11, ERRATA_A510_2666669},
-		[11] = {2684597, 0x00, 0x12, ERRATA_A510_2684597},
-		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A510_H_INC */
-
 #if NEOVERSE_V2_H_INC
 {
-	.cpu_partnumber = NEOVERSE_V2_MIDR,
+	.cpu_midr = NEOVERSE_V2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2331132, 0x00, 0x02, ERRATA_V2_2331132},
-		[1] = {2618597, 0x00, 0x01, ERRATA_V2_2618597},
-		[2] = {2662553, 0x00, 0x01, ERRATA_V2_2662553},
-		[3] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[4] = {2719105, 0x00, 0x01, ERRATA_V2_2719105},
-		[5] = {2743011, 0x00, 0x01, ERRATA_V2_2743011},
-		[6] = {2779510, 0x00, 0x01, ERRATA_V2_2779510},
-		[7] = {2801372, 0x00, 0x01, ERRATA_V2_2801372},
-		[8 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2719103, 0x00, 0x01},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V2_H_INC */
 
-#if CORTEX_A715_H_INC
-{
-	.cpu_partnumber = CORTEX_A715_MIDR,
-	.cpu_errata_list = {
-		[0] = {2561034, 0x10, 0x10, ERRATA_A715_2561034},
-		[1] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A715_H_INC */
-
 #if CORTEX_X3_H_INC
 {
-	.cpu_partnumber = CORTEX_X3_MIDR,
+	.cpu_midr = CORTEX_X3_MIDR,
 	.cpu_errata_list = {
-		[0] = {2070301, 0x00, 0x12, ERRATA_X3_2070301},
-		[1] = {2266875, 0x00, 0x10, ERRATA_X3_2266875},
-		[2] = {2302506, 0x00, 0x11, ERRATA_X3_2302506},
-		[3] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
-		[4] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
-		[5] = {2641945, 0x00, 0x10, ERRATA_X3_2641945},
-		[6] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
-		[7] = {2743088, 0x00, 0x11, ERRATA_X3_2743088},
-		[8] = {2779509, 0x00, 0x11, ERRATA_X3_2779509},
-		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701951, 0x00, 0x11},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_X3_H_INC */
 
-#if CORTEX_A520_H_INC
+#if CORTEX_X4_H_INC
 {
-	.cpu_partnumber = CORTEX_A520_MIDR,
+	.cpu_midr = CORTEX_X4_MIDR,
 	.cpu_errata_list = {
-		[0] = {2630792, 0x00, 0x01, ERRATA_A520_2630792},
-		[1] = {2858100, 0x00, 0x01, ERRATA_A520_2858100},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701112, 0x00, 0x00},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
-#endif /* CORTEX_A520_H_INC */
+#endif /* CORTEX_X4_H_INC */
 
 };
 
-/*
- * Function to do binary search and check for the specific errata ID
- * in the array of structures specific to the cpu identified.
- */
-int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val)
-{
-	int low_index = 0U, mid_index = 0U;
+#if ERRATA_NON_ARM_INTERCONNECT
 
-	int high_index = MAX_ERRATA_ENTRIES - 1;
+/* Check if the errata is enabled for non-arm interconnect */
+static int32_t non_arm_interconnect_errata(uint32_t errata_id, long rev_var)
+{
+	int32_t ret_val = EM_UNKNOWN_ERRATUM;
 
-	assert(ptr != NULL);
+	/* Determine the number of cpu listed in the cpu list */
+	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
 
-	/*
-	 * Pointer to the errata list of the cpu that matches
-	 * extracted partnumber in the cpu list
-	 */
-	struct em_cpu *erratum_ptr = NULL;
+	/* Read the midr reg to extract cpu, revision and variant info */
+	uint32_t midr_val = read_midr();
 
-	while (low_index <= high_index) {
-		mid_index = (low_index + high_index) / 2;
+	for (uint8_t i = 0U; i < size_cpulist; i++) {
+		cpu_ptr = &cpu_list[i];
+		/*
+		 * If the cpu partnumber in the cpu list, matches the midr
+		 * part number, check to see if the errata ID matches
+		 */
+		if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_midr)) {
 
-		erratum_ptr = &ptr->cpu_errata_list[mid_index];
-		assert(erratum_ptr != NULL);
+			struct em_cpu *ptr = NULL;
 
-		if (erratum_id < erratum_ptr->em_errata_id) {
-			high_index = mid_index - 1;
-		} else if (erratum_id > erratum_ptr->em_errata_id) {
-			low_index = mid_index + 1;
-		} else if (erratum_id == erratum_ptr->em_errata_id) {
-			if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \
-				erratum_ptr->em_rxpx_hi)) {
-				if ((erratum_ptr->errata_enabled) && \
-				(!(erratum_ptr->non_arm_interconnect))) {
-					return EM_HIGHER_EL_MITIGATION;
+			for (int j = 0; j < MAX_PLAT_CPU_ERRATA_ENTRIES; j++) {
+				ptr = &cpu_ptr->cpu_errata_list[j];
+				assert(ptr != NULL);
+				if (errata_id == ptr->em_errata_id) {
+					if (RXPX_RANGE(rev_var, ptr->em_rxpx_lo, ptr->em_rxpx_hi)) {
+						ret_val = EM_AFFECTED;
+						break;
+					}
+					ret_val = EM_NOT_AFFECTED;
+					break;
 				}
-				return EM_AFFECTED;
 			}
-			return EM_NOT_AFFECTED;
+			break;
 		}
 	}
-	/* no matching errata ID */
-	return EM_UNKNOWN_ERRATUM;
+	return ret_val;
 }
+#endif
 
 /* Function to check if the errata exists for the specific CPU and rxpx */
 int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
 {
-	/*
-	 * Read MIDR value and extract the revision, variant and partnumber
-	 */
-	static uint32_t midr_val, cpu_partnum;
-	static uint8_t  cpu_rxpx_val;
-	int32_t ret_val = EM_UNKNOWN_ERRATUM;
+	int32_t ret_val;
+	struct cpu_ops *cpu_ops;
+	struct erratum_entry *entry, *end;
+	long rev_var;
 
-	/* Determine the number of cpu listed in the cpu list */
-	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
+	ret_val = EM_UNKNOWN_ERRATUM;
+	rev_var = cpu_get_rev_var();
 
-	/* Read the midr reg to extract cpu, revision and variant info */
-	midr_val = read_midr();
+#if ERRATA_NON_ARM_INTERCONNECT
+	ret_val = non_arm_interconnect_errata(errata_id, rev_var);
+	if (ret_val != EM_UNKNOWN_ERRATUM) {
+		return ret_val;
+	}
+#endif
 
-	/* Extract revision and variant from the MIDR register */
-	cpu_rxpx_val = cpu_get_rev_var();
+	cpu_ops = get_cpu_ops_ptr();
+	assert(cpu_ops != NULL);
 
-	/* Extract the cpu partnumber and check if the cpu is in the cpu list */
-	cpu_partnum = EXTRACT_PARTNUM(midr_val);
+	entry = cpu_ops->errata_list_start;
+	assert(entry != NULL);
 
-	for (uint8_t i = 0; i < size_cpulist; i++) {
-		cpu_ptr = &cpu_list[i];
-		uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber);
+	end = cpu_ops->errata_list_end;
+	assert(end != NULL);
 
-		if (partnum_extracted == cpu_partnum) {
-			/*
-			 * If the midr value is in the cpu list, binary search
-			 * for the errata ID and specific revision in the list.
-			 */
-			ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val);
-			break;
+	end--; /* point to the last erratum entry of the queried cpu */
+
+	while ((entry <= end) && (ret_val == EM_UNKNOWN_ERRATUM)) {
+		if (entry->id == errata_id) {
+			if (entry->check_func(rev_var)) {
+				if (entry->chosen)
+					return EM_HIGHER_EL_MITIGATION;
+				else
+					return EM_AFFECTED;
+			}
+			return EM_NOT_AFFECTED;
 		}
+		entry += 1;
 	}
 	return ret_val;
 }
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index fb096bc..6ccb003 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -109,8 +109,8 @@
 
 static void rmm_el2_context_init(el2_sysregs_t *regs)
 {
-	regs->ctx_regs[CTX_SPSR_EL2 >> 3] = REALM_SPSR_EL2;
-	regs->ctx_regs[CTX_SCTLR_EL2 >> 3] = SCTLR_EL2_RES1;
+	write_el2_ctx_common(regs, spsr_el2, REALM_SPSR_EL2);
+	write_el2_ctx_common(regs, sctlr_el2, SCTLR_EL2_RES1);
 }
 
 /*******************************************************************************
@@ -202,7 +202,7 @@
 	int rc;
 
 	/* Make sure RME is supported. */
-	assert(get_armv9_2_feat_rme_support() != 0U);
+	assert(is_feat_rme_present());
 
 	rmm_ep_info = bl31_plat_get_next_image_ep_info(REALM);
 	if (rmm_ep_info == NULL) {
@@ -232,8 +232,10 @@
 	assert((shared_buf_size == SZ_4K) &&
 					((void *)shared_buf_base != NULL));
 
-	/* Load the boot manifest at the beginning of the shared area */
+	/* Zero out and load the boot manifest at the beginning of the share area */
 	manifest = (struct rmm_manifest *)shared_buf_base;
+	(void)memset((void *)manifest, 0, sizeof(struct rmm_manifest));
+
 	rc = plat_rmmd_load_manifest(manifest);
 	if (rc != 0) {
 		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 33f2fb0..b75483c 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <plat/common/platform.h>
 #include <services/rmm_core_manifest.h>
@@ -86,7 +87,7 @@
 /* Main function for TRP */
 void trp_main(void)
 {
-	NOTICE("TRP: %s\n", version_string);
+	NOTICE("TRP: %s\n", build_version_string);
 	NOTICE("TRP: %s\n", build_message);
 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 72bc33f..c58adba 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -13,6 +13,7 @@
 #include <arch_features.h>
 #include <bl31/ehf.h>
 #include <bl31/interrupt_mgmt.h>
+#include <bl31/sync_handle.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -237,9 +238,7 @@
 /*
  * Prepare for ERET:
  * - Set the ELR to the registered handler address
- * - Set the SPSR register as described in the SDEI documentation and
- *   the AArch64.TakeException() pseudocode function in
- *   ARM DDI 0487F.c page J1-7635
+ * - Set the SPSR register by calling the common create_spsr() function
  */
 
 static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ctx)
@@ -250,57 +249,7 @@
 
 	u_register_t interrupted_pstate = disp_ctx->spsr_el3;
 
-	/* Check the SPAN bit in the client el SCTLR */
-	u_register_t client_el_sctlr;
-
-	if (client_el == MODE_EL2) {
-		client_el_sctlr = read_sctlr_el2();
-	} else {
-		client_el_sctlr = read_sctlr_el1();
-	}
-
-	/*
-	 * Check whether to force the PAN bit or use the value in the
-	 * interrupted EL according to the check described in
-	 * TakeException. Since the client can only be Non-Secure
-	 * EL2 or El1 some of the conditions in ElIsInHost() we know
-	 * will always be True.
-	 * When the client_el is EL2 we know that there will be a SPAN
-	 * bit in SCTLR_EL2 as we have already checked for the condition
-	 * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1
-	 */
-	u_register_t hcr_el2 = read_hcr();
-	bool el_is_in_host = (read_feat_vhe_id_field() != 0U) &&
-			     (hcr_el2 & HCR_TGE_BIT) &&
-			     (hcr_el2 & HCR_E2H_BIT);
-
-	if (is_feat_pan_supported() &&
-	    ((client_el == MODE_EL1) ||
-		(client_el == MODE_EL2 && el_is_in_host)) &&
-	    ((client_el_sctlr & SCTLR_SPAN_BIT) == 0U)) {
-		sdei_spsr |=  SPSR_PAN_BIT;
-	} else {
-		sdei_spsr |= (interrupted_pstate & SPSR_PAN_BIT);
-	}
-
-	/* If SSBS is implemented, take the value from the client el SCTLR */
-	u_register_t ssbs_enabled = (read_id_aa64pfr1_el1()
-					>> ID_AA64PFR1_EL1_SSBS_SHIFT)
-					& ID_AA64PFR1_EL1_SSBS_MASK;
-	if (ssbs_enabled != SSBS_UNAVAILABLE) {
-		u_register_t  ssbs_bit = ((client_el_sctlr & SCTLR_DSSBS_BIT)
-						>> SCTLR_DSSBS_SHIFT)
-						<< SPSR_SSBS_SHIFT_AARCH64;
-		sdei_spsr |= ssbs_bit;
-	}
-
-	/* If MTE is implemented in the client el set the TCO bit */
-	if (is_feat_mte_supported()) {
-		sdei_spsr |= SPSR_TCO_BIT_AARCH64;
-	}
-
-	/* Take the DIT field from the pstate of the interrupted el */
-	sdei_spsr |= (interrupted_pstate & SPSR_DIT_BIT);
+	sdei_spsr = create_spsr(interrupted_pstate, client_el);
 
 	cm_set_elr_spsr_el3(NON_SECURE, (uintptr_t) se->ep, sdei_spsr);
 }
diff --git a/services/std_svc/spmd/spmd_logical_sp.c b/services/std_svc/spmd/spmd_logical_sp.c
index d992187..64d506e 100644
--- a/services/std_svc/spmd/spmd_logical_sp.c
+++ b/services/std_svc/spmd/spmd_logical_sp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -528,9 +528,10 @@
 	}
 
 	/* 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);
+#else
+	cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 	spmd_build_ffa_info_get_regs(ctx, target_uuid, start_index, tag);
@@ -548,9 +549,10 @@
 
 	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);
+#else
+	cm_el1_sysregs_context_restore(NON_SECURE);
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 	return true;
@@ -667,9 +669,10 @@
 	}
 
 	/* 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);
+#else
+	cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 	/*
@@ -707,9 +710,10 @@
 				ffa_endpoint_destination(x1)));
 	}
 
-	cm_el1_sysregs_context_restore(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(NON_SECURE);
+#else
+	cm_el1_sysregs_context_restore(NON_SECURE);
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 7572adf..0715b13 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -227,9 +227,10 @@
 	assert(handle == cm_get_context(NON_SECURE));
 
 	/* 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);
+#else
+	cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 	/* Convey the event to the SPMC through the FFA_INTERRUPT interface. */
@@ -252,9 +253,10 @@
 
 	ctx->secure_interrupt_ongoing = false;
 
-	cm_el1_sysregs_context_restore(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(NON_SECURE);
+#else
+	cm_el1_sysregs_context_restore(NON_SECURE);
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 
@@ -593,14 +595,17 @@
 	 */
 #if (EL3_EXCEPTION_HANDLING == 0)
 	/*
-	 * Register an interrupt handler routing Group0 interrupts to SPMD
-	 * while the NWd is running.
+	 * If EL3 interrupts are supported by the platform, register an
+	 * interrupt handler routing Group0 interrupts to SPMD while the NWd is
+	 * running.
 	 */
-	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
-					     spmd_group0_interrupt_handler_nwd,
-					     flags);
-	if (rc != 0) {
-		panic();
+	if (plat_ic_has_interrupt_type(INTR_TYPE_EL3)) {
+		rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+						     spmd_group0_interrupt_handler_nwd,
+						     flags);
+		if (rc != 0) {
+			panic();
+		}
 	}
 #endif
 
@@ -685,9 +690,6 @@
 
 	/* Save incoming security state */
 #if SPMD_SPM_AT_SEL2
-	if (secure_state_in == NON_SECURE) {
-		cm_el1_sysregs_context_save(secure_state_in);
-	}
 	cm_el2_sysregs_context_save(secure_state_in);
 #else
 	cm_el1_sysregs_context_save(secure_state_in);
@@ -695,9 +697,6 @@
 
 	/* Restore outgoing security state */
 #if SPMD_SPM_AT_SEL2
-	if (secure_state_out == NON_SECURE) {
-		cm_el1_sysregs_context_restore(secure_state_out);
-	}
 	cm_el2_sysregs_context_restore(secure_state_out);
 #else
 	cm_el1_sysregs_context_restore(secure_state_out);
@@ -948,9 +947,10 @@
 				break;
 			}
 			/* Save non-secure system registers context */
-			cm_el1_sysregs_context_save(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 			cm_el2_sysregs_context_save(NON_SECURE);
+#else
+			cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 			/*
diff --git a/tools/amlogic/Makefile b/tools/amlogic/Makefile
index 5ff26e5..7a53437 100644
--- a/tools/amlogic/Makefile
+++ b/tools/amlogic/Makefile
@@ -10,11 +10,11 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 PROJECT := doimage${BIN_EXT}
 OBJECTS := doimage.o
-V := 0
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
 
@@ -24,26 +24,20 @@
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 21523f6..16f4aa3 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -5,7 +5,6 @@
 #
 
 PLAT		:= none
-V		?= 0
 DEBUG		:= 0
 CRTTOOL		?= cert_create${BIN_EXT}
 BINARY		:= $(notdir ${CRTTOOL})
@@ -16,8 +15,10 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
+include ${MAKE_HELPERS_DIRECTORY}utilities.mk
 
 ifneq (${PLAT},none)
 TF_PLATFORM_ROOT	:=	../../plat/
@@ -60,13 +61,7 @@
   HOSTCCFLAGS += -O2 -DLOG_LEVEL=20
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
-HOSTCCFLAGS += ${DEFINES}
+HOSTCCFLAGS += ${DEFINES} -DPLAT_MSG=$(call escape-shell,"$(PLAT_MSG)")
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
 # computed value.
 HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
@@ -89,23 +84,20 @@
 all: --openssl ${BINARY}
 
 ${BINARY}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
-                const char platform_msg[] = "${PLAT_MSG}";' | \
-                $(host-cc) -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
-	${Q}$(host-cc) src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 --openssl:
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+	$(call SHELL_DELETE_ALL,${OBJECTS})
 
 realclean: clean
 	$(call SHELL_DELETE,${BINARY})
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 2513213..4a36ee8 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -22,7 +22,6 @@
 #include "sha.h"
 
 #define SERIAL_RAND_BITS	64
-#define RSA_SALT_LEN		32
 
 cert_t *certs;
 unsigned int num_certs;
@@ -152,7 +151,7 @@
 			goto END;
 		}
 
-		if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN)) {
+		if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, EVP_MD_size(get_digest(md_alg)))) {
 			ERR_print_errors_fp(stdout);
 			goto END;
 		}
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 04214aa..f6ceeda 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -168,6 +168,7 @@
 	}
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
@@ -177,6 +178,7 @@
 {
 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
 }
+#endif
 #endif /* USING_OPENSSL3 */
 #endif /* OPENSSL_NO_EC */
 
@@ -185,8 +187,10 @@
 	[KEY_ALG_RSA] = key_create_rsa,
 #ifndef OPENSSL_NO_EC
 	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
 	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
+#endif
 #endif /* OPENSSL_NO_EC */
 };
 
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index f10a768..edc2d68 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,10 +66,8 @@
 static int save_keys;
 static int print_cert;
 
-/* Info messages created in the Makefile */
-extern const char build_msg[];
-extern const char platform_msg[];
-
+static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
+static const char platform_msg[] = PLAT_MSG;
 
 static char *strdup(const char *str)
 {
@@ -85,8 +83,10 @@
 	[KEY_ALG_RSA] = "rsa",
 #ifndef OPENSSL_NO_EC
 	[KEY_ALG_ECDSA_NIST] = "ecdsa",
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	[KEY_ALG_ECDSA_BRAINPOOL_R] = "ecdsa-brainpool-regular",
 	[KEY_ALG_ECDSA_BRAINPOOL_T] = "ecdsa-brainpool-twisted",
+#endif
 #endif /* OPENSSL_NO_EC */
 };
 
@@ -269,8 +269,12 @@
 	},
 	{
 		{ "key-alg", required_argument, NULL, 'a' },
-		"Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, " \
+		"Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, "
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 		"'ecdsa', 'ecdsa-brainpool-regular', 'ecdsa-brainpool-twisted'"
+#else
+		"'ecdsa'"
+#endif
 	},
 	{
 		{ "key-size", required_argument, NULL, 'b' },
diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index d0efab8..56cb21a 100644
--- a/tools/conventional-changelog-tf-a/package.json
+++ b/tools/conventional-changelog-tf-a/package.json
@@ -1,6 +1,6 @@
 {
   "name": "conventional-changelog-tf-a",
-  "version": "2.10.0",
+  "version": "2.11.0",
   "license": "BSD-3-Clause",
   "private": true,
   "main": "index.js",
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 83f2f57..0210c36 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,10 +1,10 @@
 #
+# Copyright (c) 2024, Arm Limited. All rights reserved.
 # Copyright (c) 2019-2022, Linaro Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-V		?= 0
 BUILD_INFO	?= 1
 DEBUG		:= 0
 ENCTOOL		?= encrypt_fw${BIN_EXT}
@@ -16,6 +16,7 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
@@ -38,11 +39,6 @@
   HOSTCCFLAGS += -O2 -DLOG_LEVEL=10
 endif
 endif
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
 
 HOSTCCFLAGS += ${DEFINES}
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
@@ -68,22 +64,20 @@
 all: --openssl ${BINARY}
 
 ${BINARY}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
-                $(host-cc) -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
-	${Q}$(host-cc) src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 --openssl:
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+	$(call SHELL_DELETE_ALL,${OBJECTS})
 
 realclean: clean
 	$(call SHELL_DELETE,${BINARY})
diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c
index 39b7af7..6e43e73 100644
--- a/tools/encrypt_fw/src/main.c
+++ b/tools/encrypt_fw/src/main.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, Linaro Limited. All rights reserved.
  * Author: Sumit Garg <sumit.garg@linaro.org>
  *
@@ -25,8 +26,7 @@
 
 /* Global options */
 
-/* Info messages created in the Makefile */
-extern const char build_msg[];
+static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
 
 static char *key_algs_str[] = {
 	[KEY_ALG_GCM] = "gcm",
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 865ff4c..23c8e64 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -9,13 +9,13 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 FIPTOOL ?= fiptool${BIN_EXT}
 PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
-V ?= 0
 STATIC ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
@@ -55,12 +55,6 @@
 
 HOSTCCFLAGS += ${DEFINES}
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 ifneq (${PLAT},)
 TF_PLATFORM_ROOT	:=	../../plat/
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
@@ -81,22 +75,22 @@
 all: --openssl ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@ $(LDOPTS)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@ $(LDOPTS)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
 
 -include $(DEPS)
 
 --openssl:
 ifeq ($(STATIC),0)
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 endif # STATIC
 
diff --git a/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
index 903310b..792593f 100644
--- a/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
+++ b/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
@@ -13,44 +13,44 @@
 
 toc_entry_t plat_def_toc_entries[] = {
 	{
-		.name = "RSS Firmware BL1_2 image",
-		.uuid = UUID_RSS_FIRMWARE_BL1_2,
-		.cmdline_name = "rss-bl1_2"
+		.name = "RSE Firmware BL1_2 image",
+		.uuid = UUID_RSE_FIRMWARE_BL1_2,
+		.cmdline_name = "rse-bl1_2"
 	},
 	{
-		.name = "RSS Firmware BL2 image",
-		.uuid = UUID_RSS_FIRMWARE_BL2,
-		.cmdline_name = "rss-bl2"
+		.name = "RSE Firmware BL2 image",
+		.uuid = UUID_RSE_FIRMWARE_BL2,
+		.cmdline_name = "rse-bl2"
 	},
 	{
-		.name = "RSS Firmware SCP BL1 image",
-		.uuid = UUID_RSS_FIRMWARE_SCP_BL1,
-		.cmdline_name = "rss-scp-bl1"
+		.name = "RSE Firmware SCP BL1 image",
+		.uuid = UUID_RSE_FIRMWARE_SCP_BL1,
+		.cmdline_name = "rse-scp-bl1"
 	},
 	{
-		.name = "RSS Firmware AP BL1 image",
-		.uuid = UUID_RSS_FIRMWARE_AP_BL1,
-		.cmdline_name = "rss-ap-bl1"
+		.name = "RSE Firmware AP BL1 image",
+		.uuid = UUID_RSE_FIRMWARE_AP_BL1,
+		.cmdline_name = "rse-ap-bl1"
 	},
 	{
-		.name = "RSS Firmware non-secure image",
-		.uuid = UUID_RSS_FIRMWARE_NS,
-		.cmdline_name = "rss-ns"
+		.name = "RSE Firmware non-secure image",
+		.uuid = UUID_RSE_FIRMWARE_NS,
+		.cmdline_name = "rse-ns"
 	},
 	{
-		.name = "RSS Firmware secure image",
-		.uuid = UUID_RSS_FIRMWARE_S,
-		.cmdline_name = "rss-s"
+		.name = "RSE Firmware secure image",
+		.uuid = UUID_RSE_FIRMWARE_S,
+		.cmdline_name = "rse-s"
 	},
 	{
-		.name = "RSS Firmware non-secure SIC tables",
-		.uuid = UUID_RSS_SIC_TABLES_NS,
-		.cmdline_name = "rss-sic-tables-ns"
+		.name = "RSE Firmware non-secure SIC tables",
+		.uuid = UUID_RSE_SIC_TABLES_NS,
+		.cmdline_name = "rse-sic-tables-ns"
 	},
 	{
-		.name = "RSS Firmware secure SIC tables",
-		.uuid = UUID_RSS_SIC_TABLES_S,
-		.cmdline_name = "rss-sic-tables-s"
+		.name = "RSE Firmware secure SIC tables",
+		.uuid = UUID_RSE_SIC_TABLES_S,
+		.cmdline_name = "rse-sic-tables-s"
 	},
 
 	{
diff --git a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/st/plat_def_uuid_config.c
similarity index 71%
rename from tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/st/plat_def_uuid_config.c
index 4df4144..8d3329f 100644
--- a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
+++ b/tools/fiptool/plat_fiptool/st/plat_def_uuid_config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,11 @@
 
 toc_entry_t plat_def_toc_entries[] = {
 	{
+		.name = "DDR_FW",
+		.uuid = UUID_DDR_FW,
+		.cmdline_name = "ddr-fw"
+	},
+	{
 		.name = "STM32MP CONFIG CERT",
 		.uuid = UUID_STM32MP_CONFIG_CERT,
 		.cmdline_name = "stm32mp-cfg-cert"
diff --git a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk b/tools/fiptool/plat_fiptool/st/plat_fiptool.mk
similarity index 71%
rename from tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
rename to tools/fiptool/plat_fiptool/st/plat_fiptool.mk
index 0d69dbd..494715c 100644
--- a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/st/plat_fiptool.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,14 +9,14 @@
 # in the plat_def_toc_entries[].
 PLAT_DEF_UUID_FILE_NAME	:= plat_def_uuid_config
 
-INCLUDE_PATHS		+= -I${PLAT_DIR}/include -I./
+INCLUDE_PATHS		+= -I../../plat/st/common/include -I./
 
 PLAT_DEF_UUID		:= yes
 
 ifeq (${PLAT_DEF_UUID},yes)
 HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
 
-${PLAT_DEF_UUID_FILE_NAME}.o: plat_fiptool/st/stm32mp1/${PLAT_DEF_UUID_FILE_NAME}.c
+${PLAT_DEF_UUID_FILE_NAME}.o: plat_fiptool/st/${PLAT_DEF_UUID_FILE_NAME}.c
 	$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 PLAT_OBJECTS += ${PLAT_DEF_UUID_FILE_NAME}.o
diff --git a/tools/marvell/doimage/Makefile b/tools/marvell/doimage/Makefile
index 6e59aa2..488b768 100644
--- a/tools/marvell/doimage/Makefile
+++ b/tools/marvell/doimage/Makefile
@@ -6,6 +6,7 @@
 
 toolchains := host
 
+include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
 PROJECT = doimage
@@ -36,16 +37,16 @@
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
-	${Q}${RM} ${PROJECT}
-	${Q}${RM} ${OBJECTS}
+	$(q)${RM} ${PROJECT}
+	$(q)${RM} ${OBJECTS}
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index b6b3b04..7648b7f 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -9,13 +9,13 @@
 MAKE_HELPERS_DIRECTORY := ../../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 PROJECT_1 := create_pbl${BIN_EXT}
 OBJECTS_1 := create_pbl.o
 PROJECT_2 := byte_swap${BIN_EXT}
 OBJECTS_2 := byte_swap.o
-V ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 CFLAGS := -Wall -Werror -pedantic -std=c99
@@ -26,12 +26,6 @@
 endif
 LDLIBS :=
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 INCLUDE_PATHS :=
 
 .PHONY: all clean distclean
@@ -39,22 +33,22 @@
 all: create_pbl byte_swap
 
 ${PROJECT_1}: ${OBJECTS_1} Makefile
-	@echo "  LD      $@"
-	${Q}$(host-cc) ${OBJECTS_1} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  LD      $@"
+	$(q)$(host-cc) ${OBJECTS_1} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ${PROJECT_2}: ${OBJECTS_2} Makefile
-	@echo "  LD      $@"
-	${Q}$(host-cc) ${OBJECTS_2} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  LD      $@"
+	$(q)$(host-cc) ${OBJECTS_2} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c %.h Makefile
-	@echo "  CC      $<"
-	${Q}$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  CC      $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT_1} ${OBJECTS_1})
diff --git a/tools/nxp/create_pbl/pbl_ch2.mk b/tools/nxp/create_pbl/pbl_ch2.mk
index e6f1d8b..bf05a12 100644
--- a/tools/nxp/create_pbl/pbl_ch2.mk
+++ b/tools/nxp/create_pbl/pbl_ch2.mk
@@ -15,12 +15,12 @@
 ifeq ($(SECURE_BOOT),yes)
 pbl: ${BUILD_PLAT}/bl2.bin
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# Generate header for bl2.bin
-	$(Q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
 	# Compile create_pbl tool
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
 	# Add bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE}\
 			-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl ;\
@@ -31,7 +31,7 @@
 # Swapping of RCW is required for QSPi Chassis 2 devices
 ifeq (${BOOT_MODE}, qspi)
 ifeq ($(SWAP),1)
-	${Q}echo "Byteswapping RCW for QSPI"
+	$(s)echo "Byteswapping RCW for QSPI"
 	${BYTE_SWAP} ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl;
 endif # SWAP
 endif # BOOT_MODE
@@ -39,22 +39,19 @@
 endif
 else  # NON SECURE_BOOT
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# -a option appends the image for Chassis 3 devices in case of non secure boot
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE} \
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl ;
 # Swapping of RCW is required for QSPi Chassis 2 devices
 ifeq (${BOOT_MODE}, qspi)
 ifeq ($(SWAP),1)
-	${Q}echo "Byteswapping RCW for QSPI"
+	$(s)echo "Byteswapping RCW for QSPI"
 	${BYTE_SWAP} ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl;
 endif # SWAP
 endif # BOOT_MODE
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
 endif
 endif # SECURE_BOOT
-
-
-
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index 9283474..15129e4 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -21,13 +21,13 @@
 ifeq ($(SECURE_BOOT),yes)
 pbl: ${BUILD_PLAT}/bl2.bin
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# Generate header for bl2.bin
-	$(Q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
 
 	# Compile create_pbl tool
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
 
 	# Add Block Copy command for bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE}\
@@ -39,14 +39,14 @@
 			-o ${BUILD_PLAT}/rcw_sec.pbl
 
 	# Sign and add "Load Security Header command to PBI commands
-	$(Q)$(CST_DIR)/create_hdr_pbi --out ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl --in ${BUILD_PLAT}/rcw_sec.pbl ${PBI_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_pbi --out ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl --in ${BUILD_PLAT}/rcw_sec.pbl ${PBI_INPUT_FILE}
 
 	# Append the bl2_hdr to the RCW image
-	@echo "${bl2_hdr_loc}"
+	$(s)echo "${bl2_hdr_loc}"
 	dd if=${BUILD_PLAT}/hdr_bl2 of=${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl bs=1K seek=${bl2_hdr_loc}
 
 	# Append the bl2.bin to the RCW image
-	@echo "${bl2_loc}"
+	$(s)echo "${bl2_loc}"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl bs=1K seek=${bl2_loc}
 
 	rm ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl
@@ -54,16 +54,16 @@
 endif
 else  #SECURE_BOOT
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
 
 	# Add Block Copy command and populate boot loc ptrfor bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE} \
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl -f ${BL2_SRC_OFFSET};
 
 	# Append the bl2.bin to the RCW image
-	@echo "bl2_loc is ${bl2_loc} KB"
+	$(s)echo "bl2_loc is ${bl2_loc} KB"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl bs=1K seek=${bl2_loc}
 
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index baa6e7e..8c2c054 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -6,6 +6,7 @@
 
 toolchains := aarch64
 
+include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
 ###################################################
@@ -89,19 +90,19 @@
 # Linker
 ###################################################
 $(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0)
-	$(aarch64-ld) $(OBJ_FILE_SA0)		 	\
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib	\
 	-T $(MEMORY_DEF_SA0)			\
 	-o $(OUTPUT_FILE_SA0)			\
-	-Map $(FILE_NAME_SA0).map 		\
+	-Wl,-Map $(FILE_NAME_SA0).map 		\
 
 	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
 $(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6)
-	$(aarch64-ld) $(OBJ_FILE_SA6)		 	\
+	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib	\
 	-T $(MEMORY_DEF_SA6)			\
 	-o $(OUTPUT_FILE_SA6)			\
-	-Map $(FILE_NAME_SA6).map 		\
+	-Wl,-Map $(FILE_NAME_SA6).map 		\
 
 	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
diff --git a/tools/renesas/rzg_layout_create/makefile b/tools/renesas/rzg_layout_create/makefile
index 4cab5fb..d2a54ea 100644
--- a/tools/renesas/rzg_layout_create/makefile
+++ b/tools/renesas/rzg_layout_create/makefile
@@ -6,6 +6,7 @@
 
 toolchains := aarch64
 
+include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
 ###################################################
@@ -86,19 +87,19 @@
 # Linker
 ###################################################
 $(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0)
-	$(aarch64-ld) $(OBJ_FILE_SA0)		 	\
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib	\
 	-T $(MEMORY_DEF_SA0)			\
 	-o $(OUTPUT_FILE_SA0)			\
-	-Map $(FILE_NAME_SA0).map 		\
+	-Wl,-Map $(FILE_NAME_SA0).map 		\
 
 	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
 $(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6)
-	$(aarch64-ld) $(OBJ_FILE_SA6)		 	\
+	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib	\
 	-T $(MEMORY_DEF_SA6)			\
 	-o $(OUTPUT_FILE_SA6)			\
-	-Map $(FILE_NAME_SA6).map 		\
+	-Wl,-Map $(FILE_NAME_SA6).map 		\
 
 	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index a913ce5..e336a0c 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -9,12 +9,12 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 SPTOOL  ?= sptool${BIN_EXT}
 PROJECT := $(notdir ${SPTOOL})
 OBJECTS := sptool.o
-V ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99
@@ -24,12 +24,6 @@
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 INCLUDE_PATHS := -I../../include/tools_share
 
 .PHONY: all clean distclean
@@ -37,15 +31,15 @@
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
index c75e941..2b34ef8 100644
--- a/tools/stm32image/Makefile
+++ b/tools/stm32image/Makefile
@@ -9,11 +9,11 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 PROJECT := stm32image${BIN_EXT}
 OBJECTS := stm32image.o
-V := 0
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
 
@@ -23,26 +23,20 @@
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})