Merge "feat(cpus): conform DSU errata to errata framework PCS" into integration
diff --git a/.versionrc.js b/.versionrc.js
index 4e9c71f..3a21ded 100644
--- a/.versionrc.js
+++ b/.versionrc.js
@@ -101,6 +101,25 @@
             "type": "json"
         },
         {
+            "filename": "docs/conf.py",
+            "updater": {
+                "readVersion": function (contents) {
+                    const _ver = contents.match(/version\s=.*"(\d)\.(\d)\.(\d)/);
+
+                    return `${_ver[1]}.${_ver[2]}.${_ver[2]}`;
+                },
+
+                "writeVersion": function (contents, version) {
+                    const _ver = 'version = "' + version + '"'
+                    const _rel = 'release = "' + version + '"'
+
+                    contents = contents.replace(/^(version\s=\s")((\d).?)*$/m, _ver)
+                    contents = contents.replace(/^(release\s=\s")((\d).?)*$/m, _rel)
+                    return contents
+                }
+            },
+        },
+        {
             "filename": "tools/conventional-changelog-tf-a/package.json",
             "type": "json"
         },
diff --git a/Makefile b/Makefile
index 3dbf28e..03f9320 100644
--- a/Makefile
+++ b/Makefile
@@ -74,37 +74,85 @@
 				${INC_DRV_DIRS_TO_CHECK}		\
 				${INC_ARM_DIRS_TO_CHECK}
 
-
 ################################################################################
 # Process build options
 ################################################################################
 
 # Verbose flag
 ifeq (${V},0)
-        Q:=@
-        ECHO:=@echo
-        CHECKCODE_ARGS	+=	--no-summary --terse
+	Q:=@
+	ECHO:=@echo
+	CHECKCODE_ARGS	+=	--no-summary --terse
 else
-        Q:=
-        ECHO:=$(ECHO_QUIET)
+	Q:=
+	ECHO:=$(ECHO_QUIET)
 endif
 
 ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
-        Q:=@
-        ECHO:=$(ECHO_QUIET)
+	Q:=@
+	ECHO:=$(ECHO_QUIET)
 endif
 
 export Q ECHO
 
-# The cert_create tool cannot generate certificates individually, so we use the
-# target 'certificates' to create them all
-ifneq (${GENERATE_COT},0)
-        FIP_DEPS += certificates
-        FWU_FIP_DEPS += fwu_certificates
+################################################################################
+# Toolchain
+################################################################################
+
+HOSTCC			:=	gcc
+export HOSTCC
+
+CC			:=	${CROSS_COMPILE}gcc
+CPP			:=	${CROSS_COMPILE}cpp
+AS			:=	${CROSS_COMPILE}gcc
+AR			:=	${CROSS_COMPILE}ar
+LINKER			:=	${CROSS_COMPILE}ld
+OC			:=	${CROSS_COMPILE}objcopy
+OD			:=	${CROSS_COMPILE}objdump
+NM			:=	${CROSS_COMPILE}nm
+PP			:=	${CROSS_COMPILE}gcc -E
+DTC			:=	dtc
+
+# Use ${LD}.bfd instead if it exists (as absolute path or together with $PATH).
+ifneq ($(strip $(wildcard ${LD}.bfd) \
+	$(foreach dir,$(subst :, ,${PATH}),$(wildcard ${dir}/${LINKER}.bfd))),)
+LINKER			:=	${LINKER}.bfd
 endif
 
+################################################################################
+# Auxiliary tools (fiptool, cert_create, etc)
+################################################################################
+
+# Variables for use with Certificate Generation Tool
+CRTTOOLPATH		?=	tools/cert_create
+CRTTOOL			?=	${CRTTOOLPATH}/cert_create${BIN_EXT}
+
+# Variables for use with Firmware Encryption Tool
+ENCTOOLPATH		?=	tools/encrypt_fw
+ENCTOOL			?=	${ENCTOOLPATH}/encrypt_fw${BIN_EXT}
+
+# Variables for use with Firmware Image Package
+FIPTOOLPATH		?=	tools/fiptool
+FIPTOOL			?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
+
+# Variables for use with sptool
+SPTOOLPATH		?=	tools/sptool
+SPTOOL			?=	${SPTOOLPATH}/sptool.py
+SP_MK_GEN		?=	${SPTOOLPATH}/sp_mk_generator.py
+
+# Variables for use with ROMLIB
+ROMLIBPATH		?=	lib/romlib
+
+# Variable for use with Python
+PYTHON			?=	python3
+
+# Variables for use with documentation build using Sphinx tool
+DOCS_PATH		?=	docs
+
+################################################################################
 # Process BRANCH_PROTECTION value and set
 # Pointer Authentication and Branch Target Identification flags
+################################################################################
 ifeq (${BRANCH_PROTECTION},0)
 	# Default value turns off all types of branch protection
 	BP_OPTION := none
@@ -129,151 +177,111 @@
 	ENABLE_BTI := 1
 else
         $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION})
-endif
+endif #(BRANCH_PROTECTION)
 
+################################################################################
+# RME dependent flags configuration
+################################################################################
 # FEAT_RME
 ifeq (${ENABLE_RME},1)
-# RME doesn't support PIE
-ifneq (${ENABLE_PIE},0)
-        $(error ENABLE_RME does not support PIE)
-endif
-# RME doesn't support BRBE
-ifneq (${ENABLE_BRBE_FOR_NS},0)
-        $(error ENABLE_RME does not support BRBE.)
-endif
-# RME requires AARCH64
-ifneq (${ARCH},aarch64)
-        $(error ENABLE_RME requires AArch64)
-endif
-# RME requires el2 context to be saved for now.
-CTX_INCLUDE_EL2_REGS := 1
-CTX_INCLUDE_AARCH32_REGS := 0
-ARM_ARCH_MAJOR := 8
-ARM_ARCH_MINOR := 5
-ENABLE_FEAT_ECV = 1
-ENABLE_FEAT_FGT = 1
-CTX_INCLUDE_PAUTH_REGS := 1
-# RME enables CSV2_2 extension by default.
-ENABLE_FEAT_CSV2_2 = 1
+	# RME doesn't support PIE
+	ifneq (${ENABLE_PIE},0)
+                $(error ENABLE_RME does not support PIE)
+	endif
 
-endif
+	# RME doesn't support BRBE
+	ifneq (${ENABLE_BRBE_FOR_NS},0)
+                $(error ENABLE_RME does not support BRBE.)
+	endif
 
-# USE_SPINLOCK_CAS requires AArch64 build
-ifeq (${USE_SPINLOCK_CAS},1)
-ifneq (${ARCH},aarch64)
-        $(error USE_SPINLOCK_CAS requires AArch64)
-endif
-endif
+	# RME requires AARCH64
+	ifneq (${ARCH},aarch64)
+                $(error ENABLE_RME requires AArch64)
+	endif
 
-# USE_DEBUGFS experimental feature recommended only in debug builds
-ifeq (${USE_DEBUGFS},1)
-ifeq (${DEBUG},1)
-        $(warning DEBUGFS experimental feature is enabled.)
-else
-        $(warning DEBUGFS experimental, recommended in DEBUG builds ONLY)
-endif
-endif
+	# RME requires el2 context to be saved for now.
+	CTX_INCLUDE_EL2_REGS := 1
+	CTX_INCLUDE_AARCH32_REGS := 0
+	ARM_ARCH_MAJOR := 8
+	ARM_ARCH_MINOR := 5
+	ENABLE_FEAT_ECV = 1
+	ENABLE_FEAT_FGT = 1
+	CTX_INCLUDE_PAUTH_REGS := 1
 
-ifneq (${DECRYPTION_SUPPORT},none)
-ENC_ARGS += -f ${FW_ENC_STATUS}
-ENC_ARGS += -k ${ENC_KEY}
-ENC_ARGS += -n ${ENC_NONCE}
-FIP_DEPS += enctool
-FWU_FIP_DEPS += enctool
-endif
+	# RME enables CSV2_2 extension by default.
+	ENABLE_FEAT_CSV2_2 = 1
+endif #(FEAT_RME)
 
 ################################################################################
-# Toolchain
+# Compiler Configuration based on ARCH_MAJOR and ARCH_MINOR flags
 ################################################################################
-
-HOSTCC			:=	gcc
-export HOSTCC
-
-CC			:=	${CROSS_COMPILE}gcc
-CPP			:=	${CROSS_COMPILE}cpp
-AS			:=	${CROSS_COMPILE}gcc
-AR			:=	${CROSS_COMPILE}ar
-LINKER			:=	${CROSS_COMPILE}ld
-OC			:=	${CROSS_COMPILE}objcopy
-OD			:=	${CROSS_COMPILE}objdump
-NM			:=	${CROSS_COMPILE}nm
-PP			:=	${CROSS_COMPILE}gcc -E
-DTC			:=	dtc
-
-# Use ${LD}.bfd instead if it exists (as absolute path or together with $PATH).
-ifneq ($(strip $(wildcard ${LD}.bfd) \
-	$(foreach dir,$(subst :, ,${PATH}),$(wildcard ${dir}/${LINKER}.bfd))),)
-LINKER			:=	${LINKER}.bfd
-endif
-
 ifeq (${ARM_ARCH_MAJOR},7)
-target32-directive	= 	-target arm-none-eabi
+	target32-directive	= 	-target arm-none-eabi
 # Will set march32-directive from platform configuration
 else
-target32-directive	= 	-target armv8a-none-eabi
+	target32-directive	= 	-target armv8a-none-eabi
 
 # Set the compiler's target architecture profile based on
 # ARM_ARCH_MAJOR ARM_ARCH_MINOR options
-ifeq (${ARM_ARCH_MINOR},0)
-march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
-march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
-else
-march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
-march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
-endif
-endif
+	ifeq (${ARM_ARCH_MINOR},0)
+		march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
+		march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
+	else
+		march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+		march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+	endif #(ARM_ARCH_MINOR)
+endif #(ARM_ARCH_MAJOR)
+
+################################################################################
+# Get Architecture Feature Modifiers
+################################################################################
+arch-features		=	${ARM_ARCH_FEATURE}
+
+####################################################
+# Enable required options for Memory Stack Tagging.
+####################################################
 
 # Memory tagging is supported in architecture Armv8.5-A AArch64 and onwards
 ifeq ($(ARCH), aarch64)
-# Check if revision is greater than or equal to 8.5
-ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-mem_tag_arch_support	= 	yes
-endif
-endif
-
-# Get architecture feature modifiers
-arch-features		=	${ARM_ARCH_FEATURE}
+	# Check if revision is greater than or equal to 8.5
+	ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+		mem_tag_arch_support	= 	yes
+	endif
+endif #(ARCH=aarch64)
 
-# Enable required options for memory stack tagging.
 # Currently, these options are enabled only for clang and armclang compiler.
 ifeq (${SUPPORT_STACK_MEMTAG},yes)
-ifdef mem_tag_arch_support
-# Check for armclang and clang compilers
-ifneq ( ,$(filter $(notdir $(CC)),armclang clang))
-# Add "memtag" architecture feature modifier if not specified
-ifeq ( ,$(findstring memtag,$(arch-features)))
-arch-features       	:=       $(arch-features)+memtag
-endif	# memtag
-ifeq ($(notdir $(CC)),armclang)
-TF_CFLAGS		+=	-mmemtag-stack
-else ifeq ($(notdir $(CC)),clang)
-TF_CFLAGS		+=	-fsanitize=memtag
-endif	# armclang
-endif	# armclang clang
-else
-$(error "Error: stack memory tagging is not supported for architecture \
-	${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a")
-endif	# mem_tag_arch_support
-endif	# SUPPORT_STACK_MEMTAG
+	ifdef mem_tag_arch_support
+		# Check for armclang and clang compilers
+		ifneq ( ,$(filter $(notdir $(CC)),armclang clang))
+		# Add "memtag" architecture feature modifier if not specified
+			ifeq ( ,$(findstring memtag,$(arch-features)))
+				arch-features	:=	$(arch-features)+memtag
+			endif	# memtag
+			ifeq ($(notdir $(CC)),armclang)
+				TF_CFLAGS	+=	-mmemtag-stack
+			else ifeq ($(notdir $(CC)),clang)
+				TF_CFLAGS	+=	-fsanitize=memtag
+			endif	# armclang
+		endif
+	else
+                $(error "Error: stack memory tagging is not supported for  \
+                 architecture ${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a")
+	endif #(mem_tag_arch_support)
+endif #(SUPPORT_STACK_MEMTAG)
 
 # Set the compiler's architecture feature modifiers
 ifneq ($(arch-features), none)
-# Strip "none+" from arch-features
-arch-features		:=	$(subst none+,,$(arch-features))
-ifeq ($(ARCH), aarch32)
-march32-directive	:=	$(march32-directive)+$(arch-features)
-else
-march64-directive	:=	$(march64-directive)+$(arch-features)
-endif
+	# Strip "none+" from arch-features
+	arch-features		:=	$(subst none+,,$(arch-features))
+	ifeq ($(ARCH), aarch32)
+		march32-directive	:=	$(march32-directive)+$(arch-features)
+	else
+		march64-directive	:=	$(march64-directive)+$(arch-features)
+	endif
 # Print features
-$(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
-endif	# arch-features
-
-# Determine if FEAT_RNG is supported
-ENABLE_FEAT_RNG		=	$(if $(findstring rng,${arch-features}),1,0)
-
-# Determine if FEAT_SB is supported
-ENABLE_FEAT_SB		=	$(if $(findstring sb,${arch-features}),1,0)
+        $(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
+endif #(arch-features)
 
 ifneq ($(findstring clang,$(notdir $(CC))),)
 	ifneq ($(findstring armclang,$(notdir $(CC))),)
@@ -294,62 +302,65 @@
 	PP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
 	AS		:=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
 else ifneq ($(findstring gcc,$(notdir $(CC))),)
-TF_CFLAGS_aarch32	=	$(march32-directive)
-TF_CFLAGS_aarch64	=	$(march64-directive)
-ifeq ($(ENABLE_LTO),1)
-	# Enable LTO only for aarch64
-	ifeq (${ARCH},aarch64)
-		LTO_CFLAGS	=	-flto
-		# Use gcc as a wrapper for the ld, recommended for LTO
-		LINKER		:=	${CROSS_COMPILE}gcc
+	TF_CFLAGS_aarch32	=	$(march32-directive)
+	TF_CFLAGS_aarch64	=	$(march64-directive)
+	ifeq ($(ENABLE_LTO),1)
+		# Enable LTO only for aarch64
+		ifeq (${ARCH},aarch64)
+			LTO_CFLAGS	=	-flto
+			# Use gcc as a wrapper for the ld, recommended for LTO
+			LINKER		:=	${CROSS_COMPILE}gcc
+		endif
 	endif
-endif
-LD			=	$(LINKER)
+	LD			=	$(LINKER)
 else
-TF_CFLAGS_aarch32	=	$(march32-directive)
-TF_CFLAGS_aarch64	=	$(march64-directive)
-LD			=	$(LINKER)
-endif
+	TF_CFLAGS_aarch32	=	$(march32-directive)
+	TF_CFLAGS_aarch64	=	$(march64-directive)
+	LD			=	$(LINKER)
+endif #(clang)
 
 # Process Debug flag
 $(eval $(call add_define,DEBUG))
 ifneq (${DEBUG}, 0)
-        BUILD_TYPE	:=	debug
-        TF_CFLAGS	+=	-g -gdwarf-4
-        ASFLAGS		+=	-g -Wa,-gdwarf-4
+	BUILD_TYPE	:=	debug
+	TF_CFLAGS	+=	-g -gdwarf-4
+	ASFLAGS		+=	-g -Wa,-gdwarf-4
 
-        # Use LOG_LEVEL_INFO by default for debug builds
-        LOG_LEVEL	:=	40
+	# Use LOG_LEVEL_INFO by default for debug builds
+	LOG_LEVEL	:=	40
 else
-        BUILD_TYPE	:=	release
-        # Use LOG_LEVEL_NOTICE by default for release builds
-        LOG_LEVEL	:=	20
-endif
+	BUILD_TYPE	:=	release
+	# Use LOG_LEVEL_NOTICE by default for release builds
+	LOG_LEVEL	:=	20
+endif #(Debug)
 
 # Default build string (git branch and commit)
 ifeq (${BUILD_STRING},)
-        BUILD_STRING  :=  $(shell git describe --always --dirty --tags 2> /dev/null)
+	BUILD_STRING  :=  $(shell git describe --always --dirty --tags 2> /dev/null)
 endif
 VERSION_STRING    :=  v${VERSION}(${BUILD_TYPE}):${BUILD_STRING}
 
 ifeq (${AARCH32_INSTRUCTION_SET},A32)
-TF_CFLAGS_aarch32	+=	-marm
+	TF_CFLAGS_aarch32	+=	-marm
 else ifeq (${AARCH32_INSTRUCTION_SET},T32)
-TF_CFLAGS_aarch32	+=	-mthumb
+	TF_CFLAGS_aarch32	+=	-mthumb
 else
-$(error Error: Unknown AArch32 instruction set ${AARCH32_INSTRUCTION_SET})
-endif
+        $(error Error: Unknown AArch32 instruction set ${AARCH32_INSTRUCTION_SET})
+endif #(AARCH32_INSTRUCTION_SET)
 
 TF_CFLAGS_aarch32	+=	-mno-unaligned-access
 TF_CFLAGS_aarch64	+=	-mgeneral-regs-only -mstrict-align
 
 ifneq (${BP_OPTION},none)
-TF_CFLAGS_aarch64	+=	-mbranch-protection=${BP_OPTION}
-endif
+	TF_CFLAGS_aarch64	+=	-mbranch-protection=${BP_OPTION}
+endif #(BP_OPTION)
 
 ASFLAGS_aarch32		=	$(march32-directive)
 ASFLAGS_aarch64		=	$(march64-directive)
 
+##############################################################################
+# WARNINGS Configuration
+###############################################################################
 # General warnings
 WARNINGS		:=	-Wall -Wmissing-include-dirs -Wunused	\
 				-Wdisabled-optimization -Wvla -Wshadow	\
@@ -395,18 +406,18 @@
 # outside of the contributor's control. Don't fail the build on them so warnings
 # can be seen and hopefully addressed
 ifdef W
-ifneq (${W},0)
-E	 ?= 0
-endif
+	ifneq (${W},0)
+		E	 ?= 0
+	endif
 endif
 
 ifeq (${W},1)
-WARNINGS += $(WARNING1)
+	WARNINGS += $(WARNING1)
 else ifeq (${W},2)
-WARNINGS += $(WARNING1) $(WARNING2)
+	WARNINGS += $(WARNING1) $(WARNING2)
 else ifeq (${W},3)
-WARNINGS += $(WARNING1) $(WARNING2) $(WARNING3)
-endif
+	WARNINGS += $(WARNING1) $(WARNING2) $(WARNING3)
+endif #(W)
 
 # Compiler specific warnings
 ifeq ($(findstring clang,$(notdir $(CC))),)
@@ -422,12 +433,15 @@
 # using clang
 WARNINGS	+=		-Wshift-overflow -Wshift-sign-overflow \
 				-Wlogical-op-parentheses
-endif
+endif #(Clang Warning)
 
 ifneq (${E},0)
-ERRORS := -Werror
-endif
+	ERRORS := -Werror
+endif #(E)
 
+################################################################################
+# Compiler and Linker Directives
+################################################################################
 CPPFLAGS		=	${DEFINES} ${INCLUDES} ${MBEDTLS_INC} -nostdinc	\
 				$(ERRORS) $(WARNINGS)
 ASFLAGS			+=	$(CPPFLAGS) $(ASFLAGS_$(ARCH))			\
@@ -437,15 +451,14 @@
 				-ffreestanding -fno-builtin -fno-common		\
 				-Os -std=gnu99
 
-$(eval $(call add_define,SVE_VECTOR_LEN))
-
 ifeq (${SANITIZE_UB},on)
-TF_CFLAGS		+=	-fsanitize=undefined -fno-sanitize-recover
-endif
+	TF_CFLAGS	+=	-fsanitize=undefined -fno-sanitize-recover
+endif #(${SANITIZE_UB},on)
+
 ifeq (${SANITIZE_UB},trap)
-TF_CFLAGS		+=	-fsanitize=undefined -fno-sanitize-recover	\
+	TF_CFLAGS	+=	-fsanitize=undefined -fno-sanitize-recover	\
 				-fsanitize-undefined-trap-on-error
-endif
+endif #(${SANITIZE_UB},trap)
 
 GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
 
@@ -453,51 +466,53 @@
 
 # LD = armlink
 ifneq ($(findstring armlink,$(notdir $(LD))),)
-TF_LDFLAGS		+=	--diag_error=warning --lto_level=O1
-TF_LDFLAGS		+=	--remove --info=unused,unusedsymbols
-TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
+	TF_LDFLAGS		+=	--diag_error=warning --lto_level=O1
+	TF_LDFLAGS		+=	--remove --info=unused,unusedsymbols
+	TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
 
 # LD = gcc (used when GCC LTO is enabled)
 else ifneq ($(findstring gcc,$(notdir $(LD))),)
-# Pass ld options with Wl or Xlinker switches
-TF_LDFLAGS		+=	-Wl,--fatal-warnings -O1
-TF_LDFLAGS		+=	-Wl,--gc-sections
+	# Pass ld options with Wl or Xlinker switches
+	TF_LDFLAGS		+=	-Wl,--fatal-warnings -O1
+	TF_LDFLAGS		+=	-Wl,--gc-sections
 
-TF_LDFLAGS		+=	-Wl,-z,common-page-size=4096 # Configure page size constants
-TF_LDFLAGS		+=	-Wl,-z,max-page-size=4096
+	TF_LDFLAGS		+=	-Wl,-z,common-page-size=4096 #Configure page size constants
+	TF_LDFLAGS		+=	-Wl,-z,max-page-size=4096
 
-ifeq ($(ENABLE_LTO),1)
-	ifeq (${ARCH},aarch64)
-		TF_LDFLAGS	+=	-flto -fuse-linker-plugin
-	endif
-endif
+	ifeq ($(ENABLE_LTO),1)
+		ifeq (${ARCH},aarch64)
+			TF_LDFLAGS	+=	-flto -fuse-linker-plugin
+		endif
+	endif #(ENABLE_LTO)
+
 # GCC automatically adds fix-cortex-a53-843419 flag when used to link
 # which breaks some builds, so disable if errata fix is not explicitly enabled
-ifneq (${ERRATA_A53_843419},1)
-	TF_LDFLAGS	+= 	-mno-fix-cortex-a53-843419
-endif
-TF_LDFLAGS		+= 	-nostdlib
-TF_LDFLAGS		+=	$(subst --,-Xlinker --,$(TF_LDFLAGS_$(ARCH)))
+	ifneq (${ERRATA_A53_843419},1)
+		TF_LDFLAGS	+= 	-mno-fix-cortex-a53-843419
+	endif
+	TF_LDFLAGS		+= 	-nostdlib
+	TF_LDFLAGS		+=	$(subst --,-Xlinker --,$(TF_LDFLAGS_$(ARCH)))
 
 # LD = gcc-ld (ld) or llvm-ld (ld.lld) or other
 else
 # With ld.bfd version 2.39 and newer new warnings are added. Skip those since we
 # are not loaded by a elf loader.
-TF_LDFLAGS		+=	$(call ld_option, --no-warn-rwx-segments)
-TF_LDFLAGS		+=	-O1
-TF_LDFLAGS		+=	--gc-sections
+	TF_LDFLAGS		+=	$(call ld_option, --no-warn-rwx-segments)
+	TF_LDFLAGS		+=	-O1
+	TF_LDFLAGS		+=	--gc-sections
 
-TF_LDFLAGS		+=	-z common-page-size=4096 # Configure page size constants
-TF_LDFLAGS		+=	-z max-page-size=4096
+	TF_LDFLAGS		+=	-z common-page-size=4096 # Configure page size constants
+	TF_LDFLAGS		+=	-z max-page-size=4096
 
 # ld.lld doesn't recognize the errata flags,
 # therefore don't add those in that case.
 # ld.lld reports section type mismatch warnings,
 # therefore don't add --fatal-warnings to it.
-ifeq ($(findstring ld.lld,$(notdir $(LD))),)
-TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH)) --fatal-warnings
-endif
-endif
+	ifeq ($(findstring ld.lld,$(notdir $(LD))),)
+		TF_LDFLAGS	+=	$(TF_LDFLAGS_$(ARCH)) --fatal-warnings
+	endif
+
+endif #(LD = armlink)
 
 DTC_FLAGS		+=	-I dts -O dtb
 DTC_CPPFLAGS		+=	-P -nostdinc -Iinclude -Ifdts -undef \
@@ -525,15 +540,15 @@
 ifeq (${ENABLE_PAUTH}, 1)
 # arm/common/aarch64/arm_pauth.c contains a sample platform hook to complete the
 # Pauth support. As it's not secure, it must be reimplemented for real platforms
-BL_COMMON_SOURCES	+=	lib/extensions/pauth/pauth_helpers.S
+	BL_COMMON_SOURCES	+=	lib/extensions/pauth/pauth_helpers.S
 endif
 
 ifeq ($(notdir $(CC)),armclang)
-BL_COMMON_SOURCES	+=	lib/${ARCH}/armclang_printf.S
+	BL_COMMON_SOURCES	+=	lib/${ARCH}/armclang_printf.S
 endif
 
 ifeq (${SANITIZE_UB},on)
-BL_COMMON_SOURCES	+=	plat/common/ubsan.c
+	BL_COMMON_SOURCES	+=	plat/common/ubsan.c
 endif
 
 INCLUDES		+=	-Iinclude				\
@@ -548,7 +563,6 @@
 ################################################################################
 # Generic definitions
 ################################################################################
-
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
 
 ifeq (${BUILD_BASE},)
@@ -561,91 +575,97 @@
 # Platforms providing their own TBB makefile may override this value
 INCLUDE_TBBR_MK		:=	1
 
-
 ################################################################################
 # Include SPD Makefile if one has been specified
 ################################################################################
 
 ifneq (${SPD},none)
-    ifeq (${ARCH},aarch32)
-        $(error "Error: SPD is incompatible with AArch32.")
-    endif
+	ifeq (${ARCH},aarch32)
+                $(error "Error: SPD is incompatible with AArch32.")
+	endif
 
-    ifdef EL3_PAYLOAD_BASE
-        $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
-        $(warning "The SPD and its BL32 companion will be present but ignored.")
-    endif
+	ifdef EL3_PAYLOAD_BASE
+                $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
+                $(warning "The SPD and its BL32 companion will be present but \
+                ignored.")
+	endif
 
-    ifeq (${SPD},spmd)
-        # SPMD is located in std_svc directory
-        SPD_DIR := std_svc
+	ifeq (${SPD},spmd)
+	# SPMD is located in std_svc directory
+		SPD_DIR := std_svc
 
-        ifeq ($(SPMD_SPM_AT_SEL2),1)
-            CTX_INCLUDE_EL2_REGS := 1
-	    ifeq ($(SPMC_AT_EL3),1)
-                $(error SPM cannot be enabled in both S-EL2 and EL3.)
-            endif
-        endif
+		ifeq ($(SPMD_SPM_AT_SEL2),1)
+			CTX_INCLUDE_EL2_REGS := 1
+			ifeq ($(SPMC_AT_EL3),1)
+                                $(error SPM cannot be enabled in both S-EL2 and EL3.)
+			endif
+		endif
 
-        ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
-            DTC_CPPFLAGS	+=	-DOPTEE_SP_FW_CONFIG
-        endif
+		ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
+			DTC_CPPFLAGS	+=	-DOPTEE_SP_FW_CONFIG
+		endif
 
-        ifeq ($(TS_SP_FW_CONFIG),1)
-            DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
-        endif
+		ifeq ($(TS_SP_FW_CONFIG),1)
+		DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
+		endif
 
-        ifneq ($(ARM_BL2_SP_LIST_DTS),)
-            DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
-        endif
+		ifneq ($(ARM_BL2_SP_LIST_DTS),)
+		DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
+		endif
 
-        ifneq ($(SP_LAYOUT_FILE),)
-            BL2_ENABLE_SP_LOAD := 1
-        endif
-    else
-        # All other SPDs in spd directory
-        SPD_DIR := spd
-    endif
+		ifneq ($(SP_LAYOUT_FILE),)
+		BL2_ENABLE_SP_LOAD := 1
+		endif
+	else
+		# All other SPDs in spd directory
+		SPD_DIR := spd
+	endif #(SPD)
 
-    # We expect to locate an spd.mk under the specified SPD directory
-    SPD_MAKE	:=	$(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
+	# We expect to locate an spd.mk under the specified SPD directory
+	SPD_MAKE	:=	$(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
 
-    ifeq (${SPD_MAKE},)
-        $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
-    endif
-    $(info Including ${SPD_MAKE})
-    include ${SPD_MAKE}
+	ifeq (${SPD_MAKE},)
+                $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
+	endif
+        $(info Including ${SPD_MAKE})
+        include ${SPD_MAKE}
 
-    # If there's BL32 companion for the chosen SPD, we expect that the SPD's
-    # Makefile would set NEED_BL32 to "yes". In this case, the build system
-    # supports two mutually exclusive options:
-    # * BL32 is built from source: then BL32_SOURCES must contain the list
-    #   of source files to build BL32
-    # * BL32 is a prebuilt binary: then BL32 must point to the image file
-    #   that will be included in the FIP
-    # If both BL32_SOURCES and BL32 are defined, the binary takes precedence
-    # over the sources.
-endif
+	# If there's BL32 companion for the chosen SPD, we expect that the SPD's
+	# Makefile would set NEED_BL32 to "yes". In this case, the build system
+	# supports two mutually exclusive options:
+	# * BL32 is built from source: then BL32_SOURCES must contain the list
+	#   of source files to build BL32
+	# * BL32 is a prebuilt binary: then BL32 must point to the image file
+	#   that will be included in the FIP
+	# If both BL32_SOURCES and BL32 are defined, the binary takes precedence
+	# over the sources.
+endif #(SPD=none)
 
 ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
-ifeq (${SPD},none)
-ifeq (${ENABLE_RME},0)
-    $(error CTX_INCLUDE_EL2_REGS is available only when SPD or RME is enabled)
-endif
-endif
+	ifeq (${SPD},none)
+		ifeq (${ENABLE_RME},0)
+                        $(error CTX_INCLUDE_EL2_REGS is available only when SPD \
+                        or RME is enabled)
+		endif
+	endif
 endif
 
 ################################################################################
 # Include rmmd Makefile if RME is enabled
 ################################################################################
-
 ifneq (${ENABLE_RME},0)
-ifneq (${ARCH},aarch64)
-	$(error ENABLE_RME requires AArch64)
-endif
-ifeq ($(SPMC_AT_EL3),1)
-	$(error SPMC_AT_EL3 and ENABLE_RME cannot both be enabled.)
-endif
+	ifneq (${ARCH},aarch64)
+                $(error ENABLE_RME requires AArch64)
+	endif
+	ifeq ($(SPMC_AT_EL3),1)
+                $(error SPMC_AT_EL3 and ENABLE_RME cannot both be enabled.)
+	endif
+
+	ifneq (${SPD}, none)
+		ifneq (${SPD}, spmd)
+                        $(error ENABLE_RME is incompatible with SPD=${SPD}. Use SPD=spmd)
+		endif
+	endif
 include services/std_svc/rmmd/rmmd.mk
 $(warning "RME is an experimental feature")
 endif
@@ -664,9 +684,10 @@
 
 ifeq (${RESET_TO_BL2},1)
 	BL2_RUNS_AT_EL3	:=	1
-    ifeq (${ENABLE_RME},1)
-        $(error RESET_TO_BL2=1 and ENABLE_RME=1 configuration is not supported at the moment.)
-    endif
+	ifeq (${ENABLE_RME},1)
+                $(error RESET_TO_BL2=1 and ENABLE_RME=1 configuration is not \
+                supported at the moment.)
+	endif
 else ifeq (${ENABLE_RME},1)
 	BL2_RUNS_AT_EL3	:=	1
 else
@@ -685,7 +706,7 @@
 ifneq ($(findstring gcc,$(notdir $(LD))),)
 	TF_LDFLAGS	+=	-no-pie
 endif
-endif
+endif #(PIE_FOUND)
 
 ifneq ($(findstring gcc,$(notdir $(LD))),)
 	PIE_LDFLAGS	+=	-Wl,-pie -Wl,--no-dynamic-linker
@@ -694,13 +715,13 @@
 endif
 
 ifeq ($(ENABLE_PIE),1)
-ifeq ($(RESET_TO_BL2),1)
-ifneq ($(BL2_IN_XIP_MEM),1)
-	BL2_CPPFLAGS	+=	-fpie
-	BL2_CFLAGS	+=	-fpie
-	BL2_LDFLAGS	+=	$(PIE_LDFLAGS)
-endif
-endif
+	ifeq ($(RESET_TO_BL2),1)
+		ifneq ($(BL2_IN_XIP_MEM),1)
+			BL2_CPPFLAGS	+=	-fpie
+			BL2_CFLAGS	+=	-fpie
+			BL2_LDFLAGS	+=	$(PIE_LDFLAGS)
+		endif #(BL2_IN_XIP_MEM)
+	endif #(RESET_TO_BL2)
 	BL31_CPPFLAGS	+=	-fpie
 	BL31_CFLAGS 	+=	-fpie
 	BL31_LDFLAGS	+=	$(PIE_LDFLAGS)
@@ -708,7 +729,7 @@
 	BL32_CPPFLAGS	+=	-fpie
 	BL32_CFLAGS	+=	-fpie
 	BL32_LDFLAGS	+=	$(PIE_LDFLAGS)
-endif
+endif #(ENABLE_PIE)
 
 BL1_CPPFLAGS  += -DREPORT_ERRATA=${DEBUG}
 BL31_CPPFLAGS += -DREPORT_ERRATA=${DEBUG}
@@ -716,17 +737,17 @@
 
 BL1_CPPFLAGS += -DIMAGE_AT_EL3
 ifeq ($(RESET_TO_BL2),1)
-BL2_CPPFLAGS += -DIMAGE_AT_EL3
+	BL2_CPPFLAGS += -DIMAGE_AT_EL3
 else
-BL2_CPPFLAGS += -DIMAGE_AT_EL1
-endif
+	BL2_CPPFLAGS += -DIMAGE_AT_EL1
+endif #(RESET_TO_BL2)
 
 ifeq (${ARCH},aarch64)
-BL2U_CPPFLAGS += -DIMAGE_AT_EL1
-BL31_CPPFLAGS += -DIMAGE_AT_EL3
-BL32_CPPFLAGS += -DIMAGE_AT_EL1
+	BL2U_CPPFLAGS += -DIMAGE_AT_EL1
+	BL31_CPPFLAGS += -DIMAGE_AT_EL3
+	BL32_CPPFLAGS += -DIMAGE_AT_EL1
 else
-BL32_CPPFLAGS += -DIMAGE_AT_EL3
+	BL32_CPPFLAGS += -DIMAGE_AT_EL3
 endif
 
 # Include the CPU specific operations makefile, which provides default
@@ -734,25 +755,23 @@
 # This can be overridden by the platform.
 include lib/cpus/cpu-ops.mk
 
-ifeq (${ARCH},aarch32)
-NEED_BL32 := yes
-
 ################################################################################
 # Build `AARCH32_SP` as BL32 image for AArch32
 ################################################################################
-ifneq (${AARCH32_SP},none)
-# We expect to locate an sp.mk under the specified AARCH32_SP directory
-AARCH32_SP_MAKE	:=	$(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk)
-
-ifeq (${AARCH32_SP_MAKE},)
-  $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
-endif
+ifeq (${ARCH},aarch32)
+        NEED_BL32 := yes
 
-$(info Including ${AARCH32_SP_MAKE})
-include ${AARCH32_SP_MAKE}
-endif
+        ifneq (${AARCH32_SP},none)
+        # We expect to locate an sp.mk under the specified AARCH32_SP directory
+		AARCH32_SP_MAKE	:=	$(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk)
 
-endif
+                ifeq (${AARCH32_SP_MAKE},)
+                        $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
+                endif
+        $(info Including ${AARCH32_SP_MAKE})
+        include ${AARCH32_SP_MAKE}
+        endif
+endif #(ARCH=aarch32)
 
 ################################################################################
 # Include libc if not overridden
@@ -762,226 +781,272 @@
 endif
 
 ################################################################################
-# Check incompatible options
+# Check incompatible options and dependencies
 ################################################################################
 
-ifdef EL3_PAYLOAD_BASE
-        ifdef PRELOADED_BL33_BASE
-                $(warning "PRELOADED_BL33_BASE and EL3_PAYLOAD_BASE are \
-                incompatible build options. EL3_PAYLOAD_BASE has priority.")
-        endif
-        ifneq (${GENERATE_COT},0)
-                $(error "GENERATE_COT and EL3_PAYLOAD_BASE are incompatible build options.")
+# USE_DEBUGFS experimental feature recommended only in debug builds
+ifeq (${USE_DEBUGFS},1)
+        ifeq (${DEBUG},1)
+                $(warning DEBUGFS experimental feature is enabled.)
+        else
+                $(warning DEBUGFS experimental, recommended in DEBUG builds ONLY)
         endif
-        ifneq (${TRUSTED_BOARD_BOOT},0)
-                $(error "TRUSTED_BOARD_BOOT and EL3_PAYLOAD_BASE are incompatible build options.")
+endif #(USE_DEBUGFS)
+
+# USE_SPINLOCK_CAS requires AArch64 build
+ifeq (${USE_SPINLOCK_CAS},1)
+        ifneq (${ARCH},aarch64)
+               $(error USE_SPINLOCK_CAS requires AArch64)
         endif
+endif #(USE_SPINLOCK_CAS)
+
+# The cert_create tool cannot generate certificates individually, so we use the
+# target 'certificates' to create them all
+ifneq (${GENERATE_COT},0)
+        FIP_DEPS += certificates
+        FWU_FIP_DEPS += fwu_certificates
 endif
 
+ifneq (${DECRYPTION_SUPPORT},none)
+	ENC_ARGS += -f ${FW_ENC_STATUS}
+	ENC_ARGS += -k ${ENC_KEY}
+	ENC_ARGS += -n ${ENC_NONCE}
+	FIP_DEPS += enctool
+	FWU_FIP_DEPS += enctool
+endif #(DECRYPTION_SUPPORT)
+
+ifdef EL3_PAYLOAD_BASE
+	ifdef PRELOADED_BL33_BASE
+                $(warning "PRELOADED_BL33_BASE and EL3_PAYLOAD_BASE are \
+		incompatible build options. EL3_PAYLOAD_BASE has priority.")
+	endif
+	ifneq (${GENERATE_COT},0)
+                $(error "GENERATE_COT and EL3_PAYLOAD_BASE are incompatible \
+                build options.")
+	endif
+	ifneq (${TRUSTED_BOARD_BOOT},0)
+                $(error "TRUSTED_BOARD_BOOT and EL3_PAYLOAD_BASE are \
+                incompatible \ build options.")
+	endif
+endif #(EL3_PAYLOAD_BASE)
+
 ifeq (${NEED_BL33},yes)
-        ifdef EL3_PAYLOAD_BASE
+	ifdef EL3_PAYLOAD_BASE
                 $(warning "BL33 image is not needed when option \
                 BL33_PAYLOAD_BASE is used and won't be added to the FIP file.")
-        endif
-        ifdef PRELOADED_BL33_BASE
+	endif
+	ifdef PRELOADED_BL33_BASE
                 $(warning "BL33 image is not needed when option \
-                PRELOADED_BL33_BASE is used and won't be added to the FIP \
-                file.")
-        endif
-endif
+                PRELOADED_BL33_BASE is used and won't be added to the FIP file.")
+	endif
+endif #(NEED_BL33)
 
 # 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.
 ifeq ($(HW_ASSISTED_COHERENCY)-$(USE_COHERENT_MEM),1-1)
-$(error USE_COHERENT_MEM cannot be enabled with HW_ASSISTED_COHERENCY)
+        $(error USE_COHERENT_MEM cannot be enabled with HW_ASSISTED_COHERENCY)
 endif
 
 #For now, BL2_IN_XIP_MEM is only supported when RESET_TO_BL2 is 1.
 ifeq ($(RESET_TO_BL2)-$(BL2_IN_XIP_MEM),0-1)
-$(error "BL2_IN_XIP_MEM is only supported when RESET_TO_BL2 is enabled")
+        $(error "BL2_IN_XIP_MEM is only supported when RESET_TO_BL2 is enabled")
 endif
 
 # RAS_EXTENSION is deprecated, provide alternate build options
 ifeq ($(RAS_EXTENSION),1)
-    $(error "RAS_EXTENSION is now deprecated, please use ENABLE_FEAT_RAS and RAS_FFH_SUPPORT instead")
+        $(error "RAS_EXTENSION is now deprecated, please use ENABLE_FEAT_RAS \
+        and RAS_FFH_SUPPORT instead")
 endif
+
 # RAS firmware first handling requires that EAs are handled in EL3 first
 ifeq ($(RAS_FFH_SUPPORT),1)
-    ifneq ($(ENABLE_FEAT_RAS),1)
-        $(error For RAS_FFH_SUPPORT, ENABLE_FEAT_RAS must also be 1)
-    endif
-    ifneq ($(HANDLE_EA_EL3_FIRST_NS),1)
-        $(error For RAS_FFH_SUPPORT, HANDLE_EA_EL3_FIRST_NS must also be 1)
-    endif
-endif
+	ifneq ($(ENABLE_FEAT_RAS),1)
+                $(error For RAS_FFH_SUPPORT, ENABLE_FEAT_RAS must also be 1)
+	endif
+	ifneq ($(HANDLE_EA_EL3_FIRST_NS),1)
+                $(error For RAS_FFH_SUPPORT, HANDLE_EA_EL3_FIRST_NS must also be 1)
+	endif
+endif #(RAS_FFH_SUPPORT)
+
 # When FAULT_INJECTION_SUPPORT is used, require that FEAT_RAS is enabled
 ifeq ($(FAULT_INJECTION_SUPPORT),1)
-    ifeq ($(ENABLE_FEAT_RAS),0)
-        $(error For FAULT_INJECTION_SUPPORT, ENABLE_FEAT_RAS must not be 0)
-    endif
-endif
+	ifeq ($(ENABLE_FEAT_RAS),0)
+                $(error For FAULT_INJECTION_SUPPORT, ENABLE_FEAT_RAS must not be 0)
+	endif
+endif #(FAULT_INJECTION_SUPPORT)
 
 # DYN_DISABLE_AUTH can be set only when TRUSTED_BOARD_BOOT=1
 ifeq ($(DYN_DISABLE_AUTH), 1)
-    ifeq (${TRUSTED_BOARD_BOOT}, 0)
-        $(error "TRUSTED_BOARD_BOOT must be enabled for DYN_DISABLE_AUTH to be set.")
-    endif
-endif
+	ifeq (${TRUSTED_BOARD_BOOT}, 0)
+                $(error "TRUSTED_BOARD_BOOT must be enabled for DYN_DISABLE_AUTH \
+                to be set.")
+	endif
+endif #(DYN_DISABLE_AUTH)
 
 ifeq ($(MEASURED_BOOT)-$(TRUSTED_BOARD_BOOT),1-1)
 # Support authentication verification and hash calculation
-    CRYPTO_SUPPORT := 3
+	CRYPTO_SUPPORT := 3
 else ifeq ($(DRTM_SUPPORT)-$(TRUSTED_BOARD_BOOT),1-1)
 # Support authentication verification and hash calculation
-    CRYPTO_SUPPORT := 3
+	CRYPTO_SUPPORT := 3
 else ifneq ($(filter 1,${MEASURED_BOOT} ${DRTM_SUPPORT}),)
 # Support hash calculation only
-    CRYPTO_SUPPORT := 2
+	CRYPTO_SUPPORT := 2
 else ifeq (${TRUSTED_BOARD_BOOT},1)
 # Support authentication verification only
-    CRYPTO_SUPPORT := 1
+	CRYPTO_SUPPORT := 1
 else
-    CRYPTO_SUPPORT := 0
-endif
+	CRYPTO_SUPPORT := 0
+endif #($(MEASURED_BOOT)-$(TRUSTED_BOARD_BOOT))
 
 # SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled.
 ifeq ($(SDEI_SUPPORT)-$(SDEI_IN_FCONF),0-1)
-$(error "SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled")
+        $(error "SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled")
 endif
 
 # If pointer authentication is used in the firmware, make sure that all the
 # registers associated to it are also saved and restored.
 # Not doing it would leak the value of the keys used by EL3 to EL1 and S-EL1.
 ifeq ($(ENABLE_PAUTH),1)
-    ifeq ($(CTX_INCLUDE_PAUTH_REGS),0)
-        $(error Pointer Authentication requires CTX_INCLUDE_PAUTH_REGS=1)
-    endif
-endif
+	ifeq ($(CTX_INCLUDE_PAUTH_REGS),0)
+                $(error Pointer Authentication requires CTX_INCLUDE_PAUTH_REGS=1)
+	endif
+endif #(ENABLE_PAUTH)
 
 ifeq ($(CTX_INCLUDE_PAUTH_REGS),1)
-    ifneq (${ARCH},aarch64)
-        $(error CTX_INCLUDE_PAUTH_REGS requires AArch64)
-    endif
-endif
+	ifneq (${ARCH},aarch64)
+                $(error CTX_INCLUDE_PAUTH_REGS requires AArch64)
+	endif
+endif #(CTX_INCLUDE_PAUTH_REGS)
 
 ifeq ($(CTX_INCLUDE_MTE_REGS),1)
-    ifneq (${ARCH},aarch64)
-        $(error CTX_INCLUDE_MTE_REGS requires AArch64)
-    endif
-endif
+	ifneq (${ARCH},aarch64)
+                $(error CTX_INCLUDE_MTE_REGS requires AArch64)
+	endif
+endif #(CTX_INCLUDE_MTE_REGS)
 
 ifeq ($(PSA_FWU_SUPPORT),1)
-    $(info PSA_FWU_SUPPORT is an experimental feature)
-endif
+        $(info PSA_FWU_SUPPORT is an experimental feature)
+endif #(PSA_FWU_SUPPORT)
 
 ifeq ($(FEATURE_DETECTION),1)
-    $(info FEATURE_DETECTION is an experimental feature)
-endif
+        $(info FEATURE_DETECTION is an experimental feature)
+endif #(FEATURE_DETECTION)
 
 ifneq ($(ENABLE_SME2_FOR_NS), 0)
-    ifeq (${ENABLE_SME_FOR_NS}, 0)
-        $(warning "ENABLE_SME2_FOR_NS requires ENABLE_SME_FOR_NS also to be set")
-        $(warning "Forced ENABLE_SME_FOR_NS=1")
-        override ENABLE_SME_FOR_NS	:= 1
-    endif
-endif
+	ifeq (${ENABLE_SME_FOR_NS}, 0)
+                $(warning "ENABLE_SME2_FOR_NS requires ENABLE_SME_FOR_NS also \
+                to be set")
+                $(warning "Forced ENABLE_SME_FOR_NS=1")
+		override ENABLE_SME_FOR_NS	:= 1
+	endif
+endif #(ENABLE_SME2_FOR_NS)
 
 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-    ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
-        $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2")
-    endif
-endif
+	ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+                $(error "ALLOW_RO_XLAT_TABLES requires translation tables \
+                library v2")
+	endif
+endif #(ARM_XLAT_TABLES_LIB_V1)
 
 ifneq (${DECRYPTION_SUPPORT},none)
-    ifeq (${TRUSTED_BOARD_BOOT}, 0)
-        $(error TRUSTED_BOARD_BOOT must be enabled for DECRYPTION_SUPPORT to be set)
-    endif
-endif
+	ifeq (${TRUSTED_BOARD_BOOT}, 0)
+                $(error TRUSTED_BOARD_BOOT must be enabled for DECRYPTION_SUPPORT \
+                to be set)
+	endif
+endif #(DECRYPTION_SUPPORT)
 
 # Ensure that no Aarch64-only features are enabled in Aarch32 build
 ifeq (${ARCH},aarch32)
 
-    # SME/SVE only supported on AArch64
-    ifneq (${ENABLE_SME_FOR_NS},0)
-        $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
-    endif
+	# SME/SVE only supported on AArch64
+	ifneq (${ENABLE_SME_FOR_NS},0)
+                $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
+	endif
 
-    ifeq (${ENABLE_SVE_FOR_NS},1)
-        # Warning instead of error due to CI dependency on this
-        $(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
-    endif
+	ifeq (${ENABLE_SVE_FOR_NS},1)
+		# Warning instead of error due to CI dependency on this
+                $(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
+	endif
 
-    # BRBE is not supported in AArch32
-    ifeq (${ENABLE_BRBE_FOR_NS},1)
-        $(error "ENABLE_BRBE_FOR_NS cannot be used with ARCH=aarch32")
-    endif
+	# BRBE is not supported in AArch32
+	ifeq (${ENABLE_BRBE_FOR_NS},1)
+                $(error "ENABLE_BRBE_FOR_NS cannot be used with ARCH=aarch32")
+	endif
 
-    # FEAT_RNG_TRAP is not supported in AArch32
-    ifeq (${ENABLE_FEAT_RNG_TRAP},1)
-        $(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
-    endif
-endif
+	# FEAT_RNG_TRAP is not supported in AArch32
+	ifeq (${ENABLE_FEAT_RNG_TRAP},1)
+                $(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
+	endif
+endif #(ARCH=aarch32)
 
 # Ensure ENABLE_RME is not used with SME
 ifeq (${ENABLE_RME},1)
-    ifneq (${ENABLE_SME_FOR_NS},0)
-        $(error "ENABLE_SME_FOR_NS cannot be used with ENABLE_RME")
-    endif
+	ifneq (${ENABLE_SME_FOR_NS},0)
+                $(error "ENABLE_SME_FOR_NS cannot be used with ENABLE_RME")
+	endif
 endif
 
 ifneq (${ENABLE_SME_FOR_NS},0)
-    ifeq (${ENABLE_SVE_FOR_NS},0)
-        $(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
-    endif
-endif
+	ifeq (${ENABLE_SVE_FOR_NS},0)
+                $(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
+	endif
+endif #(ENABLE_SME_FOR_NS)
 
 # Secure SME/SVE requires the non-secure component as well
 ifeq (${ENABLE_SME_FOR_SWD},1)
-    ifeq (${ENABLE_SME_FOR_NS},0)
-        $(error "ENABLE_SME_FOR_SWD requires ENABLE_SME_FOR_NS")
-    endif
-    ifeq (${ENABLE_SVE_FOR_SWD},0)
-        $(error "ENABLE_SME_FOR_SWD requires ENABLE_SVE_FOR_SWD")
-    endif
-endif
+	ifeq (${ENABLE_SME_FOR_NS},0)
+                $(error "ENABLE_SME_FOR_SWD requires ENABLE_SME_FOR_NS")
+	endif
+	ifeq (${ENABLE_SVE_FOR_SWD},0)
+                $(error "ENABLE_SME_FOR_SWD requires ENABLE_SVE_FOR_SWD")
+	endif
+endif #(ENABLE_SME_FOR_SWD)
+
 ifeq (${ENABLE_SVE_FOR_SWD},1)
-    ifeq (${ENABLE_SVE_FOR_NS},0)
-        $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
-    endif
-endif
+	ifeq (${ENABLE_SVE_FOR_NS},0)
+                $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
+	endif
+endif #(ENABLE_SVE_FOR_SWD)
 
 # SVE and SME cannot be used with CTX_INCLUDE_FPREGS since secure manager does
 # its own context management including FPU registers.
 ifeq (${CTX_INCLUDE_FPREGS},1)
-    ifneq (${ENABLE_SME_FOR_NS},0)
-        $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
-    endif
+	ifneq (${ENABLE_SME_FOR_NS},0)
+                $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
+	endif
 
-    ifeq (${ENABLE_SVE_FOR_NS},1)
-        # Warning instead of error due to CI dependency on this
-        $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
-        $(warning "Forced ENABLE_SVE_FOR_NS=0")
-        override ENABLE_SVE_FOR_NS	:= 0
-    endif
-endif
+	ifeq (${ENABLE_SVE_FOR_NS},1)
+		# Warning instead of error due to CI dependency on this
+                $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
+                $(warning "Forced ENABLE_SVE_FOR_NS=0")
+		override ENABLE_SVE_FOR_NS	:= 0
+	endif
+endif #(CTX_INCLUDE_FPREGS)
 
 ifeq ($(DRTM_SUPPORT),1)
-    $(info DRTM_SUPPORT is an experimental feature)
+        $(info DRTM_SUPPORT is an experimental feature)
 endif
 
 ifeq (${ENABLE_RME},1)
-    ifneq (${SEPARATE_CODE_AND_RODATA},1)
-        $(error `ENABLE_RME=1` requires `SEPARATE_CODE_AND_RODATA=1`)
-    endif
+	ifneq (${SEPARATE_CODE_AND_RODATA},1)
+                $(error `ENABLE_RME=1` requires `SEPARATE_CODE_AND_RODATA=1`)
+	endif
 endif
 
+# Determine if FEAT_RNG is supported
+ENABLE_FEAT_RNG		=	$(if $(findstring rng,${arch-features}),1,0)
+
+# Determine if FEAT_SB is supported
+ENABLE_FEAT_SB		=	$(if $(findstring sb,${arch-features}),1,0)
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
 
 ifdef BL1_SOURCES
-NEED_BL1 := yes
-endif
+	NEED_BL1 := yes
+endif #(BL1_SOURCES)
 
 ifdef BL2_SOURCES
 	NEED_BL2 := yes
@@ -989,64 +1054,64 @@
 	# Using BL2 implies that a BL33 image also needs to be supplied for the FIP and
 	# Certificate generation tools. This flag can be overridden by the platform.
 	ifdef EL3_PAYLOAD_BASE
-                # If booting an EL3 payload there is no need for a BL33 image
-                # in the FIP file.
-                NEED_BL33		:=	no
-        else
-                ifdef PRELOADED_BL33_BASE
-                        # If booting a BL33 preloaded image there is no need of
-                        # another one in the FIP file.
-                        NEED_BL33		:=	no
-                else
-                        NEED_BL33		?=	yes
-                endif
-        endif
-endif
+		# If booting an EL3 payload there is no need for a BL33 image
+		# in the FIP file.
+		NEED_BL33		:=	no
+	else
+		ifdef PRELOADED_BL33_BASE
+			# If booting a BL33 preloaded image there is no need of
+			# another one in the FIP file.
+			NEED_BL33		:=	no
+		else
+			NEED_BL33		?=	yes
+		endif
+	endif
+endif #(BL2_SOURCES)
 
 ifdef BL2U_SOURCES
-NEED_BL2U := yes
-endif
+	NEED_BL2U := yes
+endif #(BL2U_SOURCES)
 
 # If SCP_BL2 is given, we always want FIP to include it.
 ifdef SCP_BL2
-        NEED_SCP_BL2		:=	yes
-endif
+	NEED_SCP_BL2		:=	yes
+endif #(SCP_BL2)
 
 # For AArch32, BL31 is not currently supported.
 ifneq (${ARCH},aarch32)
-    ifdef BL31_SOURCES
-        # When booting an EL3 payload, there is no need to compile the BL31 image nor
-        # put it in the FIP.
-        ifndef EL3_PAYLOAD_BASE
-            NEED_BL31 := yes
-        endif
-    endif
-endif
+	ifdef BL31_SOURCES
+	# When booting an EL3 payload, there is no need to compile the BL31
+	# image nor put it in the FIP.
+		ifndef EL3_PAYLOAD_BASE
+			NEED_BL31 := yes
+		endif
+	endif
+endif #(ARCH=aarch64)
 
 # Process TBB related flags
 ifneq (${GENERATE_COT},0)
-        # Common cert_create options
-        ifneq (${CREATE_KEYS},0)
+	# Common cert_create options
+	ifneq (${CREATE_KEYS},0)
                 $(eval CRT_ARGS += -n)
                 $(eval FWU_CRT_ARGS += -n)
-                ifneq (${SAVE_KEYS},0)
+		ifneq (${SAVE_KEYS},0)
                         $(eval CRT_ARGS += -k)
                         $(eval FWU_CRT_ARGS += -k)
-                endif
-        endif
-        # Include TBBR makefile (unless the platform indicates otherwise)
-        ifeq (${INCLUDE_TBBR_MK},1)
+		endif
+	endif
+	# Include TBBR makefile (unless the platform indicates otherwise)
+	ifeq (${INCLUDE_TBBR_MK},1)
                 include make_helpers/tbbr/tbbr_tools.mk
-        endif
-endif
+	endif
+endif #(GENERATE_COT)
 
 ifneq (${FIP_ALIGN},0)
-FIP_ARGS += --align ${FIP_ALIGN}
-endif
+	FIP_ARGS += --align ${FIP_ALIGN}
+endif #(FIP_ALIGN)
 
 ifdef FDT_SOURCES
-NEED_FDT := yes
-endif
+	NEED_FDT := yes
+endif #(FDT_SOURCES)
 
 ################################################################################
 # Include libraries' Makefile that are used in all BL
@@ -1055,39 +1120,6 @@
 include lib/stack_protector/stack_protector.mk
 
 ################################################################################
-# Auxiliary tools (fiptool, cert_create, etc)
-################################################################################
-
-# Variables for use with Certificate Generation Tool
-CRTTOOLPATH		?=	tools/cert_create
-CRTTOOL			?=	${CRTTOOLPATH}/cert_create${BIN_EXT}
-
-# Variables for use with Firmware Encryption Tool
-ENCTOOLPATH		?=	tools/encrypt_fw
-ENCTOOL			?=	${ENCTOOLPATH}/encrypt_fw${BIN_EXT}
-
-# Variables for use with Firmware Image Package
-FIPTOOLPATH		?=	tools/fiptool
-FIPTOOL			?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
-
-# Variables for use with sptool
-SPTOOLPATH		?=	tools/sptool
-SPTOOL			?=	${SPTOOLPATH}/sptool.py
-SP_MK_GEN		?=	${SPTOOLPATH}/sp_mk_generator.py
-
-# Variables for use with ROMLIB
-ROMLIBPATH		?=	lib/romlib
-
-# Variable for use with Python
-PYTHON			?=	python3
-
-# Variables for use with documentation build using Sphinx tool
-DOCS_PATH		?=	docs
-
-# Defination of SIMICS flag
-SIMICS_BUILD	?=	0
-
-################################################################################
 # Include BL specific makefiles
 ################################################################################
 
@@ -1111,78 +1143,78 @@
 # Build options checks
 ################################################################################
 
+# Boolean_Flags
 $(eval $(call assert_booleans,\
     $(sort \
-        ALLOW_RO_XLAT_TABLES \
-        BL2_ENABLE_SP_LOAD \
-        COLD_BOOT_SINGLE_CPU \
-        CREATE_KEYS \
-        CTX_INCLUDE_AARCH32_REGS \
-        CTX_INCLUDE_FPREGS \
-        CTX_INCLUDE_EL2_REGS \
-        DEBUG \
-        DISABLE_MTPMU \
-        DYN_DISABLE_AUTH \
-        EL3_EXCEPTION_HANDLING \
-        ENABLE_AMU_AUXILIARY_COUNTERS \
-        ENABLE_AMU_FCONF \
-        AMU_RESTRICT_COUNTERS \
-        ENABLE_ASSERTIONS \
-        ENABLE_FEAT_SB \
-        ENABLE_PIE \
-        ENABLE_PMF \
-        ENABLE_PSCI_STAT \
-        ENABLE_RUNTIME_INSTRUMENTATION \
-        ENABLE_SME_FOR_SWD \
-        ENABLE_SVE_FOR_SWD \
-        ERROR_DEPRECATED \
-        FAULT_INJECTION_SUPPORT \
-        GENERATE_COT \
-        GICV2_G0_FOR_EL3 \
-        HANDLE_EA_EL3_FIRST_NS \
-        HW_ASSISTED_COHERENCY \
-        MEASURED_BOOT \
-        DRTM_SUPPORT \
-        NS_TIMER_SWITCH \
-        OVERRIDE_LIBC \
-        PL011_GENERIC_UART \
-        PLAT_RSS_NOT_SUPPORTED \
-        PROGRAMMABLE_RESET_ADDRESS \
-        PSCI_EXTENDED_STATE_ID \
-        PSCI_OS_INIT_MODE \
-        RESET_TO_BL31 \
-        SAVE_KEYS \
-        SEPARATE_CODE_AND_RODATA \
-        SEPARATE_BL2_NOLOAD_REGION \
-        SEPARATE_NOBITS_REGION \
-        SPIN_ON_BL1_EXIT \
-        SPM_MM \
-        SPMC_AT_EL3 \
-        SPMD_SPM_AT_SEL2 \
-        TRUSTED_BOARD_BOOT \
-        USE_COHERENT_MEM \
-        USE_DEBUGFS \
-        ARM_IO_IN_DTB \
-        SDEI_IN_FCONF \
-        SEC_INT_DESC_IN_FCONF \
-        USE_ROMLIB \
-        USE_TBBR_DEFS \
-        WARMBOOT_ENABLE_DCACHE_EARLY \
-        RESET_TO_BL2 \
-        BL2_IN_XIP_MEM \
-        BL2_INV_DCACHE \
-        USE_SPINLOCK_CAS \
-        ENCRYPT_BL31 \
-        ENCRYPT_BL32 \
-        ERRATA_SPECULATIVE_AT \
-        RAS_TRAP_NS_ERR_REC_ACCESS \
-        COT_DESC_IN_DTB \
-        USE_SP804_TIMER \
-        PSA_FWU_SUPPORT \
-        ENABLE_MPMM \
-        ENABLE_MPMM_FCONF \
-        SIMICS_BUILD \
-        FEATURE_DETECTION \
+	ALLOW_RO_XLAT_TABLES \
+	BL2_ENABLE_SP_LOAD \
+	COLD_BOOT_SINGLE_CPU \
+	CREATE_KEYS \
+	CTX_INCLUDE_AARCH32_REGS \
+	CTX_INCLUDE_FPREGS \
+	CTX_INCLUDE_EL2_REGS \
+	DEBUG \
+	DISABLE_MTPMU \
+	DYN_DISABLE_AUTH \
+	EL3_EXCEPTION_HANDLING \
+	ENABLE_AMU_AUXILIARY_COUNTERS \
+	ENABLE_AMU_FCONF \
+	AMU_RESTRICT_COUNTERS \
+	ENABLE_ASSERTIONS \
+	ENABLE_FEAT_SB \
+	ENABLE_PIE \
+	ENABLE_PMF \
+	ENABLE_PSCI_STAT \
+	ENABLE_RUNTIME_INSTRUMENTATION \
+	ENABLE_SME_FOR_SWD \
+	ENABLE_SVE_FOR_SWD \
+	ERROR_DEPRECATED \
+	FAULT_INJECTION_SUPPORT \
+	GENERATE_COT \
+	GICV2_G0_FOR_EL3 \
+	HANDLE_EA_EL3_FIRST_NS \
+	HW_ASSISTED_COHERENCY \
+	MEASURED_BOOT \
+	DRTM_SUPPORT \
+	NS_TIMER_SWITCH \
+	OVERRIDE_LIBC \
+	PL011_GENERIC_UART \
+	PLAT_RSS_NOT_SUPPORTED \
+	PROGRAMMABLE_RESET_ADDRESS \
+	PSCI_EXTENDED_STATE_ID \
+	PSCI_OS_INIT_MODE \
+	RESET_TO_BL31 \
+	SAVE_KEYS \
+	SEPARATE_CODE_AND_RODATA \
+	SEPARATE_BL2_NOLOAD_REGION \
+	SEPARATE_NOBITS_REGION \
+	SPIN_ON_BL1_EXIT \
+	SPM_MM \
+	SPMC_AT_EL3 \
+	SPMD_SPM_AT_SEL2 \
+	TRUSTED_BOARD_BOOT \
+	USE_COHERENT_MEM \
+	USE_DEBUGFS \
+	ARM_IO_IN_DTB \
+	SDEI_IN_FCONF \
+	SEC_INT_DESC_IN_FCONF \
+	USE_ROMLIB \
+	USE_TBBR_DEFS \
+	WARMBOOT_ENABLE_DCACHE_EARLY \
+	RESET_TO_BL2 \
+	BL2_IN_XIP_MEM \
+	BL2_INV_DCACHE \
+	USE_SPINLOCK_CAS \
+	ENCRYPT_BL31 \
+	ENCRYPT_BL32 \
+	ERRATA_SPECULATIVE_AT \
+	RAS_TRAP_NS_ERR_REC_ACCESS \
+	COT_DESC_IN_DTB \
+	USE_SP804_TIMER \
+	PSA_FWU_SUPPORT \
+	ENABLE_MPMM \
+	ENABLE_MPMM_FCONF \
+	FEATURE_DETECTION \
 	TRNG_SUPPORT \
 	ERRATA_ABI_SUPPORT \
 	ERRATA_NON_ARM_INTERCONNECT \
@@ -1190,52 +1222,53 @@
 	RAS_FFH_SUPPORT \
 )))
 
+# Numeric_Flags
 $(eval $(call assert_numerics,\
     $(sort \
-        ARM_ARCH_MAJOR \
-        ARM_ARCH_MINOR \
-        BRANCH_PROTECTION \
-        CTX_INCLUDE_PAUTH_REGS \
-        CTX_INCLUDE_MTE_REGS \
-        CTX_INCLUDE_NEVE_REGS \
-        CRYPTO_SUPPORT \
-        ENABLE_BRBE_FOR_NS \
-        ENABLE_TRBE_FOR_NS \
-        ENABLE_BTI \
-        ENABLE_PAUTH \
-        ENABLE_FEAT_AMU \
-        ENABLE_FEAT_AMUv1p1 \
-        ENABLE_FEAT_CSV2_2 \
-        ENABLE_FEAT_RAS	\
-        ENABLE_FEAT_DIT \
-        ENABLE_FEAT_ECV \
-        ENABLE_FEAT_FGT \
-        ENABLE_FEAT_HCX \
-        ENABLE_FEAT_PAN \
-        ENABLE_FEAT_RNG \
-        ENABLE_FEAT_RNG_TRAP \
-        ENABLE_FEAT_SEL2 \
-        ENABLE_FEAT_TCR2 \
-        ENABLE_FEAT_S2PIE \
-        ENABLE_FEAT_S1PIE \
-        ENABLE_FEAT_S2POE \
-        ENABLE_FEAT_S1POE \
-        ENABLE_FEAT_GCS \
-        ENABLE_FEAT_VHE \
-        ENABLE_MPAM_FOR_LOWER_ELS \
-        ENABLE_RME \
-        ENABLE_SPE_FOR_NS \
-        ENABLE_SYS_REG_TRACE_FOR_NS \
-        ENABLE_SME_FOR_NS \
-        ENABLE_SME2_FOR_NS \
-        ENABLE_SVE_FOR_NS \
-        ENABLE_TRF_FOR_NS \
-        FW_ENC_STATUS \
-        NR_OF_FW_BANKS \
-        NR_OF_IMAGES_IN_FW_BANK \
-        TWED_DELAY \
-        ENABLE_FEAT_TWED \
-        SVE_VECTOR_LEN \
+	ARM_ARCH_MAJOR \
+	ARM_ARCH_MINOR \
+	BRANCH_PROTECTION \
+	CTX_INCLUDE_PAUTH_REGS \
+	CTX_INCLUDE_MTE_REGS \
+	CTX_INCLUDE_NEVE_REGS \
+	CRYPTO_SUPPORT \
+	ENABLE_BRBE_FOR_NS \
+	ENABLE_TRBE_FOR_NS \
+	ENABLE_BTI \
+	ENABLE_PAUTH \
+	ENABLE_FEAT_AMU \
+	ENABLE_FEAT_AMUv1p1 \
+	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_RAS	\
+	ENABLE_FEAT_DIT \
+	ENABLE_FEAT_ECV \
+	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_HCX \
+	ENABLE_FEAT_PAN \
+	ENABLE_FEAT_RNG \
+	ENABLE_FEAT_RNG_TRAP \
+	ENABLE_FEAT_SEL2 \
+	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_S2PIE \
+	ENABLE_FEAT_S1PIE \
+	ENABLE_FEAT_S2POE \
+	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_GCS \
+	ENABLE_FEAT_VHE \
+	ENABLE_MPAM_FOR_LOWER_ELS \
+	ENABLE_RME \
+	ENABLE_SPE_FOR_NS \
+	ENABLE_SYS_REG_TRACE_FOR_NS \
+	ENABLE_SME_FOR_NS \
+	ENABLE_SME2_FOR_NS \
+	ENABLE_SVE_FOR_NS \
+	ENABLE_TRF_FOR_NS \
+	FW_ENC_STATUS \
+	NR_OF_FW_BANKS \
+	NR_OF_IMAGES_IN_FW_BANK \
+	TWED_DELAY \
+	ENABLE_FEAT_TWED \
+	SVE_VECTOR_LEN \
 	IMPDEF_SYSREG_TRAP \
 )))
 
@@ -1255,162 +1288,162 @@
 
 $(eval $(call add_defines,\
     $(sort \
-        ALLOW_RO_XLAT_TABLES \
-        ARM_ARCH_MAJOR \
-        ARM_ARCH_MINOR \
-        BL2_ENABLE_SP_LOAD \
-        COLD_BOOT_SINGLE_CPU \
-        CTX_INCLUDE_AARCH32_REGS \
-        CTX_INCLUDE_FPREGS \
-        CTX_INCLUDE_PAUTH_REGS \
-        EL3_EXCEPTION_HANDLING \
-        CTX_INCLUDE_MTE_REGS \
-        CTX_INCLUDE_EL2_REGS \
-        CTX_INCLUDE_NEVE_REGS \
-        DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
-        DISABLE_MTPMU \
-        ENABLE_FEAT_AMU \
-        ENABLE_AMU_AUXILIARY_COUNTERS \
-        ENABLE_AMU_FCONF \
-        AMU_RESTRICT_COUNTERS \
-        ENABLE_ASSERTIONS \
-        ENABLE_BTI \
-        ENABLE_MPAM_FOR_LOWER_ELS \
-        ENABLE_PAUTH \
-        ENABLE_PIE \
-        ENABLE_PMF \
-        ENABLE_PSCI_STAT \
-        ENABLE_RME \
-        ENABLE_RUNTIME_INSTRUMENTATION \
-        ENABLE_SME_FOR_NS \
-        ENABLE_SME2_FOR_NS \
-        ENABLE_SME_FOR_SWD \
-        ENABLE_SPE_FOR_NS \
-        ENABLE_SVE_FOR_NS \
-        ENABLE_SVE_FOR_SWD \
-        ENCRYPT_BL31 \
-        ENCRYPT_BL32 \
-        ERROR_DEPRECATED \
-        FAULT_INJECTION_SUPPORT \
-        GICV2_G0_FOR_EL3 \
-        HANDLE_EA_EL3_FIRST_NS \
-        HW_ASSISTED_COHERENCY \
-        LOG_LEVEL \
-        MEASURED_BOOT \
-        DRTM_SUPPORT \
-        NS_TIMER_SWITCH \
-        PL011_GENERIC_UART \
-        PLAT_${PLAT} \
-        PLAT_RSS_NOT_SUPPORTED \
-        PROGRAMMABLE_RESET_ADDRESS \
-        PSCI_EXTENDED_STATE_ID \
-        PSCI_OS_INIT_MODE \
-        ENABLE_FEAT_RAS \
-        RAS_FFH_SUPPORT \
-        RESET_TO_BL31 \
-        SEPARATE_CODE_AND_RODATA \
-        SEPARATE_BL2_NOLOAD_REGION \
-        SEPARATE_NOBITS_REGION \
-        RECLAIM_INIT_CODE \
-        SPD_${SPD} \
-        SPIN_ON_BL1_EXIT \
-        SPM_MM \
-        SPMC_AT_EL3 \
-        SPMD_SPM_AT_SEL2 \
-        TRUSTED_BOARD_BOOT \
-        CRYPTO_SUPPORT \
-        TRNG_SUPPORT \
-        ERRATA_ABI_SUPPORT \
+	ALLOW_RO_XLAT_TABLES \
+	ARM_ARCH_MAJOR \
+	ARM_ARCH_MINOR \
+	BL2_ENABLE_SP_LOAD \
+	COLD_BOOT_SINGLE_CPU \
+	CTX_INCLUDE_AARCH32_REGS \
+	CTX_INCLUDE_FPREGS \
+	CTX_INCLUDE_PAUTH_REGS \
+	EL3_EXCEPTION_HANDLING \
+	CTX_INCLUDE_MTE_REGS \
+	CTX_INCLUDE_EL2_REGS \
+	CTX_INCLUDE_NEVE_REGS \
+	DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
+	DISABLE_MTPMU \
+	ENABLE_FEAT_AMU \
+	ENABLE_AMU_AUXILIARY_COUNTERS \
+	ENABLE_AMU_FCONF \
+	AMU_RESTRICT_COUNTERS \
+	ENABLE_ASSERTIONS \
+	ENABLE_BTI \
+	ENABLE_MPAM_FOR_LOWER_ELS \
+	ENABLE_PAUTH \
+	ENABLE_PIE \
+	ENABLE_PMF \
+	ENABLE_PSCI_STAT \
+	ENABLE_RME \
+	ENABLE_RUNTIME_INSTRUMENTATION \
+	ENABLE_SME_FOR_NS \
+	ENABLE_SME2_FOR_NS \
+	ENABLE_SME_FOR_SWD \
+	ENABLE_SPE_FOR_NS \
+	ENABLE_SVE_FOR_NS \
+	ENABLE_SVE_FOR_SWD \
+	ENCRYPT_BL31 \
+	ENCRYPT_BL32 \
+	ERROR_DEPRECATED \
+	FAULT_INJECTION_SUPPORT \
+	GICV2_G0_FOR_EL3 \
+	HANDLE_EA_EL3_FIRST_NS \
+	HW_ASSISTED_COHERENCY \
+	LOG_LEVEL \
+	MEASURED_BOOT \
+	DRTM_SUPPORT \
+	NS_TIMER_SWITCH \
+	PL011_GENERIC_UART \
+	PLAT_${PLAT} \
+	PLAT_RSS_NOT_SUPPORTED \
+	PROGRAMMABLE_RESET_ADDRESS \
+	PSCI_EXTENDED_STATE_ID \
+	PSCI_OS_INIT_MODE \
+	ENABLE_FEAT_RAS \
+	RAS_FFH_SUPPORT \
+	RESET_TO_BL31 \
+	SEPARATE_CODE_AND_RODATA \
+	SEPARATE_BL2_NOLOAD_REGION \
+	SEPARATE_NOBITS_REGION \
+	RECLAIM_INIT_CODE \
+	SPD_${SPD} \
+	SPIN_ON_BL1_EXIT \
+	SPM_MM \
+	SPMC_AT_EL3 \
+	SPMD_SPM_AT_SEL2 \
+	TRUSTED_BOARD_BOOT \
+	CRYPTO_SUPPORT \
+	TRNG_SUPPORT \
+	ERRATA_ABI_SUPPORT \
 	ERRATA_NON_ARM_INTERCONNECT \
-        USE_COHERENT_MEM \
-        USE_DEBUGFS \
-        ARM_IO_IN_DTB \
-        SDEI_IN_FCONF \
-        SEC_INT_DESC_IN_FCONF \
-        USE_ROMLIB \
-        USE_TBBR_DEFS \
-        WARMBOOT_ENABLE_DCACHE_EARLY \
-        RESET_TO_BL2 \
-        BL2_RUNS_AT_EL3	\
-        BL2_IN_XIP_MEM \
-        BL2_INV_DCACHE \
-        USE_SPINLOCK_CAS \
-        ERRATA_SPECULATIVE_AT \
-        RAS_TRAP_NS_ERR_REC_ACCESS \
-        COT_DESC_IN_DTB \
-        USE_SP804_TIMER \
-        ENABLE_FEAT_RNG \
-        ENABLE_FEAT_RNG_TRAP \
-        ENABLE_FEAT_SB \
-        ENABLE_FEAT_DIT \
-        NR_OF_FW_BANKS \
-        NR_OF_IMAGES_IN_FW_BANK \
-        PSA_FWU_SUPPORT \
-        ENABLE_BRBE_FOR_NS \
-        ENABLE_TRBE_FOR_NS \
-        ENABLE_SYS_REG_TRACE_FOR_NS \
-        ENABLE_TRF_FOR_NS \
-        ENABLE_FEAT_HCX \
-        ENABLE_MPMM \
-        ENABLE_MPMM_FCONF \
-        ENABLE_FEAT_FGT \
-        ENABLE_FEAT_ECV \
-        SIMICS_BUILD \
-        ENABLE_FEAT_AMUv1p1 \
-        ENABLE_FEAT_SEL2 \
-        ENABLE_FEAT_VHE \
-        ENABLE_FEAT_CSV2_2 \
-        ENABLE_FEAT_PAN \
-        ENABLE_FEAT_TCR2 \
-        ENABLE_FEAT_S2PIE \
-        ENABLE_FEAT_S1PIE \
-        ENABLE_FEAT_S2POE \
-        ENABLE_FEAT_S1POE \
-        ENABLE_FEAT_GCS \
-        FEATURE_DETECTION \
-        TWED_DELAY \
-        ENABLE_FEAT_TWED \
+	USE_COHERENT_MEM \
+	USE_DEBUGFS \
+	ARM_IO_IN_DTB \
+	SDEI_IN_FCONF \
+	SEC_INT_DESC_IN_FCONF \
+	USE_ROMLIB \
+	USE_TBBR_DEFS \
+	WARMBOOT_ENABLE_DCACHE_EARLY \
+	RESET_TO_BL2 \
+	BL2_RUNS_AT_EL3	\
+	BL2_IN_XIP_MEM \
+	BL2_INV_DCACHE \
+	USE_SPINLOCK_CAS \
+	ERRATA_SPECULATIVE_AT \
+	RAS_TRAP_NS_ERR_REC_ACCESS \
+	COT_DESC_IN_DTB \
+	USE_SP804_TIMER \
+	ENABLE_FEAT_RNG \
+	ENABLE_FEAT_RNG_TRAP \
+	ENABLE_FEAT_SB \
+	ENABLE_FEAT_DIT \
+	NR_OF_FW_BANKS \
+	NR_OF_IMAGES_IN_FW_BANK \
+	PSA_FWU_SUPPORT \
+	ENABLE_BRBE_FOR_NS \
+	ENABLE_TRBE_FOR_NS \
+	ENABLE_SYS_REG_TRACE_FOR_NS \
+	ENABLE_TRF_FOR_NS \
+	ENABLE_FEAT_HCX \
+	ENABLE_MPMM \
+	ENABLE_MPMM_FCONF \
+	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_ECV \
+	ENABLE_FEAT_AMUv1p1 \
+	ENABLE_FEAT_SEL2 \
+	ENABLE_FEAT_VHE \
+	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_PAN \
+	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_S2PIE \
+	ENABLE_FEAT_S1PIE \
+	ENABLE_FEAT_S2POE \
+	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_GCS \
+	FEATURE_DETECTION \
+	TWED_DELAY \
+	ENABLE_FEAT_TWED \
 	CONDITIONAL_CMO \
 	IMPDEF_SYSREG_TRAP \
+	SVE_VECTOR_LEN \
 )))
 
 ifeq (${SANITIZE_UB},trap)
         $(eval $(call add_define,MONITOR_TRAPS))
-endif
+endif #(SANITIZE_UB)
 
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
         $(eval $(call add_define,EL3_PAYLOAD_BASE))
 else
-        # Define the PRELOADED_BL33_BASE flag only if it is provided and
-        # EL3_PAYLOAD_BASE is not defined, as it has priority.
-        ifdef PRELOADED_BL33_BASE
+# Define the PRELOADED_BL33_BASE flag only if it is provided and
+# EL3_PAYLOAD_BASE is not defined, as it has priority.
+	ifdef PRELOADED_BL33_BASE
                 $(eval $(call add_define,PRELOADED_BL33_BASE))
-        endif
-endif
+	endif
+endif #(EL3_PAYLOAD_BASE)
 
 # Define the DYN_DISABLE_AUTH flag only if set.
 ifeq (${DYN_DISABLE_AUTH},1)
-$(eval $(call add_define,DYN_DISABLE_AUTH))
+        $(eval $(call add_define,DYN_DISABLE_AUTH))
 endif
 
 ifneq ($(findstring armlink,$(notdir $(LD))),)
-$(eval $(call add_define,USE_ARM_LINK))
+        $(eval $(call add_define,USE_ARM_LINK))
 endif
 
 # Generate and include sp_gen.mk if SPD is spmd and SP_LAYOUT_FILE is defined
 ifeq (${SPD},spmd)
 ifdef SP_LAYOUT_FILE
-        -include $(BUILD_PLAT)/sp_gen.mk
-        FIP_DEPS += sp
-        CRT_DEPS += sp
-        NEED_SP_PKG := yes
+	-include $(BUILD_PLAT)/sp_gen.mk
+	FIP_DEPS += sp
+	CRT_DEPS += sp
+	NEED_SP_PKG := yes
 else
-        ifeq (${SPMD_SPM_AT_SEL2},1)
-            $(error "SPMD with SPM at S-EL2 require SP_LAYOUT_FILE")
-        endif
-endif
-endif
+	ifeq (${SPMD_SPM_AT_SEL2},1)
+                $(error "SPMD with SPM at S-EL2 require SP_LAYOUT_FILE")
+	endif
+endif #(SP_LAYOUT_FILE)
+endif #(SPD)
 
 ################################################################################
 # Build targets
@@ -1431,7 +1464,7 @@
 else
     CPPFLAGS		+= 	-Wno-error=deprecated-declarations -Wno-error=cpp
 endif
-endif # !ERROR_DEPRECATED
+endif #(!ERROR_DEPRECATED)
 
 $(eval $(call MAKE_LIB_DIRS))
 $(eval $(call MAKE_LIB,c))
@@ -1439,11 +1472,11 @@
 # Expand build macros for the different images
 ifeq (${NEED_BL1},yes)
 BL1_SOURCES := $(sort ${BL1_SOURCES})
-
 $(eval $(call MAKE_BL,bl1))
-endif
+endif #(NEED_BL1)
 
 ifeq (${NEED_BL2},yes)
+
 ifeq (${RESET_TO_BL2}, 0)
 FIP_BL2_ARGS := tb-fw
 endif
@@ -1452,11 +1485,12 @@
 
 $(if ${BL2}, $(eval $(call TOOL_ADD_IMG,bl2,--${FIP_BL2_ARGS})),\
 	$(eval $(call MAKE_BL,bl2,${FIP_BL2_ARGS})))
-endif
+
+endif #(NEED_BL2)
 
 ifeq (${NEED_SCP_BL2},yes)
 $(eval $(call TOOL_ADD_IMG,scp_bl2,--scp-fw))
-endif
+endif #(NEED_SCP_BL2)
 
 ifeq (${NEED_BL31},yes)
 BL31_SOURCES += ${SPD_SOURCES}
@@ -1468,8 +1502,8 @@
 else
 $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw)),\
 	$(eval $(call MAKE_BL,bl31,soc-fw)))
-endif
-endif
+endif #(DECRYPTION_SUPPORT)
+endif #(NEED_BL31)
 
 # If a BL32 image is needed but neither BL32 nor BL32_SOURCES is defined, the
 # build system will call TOOL_ADD_IMG to print a warning message and abort the
@@ -1485,8 +1519,8 @@
 else
 $(if ${BUILD_BL32}, $(eval $(call MAKE_BL,bl32,tos-fw)),\
 	$(eval $(call TOOL_ADD_IMG,bl32,--tos-fw)))
-endif
-endif
+endif #(DECRYPTION_SUPPORT)
+endif #(NEED_BL32)
 
 # If RMM image is needed but RMM is not defined, Test Realm Payload (TRP)
 # needs to be built from RMM_SOURCES.
@@ -1496,23 +1530,23 @@
 BUILD_RMM := $(if $(RMM),,$(if $(RMM_SOURCES),1))
 
 $(if ${BUILD_RMM}, $(eval $(call MAKE_BL,rmm,rmm-fw)),\
-         $(eval $(call TOOL_ADD_IMG,rmm,--rmm-fw)))
-endif
+	 $(eval $(call TOOL_ADD_IMG,rmm,--rmm-fw)))
+endif #(NEED_RMM)
 
 # Add the BL33 image if required by the platform
 ifeq (${NEED_BL33},yes)
 $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw))
-endif
+endif #(NEED_BL33)
 
 ifeq (${NEED_BL2U},yes)
 $(if ${BL2U}, $(eval $(call TOOL_ADD_IMG,bl2u,--ap-fwu-cfg,FWU_)),\
 	$(eval $(call MAKE_BL,bl2u,ap-fwu-cfg,FWU_)))
-endif
+endif #(NEED_BL2U)
 
 # Expand build macros for the different images
 ifeq (${NEED_FDT},yes)
     $(eval $(call MAKE_DTBS,$(BUILD_PLAT)/fdts,$(FDT_SOURCES)))
-endif
+endif #(NEED_FDT)
 
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
@@ -1522,7 +1556,7 @@
 	@${ECHO_BLANK_LINE}
 	@echo "Built SP Images successfully"
 	@${ECHO_BLANK_LINE}
-endif
+endif #(NEED_SP_PKG)
 
 locate-checkpatch:
 ifndef CHECKPATCH
@@ -1531,7 +1565,7 @@
 ifeq (,$(wildcard ${CHECKPATCH}))
 	$(error "The file CHECKPATCH points to cannot be found, use eg: CHECKPATCH=../linux/scripts/checkpatch.pl")
 endif
-endif
+endif #(CHECKPATCH)
 
 clean:
 	@echo "  CLEAN"
@@ -1542,7 +1576,7 @@
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
 	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
-endif
+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
@@ -1557,7 +1591,7 @@
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
 	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
-endif
+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
@@ -1611,7 +1645,7 @@
 	@echo "Built $@ successfully"
 	@echo "Certificates can be found in ${BUILD_PLAT}"
 	@${ECHO_BLANK_LINE}
-endif
+endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FIP_CMD})
@@ -1628,7 +1662,7 @@
 	@echo "Built $@ successfully"
 	@echo "FWU certificates can be found in ${BUILD_PLAT}"
 	@${ECHO_BLANK_LINE}
-endif
+endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FWU_FIP_NAME}: ${FWU_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FWU_FIP_CMD})
@@ -1649,7 +1683,7 @@
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
 	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
-endif
+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
diff --git a/bl1/aarch64/bl1_arch_setup.c b/bl1/aarch64/bl1_arch_setup.c
index 0a1cb30..f3de536 100644
--- a/bl1/aarch64/bl1_arch_setup.c
+++ b/bl1/aarch64/bl1_arch_setup.c
@@ -17,19 +17,3 @@
 	/* Set the next EL to be AArch64 */
 	write_scr_el3(read_scr_el3() | SCR_RW_BIT);
 }
-
-/*******************************************************************************
- * Set the Secure EL1 required architectural state
- ******************************************************************************/
-void bl1_arch_next_el_setup(void)
-{
-	u_register_t next_sctlr;
-
-	/* Use the same endianness than the current BL */
-	next_sctlr = (read_sctlr_el3() & SCTLR_EE_BIT);
-
-	/* Set SCTLR Secure EL1 */
-	next_sctlr |= SCTLR_EL1_RES1;
-
-	write_sctlr_el1(next_sctlr);
-}
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index a2527e6..49dda85 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -41,6 +41,7 @@
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -72,6 +73,7 @@
          * aligned and lld does not align the LMA to the alignment specified
          * on the .data section.
          */
+        __RODATA_END_UNALIGNED__ = .;
         __RODATA_END__ = .;
 
         . = ALIGN(16);
diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h
index e119ba7..61fb5be 100644
--- a/bl1/bl1_private.h
+++ b/bl1/bl1_private.h
@@ -17,7 +17,6 @@
  * Function prototypes
  *****************************************/
 void bl1_arch_setup(void);
-void bl1_arch_next_el_setup(void);
 
 void bl1_prepare_next_image(unsigned int image_id);
 void bl1_run_bl2_in_root(void);
diff --git a/bl2/aarch64/bl2_run_next_image.S b/bl2/aarch64/bl2_run_next_image.S
index f0a8be8..1431a5f 100644
--- a/bl2/aarch64/bl2_run_next_image.S
+++ b/bl2/aarch64/bl2_run_next_image.S
@@ -24,15 +24,6 @@
 	tlbi	alle3
 	bl	bl2_el3_plat_prepare_exit
 
-#if ENABLE_PAUTH
-	/* ---------------------------------------------
-	 * Disable pointer authentication before jumping
-	 * to next boot image.
-	 * ---------------------------------------------
-	 */
-	bl	pauth_disable_el3
-#endif /* ENABLE_PAUTH */
-
 	ldp	x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
 	msr	elr_el3, x0
 	msr	spsr_el3, x1
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 5f689d5..db83a0c 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -35,6 +35,7 @@
 
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -57,6 +58,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
 
         __RODATA_END__ = .;
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 5da631c..4aa5cb0 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -65,6 +65,7 @@
 
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -78,6 +79,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
 
         __RODATA_END__ = .;
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 21c91b4..7b1a101 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -32,6 +32,7 @@
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -53,6 +54,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 8bcf94e..851ac47 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -519,7 +519,8 @@
 	 * flags using the appropriate helper.
 	 */
 2:
-	bfi	x7, x0, #FUNCID_SVE_HINT_SHIFT, #FUNCID_SVE_HINT_MASK
+	and	x16, x0, #(FUNCID_SVE_HINT_MASK << FUNCID_SVE_HINT_SHIFT)
+	orr	x7, x7, x16
 	bic	x0, x0, #(FUNCID_SVE_HINT_MASK << FUNCID_SVE_HINT_SHIFT)
 
 	/* Get the unique owning entity number */
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index abcae0c..7a8c41a 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -42,6 +42,7 @@
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(SORT(.text*)))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -62,6 +63,7 @@
         . = ALIGN(8);
 
 #   include <lib/el3_runtime/pubsub_events.h>
+        __RODATA_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 0a2bad0..dd81973 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -34,6 +34,7 @@
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -58,6 +59,7 @@
         . = ALIGN(8);
 
 #   include <lib/el3_runtime/pubsub_events.h>
+        __RODATA_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index b735f45..22bf11d 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -30,6 +30,7 @@
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -43,6 +44,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
 
         __RODATA_END__ = .;
diff --git a/changelog.yaml b/changelog.yaml
index 0c4644d..f21aa16 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -244,6 +244,13 @@
           - title: Corstone-1000
             scope: corstone-1000
 
+      - title: Aspeed
+        scope: aspeed
+
+        subsections:
+          - title: AST2700
+            scope: ast2700
+
       - title: Broadcom
         scope: brcm
 
@@ -1301,6 +1308,9 @@
       - title: Certificate Creation Tool
         scope: cert-create
 
+      - title: Memory Mapping Tool
+        scope: memmap
+
         deprecated:
           - cert_create
 
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index b591f2a..663859f 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -527,6 +527,15 @@
 :|G|: `rupsin01`_
 :|F|: plat/arm/board/tc
 
+Aspeed platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
+:|G|: `ChiaweiW`_
+:|M|: Neal Liu <neal_liu@aspeedtech.com>
+:|G|: `Neal-liu`_
+:|F|: docs/plat/ast2700.rst
+:|F|: plat/aspeed/
+
 HiSilicon HiKey and HiKey960 platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Haojian Zhuang <haojian.zhuang@linaro.org>
@@ -983,3 +992,5 @@
 .. _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
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index 1061ca0..ee322ac 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -91,7 +91,7 @@
       - 0x2: 64k
 
 - boot-order
-   - value type: <u32>
+   - value type: <u16>
    - A unique number amongst all partitions that specifies if this partition
      must be booted before others. The partition with the smaller number will be
      booted first.
diff --git a/docs/conf.py b/docs/conf.py
index 371632a..345f53b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,27 +9,34 @@
 #
 # See the options documentation at http://www.sphinx-doc.org/en/master/config
 
-import os
 
 # -- Project information -----------------------------------------------------
 
-project = 'Trusted Firmware-A'
+project = "Trusted Firmware-A"
+author = "Trusted Firmware-A contributors"
+version = "2.9.0"
+release = "2.9.0"
 
 # -- General configuration ---------------------------------------------------
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['myst_parser', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.plantuml']
+extensions = [
+    "myst_parser",
+    "sphinx.ext.autosectionlabel",
+    "sphinxcontrib.plantuml",
+    "sphinxcontrib.inkscapeconverter",
+]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
 
 # The suffix(es) of source filenames.
-source_suffix = ['.md', '.rst']
+source_suffix = [".md", ".rst"]
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -45,15 +52,16 @@
 exclude_patterns = [".env", "env", ".venv", "venv"]
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
 
 # Load the contents of the global substitutions file into the 'rst_prolog'
-# variable. This ensures that the substitutions are all inserted into each page.
-with open('global_substitutions.txt', 'r') as subs:
-  rst_prolog = subs.read()
+# variable. This ensures that the substitutions are all inserted into each
+# page.
+with open("global_substitutions.txt", "r") as subs:
+    rst_prolog = subs.read()
 
 # Minimum version of sphinx required
-needs_sphinx = '2.0'
+needs_sphinx = "2.0"
 
 # -- Options for HTML output -------------------------------------------------
 
@@ -68,21 +76,21 @@
 html_theme = "sphinx_rtd_theme"
 
 # The logo to display in the sidebar
-html_logo = 'resources/TrustedFirmware-Logo_standard-white.png'
+html_logo = "resources/TrustedFirmware-Logo_standard-white.png"
 
 # Options for the "sphinx-rtd-theme" theme
 html_theme_options = {
-    'collapse_navigation': False, # Can expand and collapse sidebar entries
-    'prev_next_buttons_location': 'both', # Top and bottom of the page
-    'style_external_links': True # Display an icon next to external links
+    "collapse_navigation": False,  # Can expand and collapse sidebar entries
+    "prev_next_buttons_location": "both",  # Top and bottom of the page
+    "style_external_links": True,  # Display an icon next to external links
 }
 
 # Path to _static directory
-html_static_path = ['_static']
+html_static_path = ["_static"]
 
 # Path to css file relative to html_static_path
 html_css_files = [
-    'css/custom.css',
+    "css/custom.css",
 ]
 
 # -- Options for autosectionlabel --------------------------------------------
@@ -92,4 +100,12 @@
 
 # -- Options for plantuml ----------------------------------------------------
 
+plantuml_output_format = "svg_img"
+
-plantuml_output_format = 'svg_img'
+# -- Options for latexmk  ----------------------------------------------------
+
+latex_engine = "xelatex"
+latex_elements = {
+    "maxlistdepth": "10",
+    "pointsize": "11pt",
+}
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 758d62b..ecbefdd 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -53,7 +53,7 @@
 errata workaround is ``ERRATA_<Processor name>_<ID>``, where the ``Processor name``
 is for example ``A57`` for the ``Cortex_A57`` CPU.
 
-Refer to :ref:`firmware_design_cpu_errata_reporting` for information on how to
+Refer to :ref:`firmware_design_cpu_errata_implementation` for information on how to
 write errata workaround functions.
 
 All workarounds are disabled by default. The platform is responsible for
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 8ac1c3e..131cca1 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -9,12 +9,12 @@
 to the stage where it hands-off control to firmware running in the normal
 world in DRAM. This is the cold boot path.
 
-TF-A also implements the `Power State Coordination Interface PDD`_ as a
-runtime service. PSCI is the interface from normal world software to firmware
-implementing power management use-cases (for example, secondary CPU boot,
-hotplug and idle). Normal world software can access TF-A runtime services via
-the Arm SMC (Secure Monitor Call) instruction. The SMC instruction must be
-used as mandated by the SMC Calling Convention (`SMCCC`_).
+TF-A also implements the `PSCI`_ as a runtime service. PSCI is the interface
+from normal world software to firmware implementing power management use-cases
+(for example, secondary CPU boot, hotplug and idle). Normal world software can
+access TF-A runtime services via the Arm SMC (Secure Monitor Call) instruction.
+The SMC instruction must be used as mandated by the SMC Calling Convention
+(`SMCCC`_).
 
 TF-A implements a framework for configuring and managing interrupts generated
 in either security state. The details of the interrupt management framework
@@ -245,63 +245,6 @@
    specific reset handler function (see the section: "CPU specific operations
    framework").
 
--  Control register setup (for AArch64)
-
-   -  ``SCTLR_EL3``. Instruction cache is enabled by setting the ``SCTLR_EL3.I``
-      bit. Alignment and stack alignment checking is enabled by setting the
-      ``SCTLR_EL3.A`` and ``SCTLR_EL3.SA`` bits. Exception endianness is set to
-      little-endian by clearing the ``SCTLR_EL3.EE`` bit.
-
-   -  ``SCR_EL3``. The register width of the next lower exception level is set
-      to AArch64 by setting the ``SCR.RW`` bit. The ``SCR.EA`` bit is set to trap
-      both External Aborts and SError Interrupts in EL3. The ``SCR.SIF`` bit is
-      also set to disable instruction fetches from Non-secure memory when in
-      secure state.
-
-   -  ``CPTR_EL3``. Accesses to the ``CPACR_EL1`` register from EL1 or EL2, or the
-      ``CPTR_EL2`` register from EL2 are configured to not trap to EL3 by
-      clearing the ``CPTR_EL3.TCPAC`` bit. Access to the trace functionality is
-      configured not to trap to EL3 by clearing the ``CPTR_EL3.TTA`` bit.
-      Instructions that access the registers associated with Floating Point
-      and Advanced SIMD execution are configured to not trap to EL3 by
-      clearing the ``CPTR_EL3.TFP`` bit.
-
-   -  ``DAIF``. The SError interrupt is enabled by clearing the SError interrupt
-      mask bit.
-
-   -  ``MDCR_EL3``. The trap controls, ``MDCR_EL3.TDOSA``, ``MDCR_EL3.TDA`` and
-      ``MDCR_EL3.TPM``, are set so that accesses to the registers they control
-      do not trap to EL3. AArch64 Secure self-hosted debug is disabled by
-      setting the ``MDCR_EL3.SDD`` bit. Also ``MDCR_EL3.SPD32`` is set to
-      disable AArch32 Secure self-hosted privileged debug from S-EL1.
-
--  Control register setup (for AArch32)
-
-   -  ``SCTLR``. Instruction cache is enabled by setting the ``SCTLR.I`` bit.
-      Alignment checking is enabled by setting the ``SCTLR.A`` bit.
-      Exception endianness is set to little-endian by clearing the
-      ``SCTLR.EE`` bit.
-
-   -  ``SCR``. The ``SCR.SIF`` bit is set to disable instruction fetches from
-      Non-secure memory when in secure state.
-
-   -  ``CPACR``. Allow execution of Advanced SIMD instructions at PL0 and PL1,
-      by clearing the ``CPACR.ASEDIS`` bit. Access to the trace functionality
-      is configured not to trap to undefined mode by clearing the
-      ``CPACR.TRCDIS`` bit.
-
-   -  ``NSACR``. Enable non-secure access to Advanced SIMD functionality and
-      system register access to implemented trace registers.
-
-   -  ``FPEXC``. Enable access to the Advanced SIMD and floating-point
-      functionality from all Exception levels.
-
-   -  ``CPSR.A``. The Asynchronous data abort interrupt is enabled by clearing
-      the Asynchronous data abort interrupt mask bit.
-
-   -  ``SDCR``. The ``SDCR.SPD`` field is set to disable AArch32 Secure
-      self-hosted privileged debug.
-
 Platform initialization
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -457,8 +400,7 @@
 memory with the entrypoint and Saved Program Status Register (``SPSR``) of the
 normal world software image. The entrypoint is the load address of the BL33
 image. The ``SPSR`` is determined as specified in Section 5.13 of the
-`Power State Coordination Interface PDD`_. This information is passed to the
-EL3 Runtime Software.
+`PSCI`_. This information is passed to the EL3 Runtime Software.
 
 AArch64 BL31 (EL3 Runtime Software) execution
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1009,8 +951,8 @@
 
 The PSCI v1.1 specification categorizes APIs as optional and mandatory. All the
 mandatory APIs in PSCI v1.1, PSCI v1.0 and in PSCI v0.2 draft specification
-`Power State Coordination Interface PDD`_ are implemented. The table lists
-the PSCI v1.1 APIs and their support in generic code.
+`PSCI`_ are implemented. The table lists the PSCI v1.1 APIs and their support
+in generic code.
 
 An API implementation might have a dependency on platform code e.g. CPU_SUSPEND
 requires the platform to export a part of the implementation. Hence the level
@@ -1302,8 +1244,9 @@
 handling functions.
 
 Details for implementing a CPU specific reset handler can be found in
-Section 8. Details for implementing a platform specific reset handler can be
-found in the :ref:`Porting Guide` (see the ``plat_reset_handler()`` function).
+:ref:`firmware_design_cpu_specific_reset_handling`. Details for implementing a
+platform specific reset handler can be found in the :ref:`Porting Guide` (see
+the``plat_reset_handler()`` function).
 
 When adding functionality to a reset handler, keep in mind that if a different
 reset handling behavior is required between the first and the subsequent
@@ -1397,12 +1340,38 @@
 the platform makefile. The generic CPU specific operations framework code exists
 in ``lib/cpus/aarch64/cpu_helpers.S``.
 
+CPU PCS
+~~~~~~~
+
+All assembly functions in CPU files are asked to follow a modified version of
+the Procedure Call Standard (PCS) in their internals. This is done to ensure
+calling these functions from outside the file doesn't unexpectedly corrupt
+registers in the very early environment and to help the internals to be easier
+to understand. Please see the :ref:`firmware_design_cpu_errata_implementation`
+for any function specific restrictions.
+
++--------------+---------------------------------+
+|   register   | use                             |
++==============+=================================+
+|   x0 - x15   | scratch                         |
++--------------+---------------------------------+
+|   x16, x17   | do not use (used by the linker) |
++--------------+---------------------------------+
+|     x18      | do not use (platform register)  |
++--------------+---------------------------------+
+|   x19 - x28  | callee saved                    |
++--------------+---------------------------------+
+|   x29, x30   | FP, LR                          |
++--------------+---------------------------------+
+
+.. _firmware_design_cpu_specific_reset_handling:
+
 CPU specific Reset Handling
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 After a reset, the state of the CPU when it calls generic reset handler is:
-MMU turned off, both instruction and data caches turned off and not part
-of any coherency domain.
+MMU turned off, both instruction and data caches turned off, not part
+of any coherency domain and no stack.
 
 The BL entrypoint code first invokes the ``plat_reset_handler()`` to allow
 the platform to perform any system initialization required and any system
@@ -1412,10 +1381,9 @@
 in midr are used to find the matching ``cpu_ops`` entry. The ``reset_func()`` in
 the returned ``cpu_ops`` is then invoked which executes the required reset
 handling for that CPU and also any errata workarounds enabled by the platform.
-This function must preserve the values of general purpose registers x20 to x29.
 
-Refer to Section "Guidelines for Reset Handlers" for general guidelines
-regarding placement of code in a reset handler.
+It should be defined using the ``cpu_reset_func_{start,end}`` macros and its
+body may only clobber x0 to x14 with x14 being the cpu_rev parameter.
 
 CPU specific power down sequence
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1448,10 +1416,10 @@
 be reported and a pointer to the ASCII list of register names in a format
 expected by the crash reporting framework.
 
-.. _firmware_design_cpu_errata_reporting:
+.. _firmware_design_cpu_errata_implementation:
 
-CPU errata status reporting
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CPU errata implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Errata workarounds for CPUs supported in TF-A are applied during both cold and
 warm boots, shortly after reset. Individual Errata workarounds are enabled as
@@ -1459,59 +1427,92 @@
 therefore some are enabled by default, others not. Platform ports shall
 override build options to enable or disable errata as appropriate. The CPU
 drivers take care of applying errata workarounds that are enabled and applicable
-to a given CPU. Refer to :ref:`arm_cpu_macros_errata_workarounds` for more
-information.
+to a given CPU.
 
-Functions in CPU drivers that apply errata workaround must follow the
-conventions listed below.
+Each erratum has a build flag in ``lib/cpus/cpu-ops.mk`` of the form:
+``ERRATA_<cpu_num>_<erratum_id>``. It also has a short description in
+:ref:`arm_cpu_macros_errata_workarounds` on when it should apply.
 
-The errata workaround must be authored as two separate functions:
+Errata framework
+^^^^^^^^^^^^^^^^
 
--  One that checks for errata. This function must determine whether that errata
-   applies to the current CPU. Typically this involves matching the current
-   CPUs revision and variant against a value that's known to be affected by the
-   errata. If the function determines that the errata applies to this CPU, it
-   must return ``ERRATA_APPLIES``; otherwise, it must return
-   ``ERRATA_NOT_APPLIES``. The utility functions ``cpu_get_rev_var`` and
-   ``cpu_rev_var_ls`` functions may come in handy for this purpose.
+The errata framework is a convention and a small library to allow errata to be
+automatically discovered. It enables compliant errata to be automatically
+applied and reported at runtime (either by status reporting or the errata ABI).
 
-For an errata identified as ``E``, the check function must be named
-``check_errata_E``.
+To write a compliant mitigation for erratum number ``erratum_id`` on a cpu that
+declared itself (with ``declare_cpu_ops``) as ``cpu_name`` one needs 3 things:
 
-This function will be invoked at different times, both from assembly and from
-C run time. Therefore it must follow AAPCS, and must not use stack.
+#. A CPU revision checker function: ``check_erratum_<cpu_name>_<erratum_id>``
 
--  Another one that applies the errata workaround. This function would call the
-   check function described above, and applies errata workaround if required.
+   It should check whether this erratum applies on this revision of this CPU.
+   It will be called with the CPU revision as its first parameter (x0) and
+   should return one of ``ERRATA_APPLIES`` or ``ERRATA_NOT_APPLIES``.
 
-CPU drivers that apply errata workaround can optionally implement an assembly
-function that report the status of errata workarounds pertaining to that CPU.
-For a driver that registers the CPU, for example, ``cpux`` via ``declare_cpu_ops``
-macro, the errata reporting function, if it exists, must be named
-``cpux_errata_report``. This function will always be called with MMU enabled; it
-must follow AAPCS and may use stack.
+   It may only clobber x0 to x4. The rest should be treated as callee-saved.
 
-In a debug build of TF-A, on a CPU that comes out of reset, both BL1 and the
-runtime firmware (BL31 in AArch64, and BL32 in AArch32) will invoke errata
-status reporting function, if one exists, for that type of CPU.
+#. A workaround function: ``erratum_<cpu_name>_<erratum_id>_wa``
+
+   It should obtain the cpu revision (with ``cpu_get_rev_var``), call its
+   revision checker, and perform the mitigation, should the erratum apply.
+
+   It may only clobber x0 to x8. The rest should be treated as callee-saved.
+
+#. Register itself to the framework
+
+   Do this with
+   ``add_erratum_entry <cpu_name>, ERRATUM(<erratum_id>), <errata_flag>``
+   where the ``errata_flag`` is the enable flag in ``cpu-ops.mk`` described
+   above.
+
+See the next section on how to do this easily.
+
+.. note::
+
+ CVEs have the format ``CVE_<year>_<number>``. To fit them in the framework, the
+ ``erratum_id`` for the checker and the workaround functions become the
+ ``number`` part of its name and the ``ERRATUM(<number>)`` part of the
+ registration should instead be ``CVE(<year>, <number>)``. In the extremely
+ unlikely scenario where a CVE and an erratum numbers clash, the CVE number
+ should be prefixed with a zero.
+
+ Also, their build flag should be ``WORKAROUND_CVE_<year>_<number>``.
+
+.. note::
 
-To report the status of each errata workaround, the function shall use the
-assembler macro ``report_errata``, passing it:
+ AArch32 uses the legacy convention. The checker function has the format
+ ``check_errata_<erratum_id>`` and the workaround has the format
+ ``errata_<cpu_number>_<erratum_id>_wa`` where ``cpu_number`` is the shortform
+ letter and number name of the CPU.
 
--  The build option that enables the errata;
+ For CVEs the ``erratum_id`` also becomes ``cve_<year>_<number>``.
 
--  The name of the CPU: this must be the same identifier that CPU driver
-   registered itself with, using ``declare_cpu_ops``;
+Errata framework helpers
+^^^^^^^^^^^^^^^^^^^^^^^^
 
--  And the errata identifier: the identifier must match what's used in the
-   errata's check function described above.
+Writing these errata involves lots of boilerplate and repetitive code. On
+AArch64 there are helpers to omit most of this. They are located in
+``include/lib/cpus/aarch64/cpu_macros.S`` and the preferred way to implement
+errata. Please see their comments on how to use them.
 
-The errata status reporting function will be called once per CPU type/errata
-combination during the software's active life time.
+The most common type of erratum workaround, one that just sets a "chicken" bit
+in some arbitrary register, would have an implementation for the Cortex-A77,
+erratum #1925769 like::
 
-It's expected that whenever an errata workaround is submitted to TF-A, the
-errata reporting function is appropriately extended to report its status as
-well.
+    workaround_reset_start cortex_a77, ERRATUM(1925769), ERRATA_A77_1925769
+        sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, CORTEX_A77_CPUECTLR_EL1_BIT_8
+    workaround_reset_end cortex_a77, ERRATUM(1925769)
+
+    check_erratum_ls cortex_a77, ERRATUM(1925769), CPU_REV(1, 1)
+
+Status reporting
+^^^^^^^^^^^^^^^^
+
+In a debug build of TF-A, on a CPU that comes out of reset, both BL1 and the
+runtime firmware (BL31 in AArch64, and BL32 in AArch32) will invoke a generic
+errata status reporting function. It will read the ``errata_entries`` list of
+that cpu and will report whether each known erratum was applied and, if not,
+whether it should have been.
 
 Reporting the status of errata workaround is for informational purpose only; it
 has no functional significance.
@@ -1616,8 +1617,10 @@
 -  ``__RO_START__``
 -  ``__RO_END__``
 -  ``__TEXT_START__``
+-  ``__TEXT_END_UNALIGNED__``
 -  ``__TEXT_END__``
 -  ``__RODATA_START__``
+-  ``__RODATA_END_UNALIGNED__``
 -  ``__RODATA_END__``
 
 BL1's linker symbols
@@ -2786,7 +2789,7 @@
 
 -  `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D)`_
 
--  `Power State Coordination Interface PDD`_
+-  `PSCI`_
 
 -  `SMC Calling Convention`_
 
@@ -2796,10 +2799,8 @@
 
 *Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
 .. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
 .. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 7f73d7e..7f9519e 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -5,10 +5,10 @@
 critical data used at boot time, for example using a TPM, so that the
 security state can be attested later.
 
-The current implementation of the driver included in Trusted Firmware-A
-(TF-A) stores the measurements into a `TCG event log`_ in secure
-memory. No other means of recording measurements (such as a discrete TPM) is
-supported right now.
+The current implementation of the driver included in |TF-A| supports several
+backends and each has a different means to store the measurements.
+This section focuses on the `TCG event log`_ backend, which stores measurements
+in secure memory.
 
 The driver also provides mechanisms to pass the Event Log to normal world if
 needed.
diff --git a/docs/design_documents/psci_osi_mode.rst b/docs/design_documents/psci_osi_mode.rst
index 3296e27..a6e1bdf 100644
--- a/docs/design_documents/psci_osi_mode.rst
+++ b/docs/design_documents/psci_osi_mode.rst
@@ -4,7 +4,7 @@
 :Author: Maulik Shah & Wing Li
 :Organization: Qualcomm Innovation Center, Inc. & Google LLC
 :Contact: Maulik Shah <quic_mkshah@quicinc.com> & Wing Li <wingers@google.com>
-:Status: RFC
+:Status: Accepted
 
 .. contents:: Table of Contents
 
@@ -367,9 +367,11 @@
     ``psci_validate_state_coordination``. If validation fails, propagate the
     error up the call stack.
 
-* Update the return type of the platform specific ``pwr_domain_suspend``
-  handler from ``void`` to ``int``, to allow the platform to optionally perform
-  validations based on hardware states.
+* Add a new optional member ``pwr_domain_validate_suspend`` to
+  ``plat_psci_ops_t`` to allow the platform to optionally perform validations
+  based on hardware states.
+
+* The platform specific ``pwr_domain_suspend`` handler remains unchanged.
 
 .. image:: ../resources/diagrams/psci-osi-mode.png
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 4eafb39..c8ff7d5 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -531,7 +531,8 @@
    through feature specific build flags are supported by the PE or not by
    validating them either at boot phase or at runtime based on the value
    possessed by the feature flag (0 to 2) and report error messages at an early
-   stage.
+   stage. This flag will also enable errata ordering checking for ``DEBUG``
+   builds.
 
    This prevents and benefits us from EL3 runtime exceptions during context save
    and restore routines guarded by these build flags. Henceforth validating them
diff --git a/docs/getting_started/psci-lib-integration-guide.rst b/docs/getting_started/psci-lib-integration-guide.rst
index 4d690a9..7e4b0db 100644
--- a/docs/getting_started/psci-lib-integration-guide.rst
+++ b/docs/getting_started/psci-lib-integration-guide.rst
@@ -3,7 +3,7 @@
 
 This document describes the PSCI library interface with a focus on how to
 integrate with a suitable Trusted OS for an Armv8-A AArch32 system. The PSCI
-Library implements the PSCI Standard as described in `PSCI spec`_ and is meant
+Library implements the PSCI Standard as described in `PSCI`_ and is meant
 to be integrated with EL3 Runtime Software which invokes the PSCI Library
 interface appropriately. **EL3 Runtime Software** refers to software executing
 at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/
@@ -74,7 +74,7 @@
 ---------------------------
 
 PSCI library is in charge of initializing/restoring the non-secure CPU system
-registers according to `PSCI specification`_ during cold/warm boot.
+registers according to `PSCI`_ during cold/warm boot.
 This is referred to as ``PSCI CPU Context Management``. Registers that need to
 be preserved across CPU power down/power up cycles are maintained in
 ``cpu_context_t`` data structure. The initialization of other non-secure CPU
@@ -120,8 +120,8 @@
 PSCI Library Interface
 ----------------------
 
-The PSCI library implements the `PSCI Specification`_. The interfaces
-to this library are declared in ``psci_lib.h`` and are as listed below:
+The PSCI library implements the `PSCI`_. The interfaces to this library are
+declared in ``psci_lib.h`` and are as listed below:
 
 .. code:: c
 
@@ -254,7 +254,7 @@
 argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th
 arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4
 (in AArch64) when the SMC is received. These are the arguments to PSCI API as
-described in `PSCI spec`_. The 'flags' (8th argument) is a bit field parameter
+described in `PSCI`_. The 'flags' (8th argument) is a bit field parameter
 and is detailed in 'smccc.h' header. It includes whether the call is from the
 secure or non-secure world. The ``cookie`` (6th argument) and the ``handle``
 (7th argument) are not used and are reserved for future use.
@@ -273,7 +273,7 @@
     Return   : void
 
 This function performs the warm boot initialization/restoration as mandated by
-`PSCI spec`_. For AArch32, on wakeup from power down the CPU resets to secure SVC
+`PSCI`_. For AArch32, on wakeup from power down the CPU resets to secure SVC
 mode and the EL3 Runtime Software must perform the prerequisite initializations
 mentioned at top of this section. This function must be called with Data cache
 disabled (unless build option ``HW_ASSISTED_COHERENCY`` is enabled) but with MMU
@@ -496,7 +496,7 @@
    This callback is called in response to PSCI_MIGRATE_INFO_TYPE or
    PSCI_MIGRATE_INFO_UP_CPU APIs. The return value of this callback must
    correspond to the return value of PSCI_MIGRATE_INFO_TYPE API as described
-   in `PSCI spec`_. If the secure payload is a Uniprocessor (UP)
+   in `PSCI`_. If the secure payload is a Uniprocessor (UP)
    implementation, then it must update the mpidr of the CPU it is resident in
    via ``resident_cpu`` (first argument). The updates to ``resident_cpu`` is
    ignored if the secure payload is a multiprocessor (MP) implementation.
@@ -528,9 +528,7 @@
 
 --------------
 
-*Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _PSCI spec: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
-.. _PSCI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
-.. _PSCI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst
index 5a4be4d..fe64558 100644
--- a/docs/getting_started/rt-svc-writers-guide.rst
+++ b/docs/getting_started/rt-svc-writers-guide.rst
@@ -314,7 +314,7 @@
 
 --------------
 
-*Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
diff --git a/docs/index.rst b/docs/index.rst
index bce9bb7..a7a5993 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -90,7 +90,7 @@
 
 .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
-.. _Power State Coordination Interface (PSCI): http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Power State Coordination Interface (PSCI): https://developer.arm.com/documentation/den0022/latest/
 .. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
 .. _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
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index ea7d11c..5320a3b 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -249,4 +249,4 @@
 .. _build the binaries from source: https://github.com/ARM-software/SCP-firmware/blob/master/user_guide.md#scp-firmware-user-guide
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Juno Getting Started Guide: https://developer.arm.com/documentation/den0928/f/?lang=en
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
diff --git a/docs/plat/ast2700.rst b/docs/plat/ast2700.rst
new file mode 100644
index 0000000..0352aea
--- /dev/null
+++ b/docs/plat/ast2700.rst
@@ -0,0 +1,17 @@
+Aspeed AST2700
+==============
+
+Aspeed AST2700 is a 64-bit ARM SoC with 4-cores Cortex-A35 integrated.
+Each core operates at 1.6GHz.
+
+Boot Flow
+---------
+
+    BootRom --> BL1/BL2 --> TF-A BL31 --> BL32 (optional) --> BL33 --> Linux Kernel
+
+How to build
+------------
+
+.. code:: shell
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=ast2700
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 57c7303..188c986 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -8,6 +8,7 @@
 
    allwinner
    arm/index
+   ast2700
    meson-axg
    meson-gxbb
    meson-gxl
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 1250071..b557a16 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2818,6 +2818,17 @@
 for the higher power domain levels depending on the result of state
 coordination. The generic code expects the handler to succeed.
 
+plat_psci_ops.pwr_domain_validate_suspend() [optional]
+......................................................
+
+This is an optional function that is only compiled into the build if the build
+option ``PSCI_OS_INIT_MODE`` is enabled.
+
+If implemented, this function allows the platform to perform platform specific
+validations based on hardware states. The generic code expects this function to
+return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
+PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
+
 plat_psci_ops.pwr_domain_suspend_pwrdown_early() [optional]
 ...........................................................
 
@@ -2876,10 +2887,6 @@
 data, for example in DRAM. The Distributor can then be powered down using an
 implementation-defined sequence.
 
-If the build option ``PSCI_OS_INIT_MODE`` is enabled, the generic code expects
-the platform to return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
-PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
-
 plat_psci_ops.pwr_domain_pwr_down_wfi()
 .......................................
 
@@ -3661,7 +3668,7 @@
 
 *Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _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
 .. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html
 .. _FreeBSD: https://www.freebsd.org
diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index 13fb7cb..9730390 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -449,17 +449,20 @@
 portable, harder to understand, maintain and audit security wise. Also, static
 analysis tools generally don't analyze assembly code.
 
-There are, however, legitimate uses of assembly language. These include:
+If specific system-level instructions must be used (like cache maintenance
+operations), please consider using inline assembly. The ``arch_helpers.h`` files
+already define inline functions for a lot of these.
 
-  - Early boot code executed before the C runtime environment is setup.
-
-  - Exception handling code.
-
-  - Low-level code where the exact sequence of instructions executed on the CPU
-    matters, such as CPU reset sequences.
+There are, however, legitimate uses of assembly language. These are usually
+early boot (eg. cpu reset sequences) and exception handling code before the C
+runtime environment is set up.
 
-  - Low-level code where specific system-level instructions must be used, such
-    as cache maintenance operations.
+When writing assembly please note that a wide variety of common instruction
+sequences have helper macros in ``asm_macros.S`` which are preferred over
+writing them directly. This is especially important for debugging purposes as
+debug symbols must manually be included. Please use the ``func_prologue`` and
+``func_epilogue`` macros if you need to use the stack. Also, obeying the
+Procedure Call Standard (PCS) is generally recommended.
 
 Do not use weak functions
 -------------------------
diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
index e513ed4..9b693c8 100644
--- a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
+++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
@@ -21,7 +21,7 @@
 fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup()
 arm_bl1_setup -> arm_io_storage : plat_arm_io_setup()
 note over arm_io_storage : register and setup fip
-arm_bl1_setup -> fconf : set_fw_config_info(fw_config_base, max_size)
+arm_bl1_setup -> fconf : set_config_info(fw_config_base, max_size, FW_CONFIG_ID)
 note over fconf
 	set fw_config information
 	(address, size, image_id)
diff --git a/docs/resources/diagrams/psci-osi-mode.png b/docs/resources/diagrams/psci-osi-mode.png
index d322953..09175e5 100644
--- a/docs/resources/diagrams/psci-osi-mode.png
+++ b/docs/resources/diagrams/psci-osi-mode.png
Binary files differ
diff --git a/docs/tools/memory-layout-tool.rst b/docs/tools/memory-layout-tool.rst
index ce14dab..8874bd7 100644
--- a/docs/tools/memory-layout-tool.rst
+++ b/docs/tools/memory-layout-tool.rst
@@ -113,6 +113,122 @@
 
     poetry run memory --help
 
+Memory Footprint
+~~~~~~~~~~~~~~~~
+
+The tool enables users to view static memory consumption. When the options
+``-f``, or ``--footprint`` are provided, the script analyses the ELF binaries in
+the build path to generate a table (per memory type), showing memory allocation
+and usage. This is the default output generated by the tool.
+
+.. code:: shell
+
+    $ poetry run memory -f
+    build-path: build/fvp/release
+    +----------------------------------------------------------------------------+
+    |                         Memory Usage (bytes) [RAM]                         |
+    +-----------+------------+------------+------------+------------+------------+
+    | Component |   Start    |   Limit    |    Size    |    Free    |   Total    |
+    +-----------+------------+------------+------------+------------+------------+
+    |    BL1    |    4034000 |    4040000 |       7000 |       5000 |       c000 |
+    |    BL2    |    4021000 |    4034000 |       d000 |       6000 |      13000 |
+    |    BL2U   |    4021000 |    4034000 |       a000 |       9000 |      13000 |
+    |    BL31   |    4003000 |    4040000 |      1e000 |      1f000 |      3d000 |
+    +-----------+------------+------------+------------+------------+------------+
+
+    +----------------------------------------------------------------------------+
+    |                         Memory Usage (bytes) [ROM]                         |
+    +-----------+------------+------------+------------+------------+------------+
+    | Component |   Start    |   Limit    |    Size    |    Free    |   Total    |
+    +-----------+------------+------------+------------+------------+------------+
+    |    BL1    |          0 |    4000000 |       5df0 |    3ffa210 |    4000000 |
+    +-----------+------------+------------+------------+------------+------------+
+
+The script relies on symbols in the symbol table to determine the start, end,
+and limit addresses of each bootloader stage.
+
+Memory Tree
+~~~~~~~~~~~
+
+A hierarchical view of the memory layout can be produced by passing the option
+``-t`` or ``--tree`` to the tool. This gives the start, end, and size of each
+module, their ELF segments as well as sections.
+
+.. code:: shell
+
+    $ poetry run memory -t
+    build-path: build/fvp/release
+    name                                       start        end       size
+    bl1                                            0    400c000    400c000
+    ├── 00                                         0       5de0       5de0
+    │   ├── .text                                  0       5000       5000
+    │   └── .rodata                             5000       5de0        de0
+    ├── 01                                   4034000    40344c5        4c5
+    │   └── .data                            4034000    40344c5        4c5
+    ├── 02                                   4034500    4034a00        500
+    │   └── .stacks                          4034500    4034a00        500
+    ├── 04                                   4034a00    4035600        c00
+    │   └── .bss                             4034a00    4035600        c00
+    └── 03                                   4036000    403b000       5000
+        └── .xlat_table                      4036000    403b000       5000
+    bl2                                      4021000    4034000      13000
+    ├── 00                                   4021000    4027000       6000
+    │   ├── .text                            4021000    4026000       5000
+    │   └── .rodata                          4026000    4027000       1000
+    └── 01                                   4027000    402e000       7000
+        ├── .data                            4027000    4027809        809
+        ├── .stacks                          4027840    4027e40        600
+        ├── .bss                             4028000    4028800        800
+        └── .xlat_table                      4029000    402e000       5000
+    bl2u                                     4021000    4034000      13000
+    ├── 00                                   4021000    4025000       4000
+    │   ├── .text                            4021000    4024000       3000
+    │   └── .rodata                          4024000    4025000       1000
+    └── 01                                   4025000    402b000       6000
+        ├── .data                            4025000    4025065         65
+        ├── .stacks                          4025080    4025480        400
+        ├── .bss                             4025600    4025c00        600
+        └── .xlat_table                      4026000    402b000       5000
+    bl31                                     4003000    4040000      3d000
+    ├── 02                                  ffe00000   ffe03000       3000
+    │   └── .el3_tzc_dram                   ffe00000   ffe03000       3000
+    ├── 00                                   4003000    4010000       d000
+    │   └── .text                            4003000    4010000       d000
+    └── 01                                   4010000    4021000      11000
+        ├── .rodata                          4010000    4012000       2000
+        ├── .data                            4012000    401219d        19d
+        ├── .stacks                          40121c0    40161c0       4000
+        ├── .bss                             4016200    4018c00       2a00
+        ├── .xlat_table                      4019000    4020000       7000
+        └── .coherent_ram                    4020000    4021000       1000
+
+
+The granularity of this view can be modified with the ``--depth`` option. For
+instance, if you only require the tree up to the level showing segment data,
+you can specify the depth with:
+
+.. code::
+
+    $ poetry run memory -t --depth 2
+    build-path: build/fvp/release
+    name                          start        end       size
+    bl1                               0    400c000    400c000
+    ├── 00                            0       5df0       5df0
+    ├── 01                      4034000    40344c5        4c5
+    ├── 02                      4034500    4034a00        500
+    ├── 04                      4034a00    4035600        c00
+    └── 03                      4036000    403b000       5000
+    bl2                         4021000    4034000      13000
+    ├── 00                      4021000    4027000       6000
+    └── 01                      4027000    402e000       7000
+    bl2u                        4021000    4034000      13000
+    ├── 00                      4021000    4025000       4000
+    └── 01                      4025000    402b000       6000
+    bl31                        4003000    4040000      3d000
+    ├── 02                     ffe00000   ffe03000       3000
+    ├── 00                      4003000    4010000       d000
+    └── 01                      4010000    4021000      11000
+
 --------------
 
 *Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index 7f0735d..a4786bb 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -217,7 +217,7 @@
 
 			/* SPI IDs range check */
 			if (!(spi_id_min >= GIC600_SPI_ID_MIN) ||
-			    !(spi_id_max < GIC600_SPI_ID_MAX) ||
+			    !(spi_id_max <= GIC600_SPI_ID_MAX) ||
 			    !(spi_id_min <= spi_id_max) ||
 			    !((spi_id_max - spi_id_min + 1) % 32 == 0)) {
 				ERROR("Invalid SPI IDs {%u, %u} passed for "
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
index f6028ad..fd1cb57 100644
--- a/drivers/arm/gic/v3/gic600_multichip_private.h
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,7 +39,7 @@
 
 /* SPI interrupt id minimum and maximum range */
 #define GIC600_SPI_ID_MIN		32
-#define GIC600_SPI_ID_MAX		960
+#define GIC600_SPI_ID_MAX		991
 
 #define GIC700_SPI_ID_MIN		32
 #define GIC700_SPI_ID_MAX		991
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 00bd7a1..b27debf 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -223,13 +223,16 @@
 		current_prop = &interrupt_props[i];
 
 		unsigned int intr_num = current_prop->intr_num;
-		uintptr_t multichip_gicd_base = gicv3_get_multichip_base(intr_num, gicd_base);
+		uintptr_t multichip_gicd_base;
 
 		/* Skip SGI, (E)PPI and LPI interrupts */
 		if (!IS_SPI(intr_num)) {
 			continue;
 		}
 
+		multichip_gicd_base =
+			gicv3_get_multichip_base(intr_num, gicd_base);
+
 		/* Configure this interrupt as a secure interrupt */
 		gicd_clr_igroupr(multichip_gicd_base, intr_num);
 
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 6d6364f..230cec9 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -172,17 +172,20 @@
 	int rc;
 
 	/*
-	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE
-	 * and consume all bytes.
+	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
+	 * it is allowed.  This is necessary to support multiple hash
+	 * algorithms.
 	 */
 	p = (unsigned char *)digest_info_ptr;
 	end = p + digest_info_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0 || ((size_t)(end - p) != len)) {
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
 	}
 
+	end = p + len;
+
 	/* Get the hash algorithm */
 	rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
 	if (rc != 0) {
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index fb5b036..8bde5bb 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -135,8 +135,38 @@
 		if ((oid != NULL) &&
 		    ((size_t)oid_len == strlen(oid_str)) &&
 		    (strcmp(oid, oid_str) == 0)) {
+			/* Extension must be ASN.1 DER */
+			if (len < 2) {
+				/* too short */
+				return IMG_PARSER_ERR_FORMAT;
+			}
+
+			if ((p[0] & 0x1F) == 0x1F) {
+				/* multi-byte ASN.1 DER tag, not allowed */
+				return IMG_PARSER_ERR_FORMAT;
+			}
+
+			if ((p[0] & 0xDF) == 0) {
+				/* UNIVERSAL 0 tag, not allowed */
+				return IMG_PARSER_ERR_FORMAT;
+			}
+
 			*ext = (void *)p;
 			*ext_len = (unsigned int)len;
+
+			/* Advance past the tag byte */
+			p++;
+
+			if (mbedtls_asn1_get_len(&p, end_ext_data, &len)) {
+				/* not valid DER */
+				return IMG_PARSER_ERR_FORMAT;
+			}
+
+			if (p + len != end_ext_data) {
+				/* junk after ASN.1 object */
+				return IMG_PARSER_ERR_FORMAT;
+			}
+
 			return IMG_PARSER_OK;
 		}
 
diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c
index 542b614..744383a 100644
--- a/drivers/mtd/nand/spi_nand.c
+++ b/drivers/mtd/nand/spi_nand.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022,  STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2023,  STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,6 @@
 
 #define SPI_NAND_MAX_ID_LEN		4U
 #define DELAY_US_400MS			400000U
-#define MACRONIX_ID			0xC2U
 
 static struct spinand_device spinand_dev;
 
@@ -91,7 +90,7 @@
 {
 	bool enable = false;
 
-	if (manufacturer_id != MACRONIX_ID) {
+	if ((spinand_dev.flags & SPI_NAND_HAS_QE_BIT) == 0U) {
 		return 0;
 	}
 
diff --git a/drivers/st/clk/clk-stm32mp13.c b/drivers/st/clk/clk-stm32mp13.c
index db427ad..01d1764 100644
--- a/drivers/st/clk/clk-stm32mp13.c
+++ b/drivers/st/clk/clk-stm32mp13.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -1216,7 +1216,7 @@
 	 * => deactivate CKPER only after switching clock
 	 */
 	if (ckper_disabled) {
-		ret = stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED & CMD_MASK);
+		ret = stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED);
 		if (ret != 0) {
 			return ret;
 		}
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index e3e0e67..d64a6cd 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -234,11 +234,16 @@
 	cmp	r0, #0
 	ASM_ASSERT(ne)
 #endif /* ENABLE_ASSERTIONS */
+	/* Skip flush if UART is not enabled */
+	ldr	r1, [r0, #USART_CR1]
+	ands	r1, r1, #USART_CR1_UE
+	beq	1f
 	/* Check Transmit Data Register Empty */
 txe_loop_3:
 	ldr	r1, [r0, #USART_ISR]
 	tst	r1, #USART_ISR_TXE
 	beq	txe_loop_3
+1:
 	bx	lr
 endfunc console_stm32_core_flush
 
diff --git a/fdts/stm32mp13-bl2.dtsi b/fdts/stm32mp13-bl2.dtsi
index 06db796..2b23daf 100644
--- a/fdts/stm32mp13-bl2.dtsi
+++ b/fdts/stm32mp13-bl2.dtsi
@@ -3,6 +3,15 @@
  * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  */
 
+/omit-if-no-ref/ &i2c4_pins_a;
+/omit-if-no-ref/ &sdmmc1_b4_pins_a;
+/omit-if-no-ref/ &sdmmc1_clk_pins_a;
+/omit-if-no-ref/ &sdmmc2_b4_pins_a;
+/omit-if-no-ref/ &sdmmc2_clk_pins_a;
+/omit-if-no-ref/ &uart4_pins_a;
+/omit-if-no-ref/ &uart8_pins_a;
+/omit-if-no-ref/ &usart1_pins_a;
+
 / {
 	aliases {
 #if !STM32MP_EMMC && !STM32MP_SDMMC
diff --git a/fdts/stm32mp13-pinctrl.dtsi b/fdts/stm32mp13-pinctrl.dtsi
index 0129372..323d5ba 100644
--- a/fdts/stm32mp13-pinctrl.dtsi
+++ b/fdts/stm32mp13-pinctrl.dtsi
@@ -6,7 +6,7 @@
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
 
 &pinctrl {
-	/omit-if-no-ref/ i2c4_pins_a: i2c4-0 {
+	i2c4_pins_a: i2c4-0 {
 		pins {
 			pinmux = <STM32_PINMUX('E', 15, AF6)>, /* I2C4_SCL */
 				 <STM32_PINMUX('B', 9, AF6)>; /* I2C4_SDA */
@@ -16,7 +16,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
 		pins {
 			pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
 				 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
@@ -29,7 +29,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc1_clk_pins_a: sdmmc1-clk-0 {
+	sdmmc1_clk_pins_a: sdmmc1-clk-0 {
 		pins {
 			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
 			slew-rate = <1>;
@@ -38,7 +38,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+	sdmmc2_b4_pins_a: sdmmc2-b4-0 {
 		pins {
 			pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
 				 <STM32_PINMUX('B', 15, AF10)>, /* SDMMC2_D1 */
@@ -51,7 +51,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_clk_pins_a: sdmmc2-clk-0 {
+	sdmmc2_clk_pins_a: sdmmc2-clk-0 {
 		pins {
 			pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC2_CK */
 			slew-rate = <1>;
@@ -60,7 +60,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart4_pins_a: uart4-0 {
+	uart4_pins_a: uart4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 6, AF8)>; /* UART4_TX */
 			bias-disable;
@@ -73,7 +73,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart1_pins_a: usart1-0 {
+	usart1_pins_a: usart1-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('C', 0, AF7)>, /* USART1_TX */
 				 <STM32_PINMUX('C', 2, AF7)>; /* USART1_RTS */
@@ -88,7 +88,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart8_pins_a: uart8-0 {
+	uart8_pins_a: uart8-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */
 			bias-disable;
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index 543afa5..2be39af 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -416,7 +416,7 @@
 		};
 
 		bsec: efuse@5c005000 {
-			compatible = "st,stm32mp15-bsec";
+			compatible = "st,stm32mp13-bsec";
 			reg = <0x5c005000 0x400>;
 			#address-cells = <1>;
 			#size-cells = <1>;
diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi
index 18a4ba9..53aeec5 100644
--- a/fdts/stm32mp15-bl2.dtsi
+++ b/fdts/stm32mp15-bl2.dtsi
@@ -3,8 +3,37 @@
  * Copyright (c) 2020-2023, STMicroelectronics - All Rights Reserved
  */
 
+/omit-if-no-ref/ &fmc_pins_a;
+/omit-if-no-ref/ &i2c2_pins_a;
+/omit-if-no-ref/ &i2c4_pins_a;
 /omit-if-no-ref/ &i2c6;
+/omit-if-no-ref/ &qspi_bk1_pins_a;
+/omit-if-no-ref/ &qspi_bk2_pins_a;
+/omit-if-no-ref/ &qspi_clk_pins_a;
+/omit-if-no-ref/ &sdmmc1_b4_pins_a;
+/omit-if-no-ref/ &sdmmc1_dir_pins_a;
+/omit-if-no-ref/ &sdmmc1_dir_pins_b;
+/omit-if-no-ref/ &sdmmc2_b4_pins_a;
+/omit-if-no-ref/ &sdmmc2_b4_pins_b;
+/omit-if-no-ref/ &sdmmc2_d47_pins_a;
+/omit-if-no-ref/ &sdmmc2_d47_pins_b;
+/omit-if-no-ref/ &sdmmc2_d47_pins_c;
+/omit-if-no-ref/ &sdmmc2_d47_pins_d;
 /omit-if-no-ref/ &spi6;
+/omit-if-no-ref/ &uart4_pins_a;
+/omit-if-no-ref/ &uart4_pins_b;
+/omit-if-no-ref/ &uart7_pins_a;
+/omit-if-no-ref/ &uart7_pins_b;
+/omit-if-no-ref/ &uart7_pins_c;
+/omit-if-no-ref/ &uart8_pins_a;
+/omit-if-no-ref/ &usart2_pins_a;
+/omit-if-no-ref/ &usart2_pins_b;
+/omit-if-no-ref/ &usart2_pins_c;
+/omit-if-no-ref/ &usart3_pins_a;
+/omit-if-no-ref/ &usart3_pins_b;
+/omit-if-no-ref/ &usart3_pins_c;
+/omit-if-no-ref/ &usbotg_fs_dp_dm_pins_a;
+/omit-if-no-ref/ &usbotg_hs_pins_a;
 
 / {
 #if !STM32MP_EMMC && !STM32MP_SDMMC
diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi
index 6882224..7b63f1b 100644
--- a/fdts/stm32mp15-bl32.dtsi
+++ b/fdts/stm32mp15-bl32.dtsi
@@ -3,8 +3,37 @@
  * Copyright (c) 2020-2023, STMicroelectronics - All Rights Reserved
  */
 
+/omit-if-no-ref/ &fmc_pins_a;
+/omit-if-no-ref/ &i2c2_pins_a;
+/omit-if-no-ref/ &i2c4_pins_a;
 /omit-if-no-ref/ &i2c6;
+/omit-if-no-ref/ &qspi_bk1_pins_a;
+/omit-if-no-ref/ &qspi_bk2_pins_a;
+/omit-if-no-ref/ &qspi_clk_pins_a;
+/omit-if-no-ref/ &sdmmc1_b4_pins_a;
+/omit-if-no-ref/ &sdmmc1_dir_pins_a;
+/omit-if-no-ref/ &sdmmc1_dir_pins_b;
+/omit-if-no-ref/ &sdmmc2_b4_pins_a;
+/omit-if-no-ref/ &sdmmc2_b4_pins_b;
+/omit-if-no-ref/ &sdmmc2_d47_pins_a;
+/omit-if-no-ref/ &sdmmc2_d47_pins_b;
+/omit-if-no-ref/ &sdmmc2_d47_pins_c;
+/omit-if-no-ref/ &sdmmc2_d47_pins_d;
 /omit-if-no-ref/ &spi6;
+/omit-if-no-ref/ &uart4_pins_a;
+/omit-if-no-ref/ &uart4_pins_b;
+/omit-if-no-ref/ &uart7_pins_a;
+/omit-if-no-ref/ &uart7_pins_b;
+/omit-if-no-ref/ &uart7_pins_c;
+/omit-if-no-ref/ &uart8_pins_a;
+/omit-if-no-ref/ &usart2_pins_a;
+/omit-if-no-ref/ &usart2_pins_b;
+/omit-if-no-ref/ &usart2_pins_c;
+/omit-if-no-ref/ &usart3_pins_a;
+/omit-if-no-ref/ &usart3_pins_b;
+/omit-if-no-ref/ &usart3_pins_c;
+/omit-if-no-ref/ &usbotg_fs_dp_dm_pins_a;
+/omit-if-no-ref/ &usbotg_hs_pins_a;
 
 / {
 	aliases {
diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi
index 8dc00fe..a1be447 100644
--- a/fdts/stm32mp15-pinctrl.dtsi
+++ b/fdts/stm32mp15-pinctrl.dtsi
@@ -6,7 +6,7 @@
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
 
 &pinctrl {
-	/omit-if-no-ref/ fmc_pins_a: fmc-0 {
+	fmc_pins_a: fmc-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
 				 <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
@@ -31,7 +31,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ i2c2_pins_a: i2c2-0 {
+	i2c2_pins_a: i2c2-0 {
 		pins {
 			pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
 				 <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
@@ -41,7 +41,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ qspi_clk_pins_a: qspi-clk-0 {
+	qspi_clk_pins_a: qspi-clk-0 {
 		pins {
 			pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
 			bias-disable;
@@ -50,7 +50,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ qspi_bk1_pins_a: qspi-bk1-0 {
+	qspi_bk1_pins_a: qspi-bk1-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
 				 <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
@@ -68,7 +68,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ qspi_bk2_pins_a: qspi-bk2-0 {
+	qspi_bk2_pins_a: qspi-bk2-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
 				 <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
@@ -86,7 +86,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
 				 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
@@ -105,7 +105,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc1_dir_pins_a: sdmmc1-dir-0 {
+	sdmmc1_dir_pins_a: sdmmc1-dir-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
 				 <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
@@ -120,7 +120,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc1_dir_pins_b: sdmmc1-dir-1 {
+	sdmmc1_dir_pins_b: sdmmc1-dir-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
 				 <STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
@@ -135,7 +135,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+	sdmmc2_b4_pins_a: sdmmc2-b4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
 				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
@@ -154,7 +154,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_b4_pins_b: sdmmc2-b4-1 {
+	sdmmc2_b4_pins_b: sdmmc2-b4-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
 				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
@@ -173,7 +173,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+	sdmmc2_d47_pins_a: sdmmc2-d47-0 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
 				 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
@@ -185,7 +185,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_d47_pins_b: sdmmc2-d47-1 {
+	sdmmc2_d47_pins_b: sdmmc2-d47-1 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 8, AF9)>,  /* SDMMC2_D4 */
 				 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
@@ -197,7 +197,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_d47_pins_c: sdmmc2-d47-2 {
+	sdmmc2_d47_pins_c: sdmmc2-d47-2 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
 				 <STM32_PINMUX('A', 15, AF9)>, /* SDMMC2_D5 */
@@ -209,7 +209,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ sdmmc2_d47_pins_d: sdmmc2-d47-3 {
+	sdmmc2_d47_pins_d: sdmmc2-d47-3 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
 				 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
@@ -218,7 +218,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart4_pins_a: uart4-0 {
+	uart4_pins_a: uart4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
 			bias-disable;
@@ -231,7 +231,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart4_pins_b: uart4-1 {
+	uart4_pins_b: uart4-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
 			bias-disable;
@@ -244,7 +244,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart7_pins_a: uart7-0 {
+	uart7_pins_a: uart7-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART7_TX */
 			bias-disable;
@@ -259,7 +259,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart7_pins_b: uart7-1 {
+	uart7_pins_b: uart7-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('F', 7, AF7)>; /* UART7_TX */
 			bias-disable;
@@ -272,7 +272,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart7_pins_c: uart7-2 {
+	uart7_pins_c: uart7-2 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART7_TX */
 			bias-disable;
@@ -285,7 +285,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ uart8_pins_a: uart8-0 {
+	uart8_pins_a: uart8-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */
 			bias-disable;
@@ -298,7 +298,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart2_pins_a: usart2-0 {
+	usart2_pins_a: usart2-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
 				 <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */
@@ -313,7 +313,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart2_pins_b: usart2-1 {
+	usart2_pins_b: usart2-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
 				 <STM32_PINMUX('A', 1, AF7)>; /* USART2_RTS */
@@ -328,7 +328,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart2_pins_c: usart2-2 {
+	usart2_pins_c: usart2-2 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 5, AF7)>, /* USART2_TX */
 				 <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */
@@ -343,7 +343,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart3_pins_a: usart3-0 {
+	usart3_pins_a: usart3-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */
 			bias-disable;
@@ -356,7 +356,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart3_pins_b: usart3-1 {
+	usart3_pins_b: usart3-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
 				 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
@@ -371,7 +371,7 @@
 		};
 	};
 
-	/omit-if-no-ref/ usart3_pins_c: usart3-2 {
+	usart3_pins_c: usart3-2 {
 		pins1 {
 			pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
 				 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
@@ -386,13 +386,13 @@
 		};
 	};
 
-	/omit-if-no-ref/ usbotg_hs_pins_a: usbotg-hs-0 {
+	usbotg_hs_pins_a: usbotg-hs-0 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
 		};
 	};
 
-	/omit-if-no-ref/ usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 {
+	usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* OTG_FS_DM */
 				 <STM32_PINMUX('A', 12, ANALOG)>; /* OTG_FS_DP */
@@ -401,7 +401,7 @@
 };
 
 &pinctrl_z {
-	/omit-if-no-ref/ i2c4_pins_a: i2c4-0 {
+	i2c4_pins_a: i2c4-0 {
 		pins {
 			pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
 				 <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 227f058..c8a6334 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -119,6 +119,10 @@
 #define ID_DFR1_MTPMU_MASK	U(0xf)
 #define ID_DFR1_MTPMU_SUPPORTED	U(1)
 
+/* ID_MMFR3 definitions */
+#define ID_MMFR3_PAN_SHIFT	U(16)
+#define ID_MMFR3_PAN_MASK	U(0xf)
+
 /* ID_MMFR4 definitions */
 #define ID_MMFR4_CNP_SHIFT	U(12)
 #define ID_MMFR4_CNP_LENGTH	U(4)
@@ -533,6 +537,7 @@
 #define DCISW		p15, 0, c7, c6, 2
 #define CTR		p15, 0, c0, c0, 1
 #define CNTFRQ		p15, 0, c14, c0, 0
+#define ID_MMFR3	p15, 0, c0, c1, 7
 #define ID_MMFR4	p15, 0, c0, c2, 6
 #define ID_DFR0		p15, 0, c0, c1, 2
 #define ID_DFR1		p15, 0, c0, c3, 5
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index 62a512b..99e3fd0 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -110,10 +110,56 @@
 	return read_feat_dit_id_field() != 0U;
 }
 
-static inline bool is_feat_spe_supported(void)
+static inline unsigned int read_feat_pan_id_field(void)
 {
-	/* FEAT_SPE is AArch64 only */
-	return false;
+	return ISOLATE_FIELD(read_id_mmfr3(), ID_MMFR3_PAN);
+}
+
+static inline bool is_feat_pan_supported(void)
+{
+	if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_pan_id_field() != 0U;
 }
 
+/*
+ * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch
+ * code. In fact, EL2 context switching is only needed for AArch64 (since
+ * there is no secure AArch32 EL2), so just disable these features here.
+ */
+static inline bool is_feat_twed_supported(void) { return false; }
+static inline bool is_feat_ecv_supported(void) { return false; }
+static inline bool is_feat_ecv_v2_supported(void) { return false; }
+static inline bool is_feat_csv2_2_supported(void) { return false; }
+static inline bool is_feat_ras_supported(void) { return false; }
+
+/* The following features are supported in AArch64 only. */
+static inline bool is_feat_vhe_supported(void) { return false; }
+static inline bool is_feat_sel2_supported(void) { return false; }
+static inline bool is_feat_fgt_supported(void) { return false; }
+static inline bool is_feat_tcr2_supported(void) { return false; }
+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_mpam_supported(void) { return false; }
+static inline bool is_feat_hcx_supported(void) { return false; }
+static inline bool is_feat_sve_supported(void) { return false; }
+static inline bool is_feat_brbe_supported(void) { return false; }
+static inline bool is_feat_trbe_supported(void) { return false; }
+static inline bool is_feat_nv2_supported(void) { return false; }
+static inline bool is_feat_sme_supported(void) { return false; }
+static inline bool is_feat_sme2_supported(void) { return false; }
+static inline bool is_feat_s2poe_supported(void) { return false; }
+static inline bool is_feat_s1poe_supported(void) { return false; }
+static inline bool is_feat_sxpoe_supported(void) { return false; }
+static inline bool is_feat_s2pie_supported(void) { return false; }
+static inline bool is_feat_s1pie_supported(void) { return false; }
+static inline bool is_feat_sxpie_supported(void) { return false; }
+
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 95d056f..ca5a44b 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -8,6 +8,7 @@
 #ifndef ARCH_HELPERS_H
 #define ARCH_HELPERS_H
 
+#include <assert.h>
 #include <cdefs.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -217,6 +218,7 @@
  ******************************************************************************/
 DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
 DEFINE_COPROCR_READ_FUNC(midr, MIDR)
+DEFINE_COPROCR_READ_FUNC(id_mmfr3, ID_MMFR3)
 DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4)
 DEFINE_COPROCR_READ_FUNC(id_dfr0, ID_DFR0)
 DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
@@ -351,6 +353,17 @@
  */
 DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
 
+/*
+ * RNDR is AArch64 only, so just provide a placeholder here to make the
+ * linker happy.
+ */
+static inline u_register_t read_rndr(void)
+{
+	assert(1);
+
+	return 0;
+}
+
 /* Previously defined accessor functions with incomplete register names  */
 #define dsb()			dsbsy()
 #define dmb()			dmbsy()
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 7d1407a..6091f62 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -25,12 +25,50 @@
 #endif
 
 
-	.macro	func_prologue
+	/*
+	 * Create a stack frame at the start of an assembly function. Will also
+	 * add all necessary call frame information (cfi) directives for a
+	 * pretty stack trace. This is necessary as there is quite a bit of
+	 * flexibility within a stack frame and the stack pointer can move
+	 * around throughout the function. If the debugger isn't told where to
+	 * find things, it gets lost, gives up and displays nothing. So inform
+	 * the debugger of what's where. Anchor the Canonical Frame Address
+	 * (CFA; the thing used to track what's where) to the frame pointer as
+	 * that's not expected to change in the function body and no extra
+	 * bookkeeping will be necessary, allowing free movement of the sp
+	 *
+	 *   _frame_size: requested space for caller to use. Must be a mutliple
+	 *     of 16 for stack pointer alignment
+	 */
+	.macro	func_prologue _frame_size=0
+	.if \_frame_size & 0xf
+	.error "frame_size must have stack pointer alignment (multiple of 16)"
+	.endif
+
+	/* put frame record at top of frame */
 	stp	x29, x30, [sp, #-0x10]!
 	mov	x29,sp
+	.if \_frame_size
+	sub	sp, sp, #\_frame_size
+	.endif
+
+	/* point CFA to start of frame record, i.e. x29 + 0x10 */
+	.cfi_def_cfa	x29,  0x10
+	/* inform it about x29, x30 locations */
+	.cfi_offset	x30, -0x8
+	.cfi_offset	x29, -0x10
 	.endm
 
-	.macro	func_epilogue
+	/*
+	 * Clear stack frame at the end of an assembly function.
+	 *
+	 *   _frame_size: the value passed to func_prologue
+	 */
+	.macro	func_epilogue _frame_size=0
+	/* remove requested space */
+	.if \_frame_size
+	add	sp, sp, #\_frame_size
+	.endif
 	ldp	x29, x30, [sp], #0x10
 	.endm
 
diff --git a/include/drivers/spi_nand.h b/include/drivers/spi_nand.h
index 40e2063..869a0c6 100644
--- a/include/drivers/spi_nand.h
+++ b/include/drivers/spi_nand.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,9 +29,13 @@
 #define SPI_NAND_STATUS_BUSY		BIT(0)
 #define SPI_NAND_STATUS_ECC_UNCOR	BIT(5)
 
+/* Flags for specific configuration */
+#define SPI_NAND_HAS_QE_BIT		BIT(0)
+
 struct spinand_device {
 	struct nand_device *nand_dev;
 	struct spi_mem_op spi_read_cache_op;
+	uint32_t flags;
 	uint8_t cfg_cache; /* Cached value of SPI NAND device register CFG */
 };
 
diff --git a/include/export/lib/utils_def_exp.h b/include/export/lib/utils_def_exp.h
index d4a4a85..2ee5769 100644
--- a/include/export/lib/utils_def_exp.h
+++ b/include/export/lib/utils_def_exp.h
@@ -27,10 +27,14 @@
 #else
 # define  U_(_x)	(_x##U)
 # define   U(_x)	U_(_x)
-# define  UL(_x)	(_x##UL)
-# define ULL(_x)	(_x##ULL)
-# define   L(_x)	(_x##L)
-# define  LL(_x)	(_x##LL)
+# define  UL_(_x)	(_x##UL)
+# define  UL(_x)	UL_(_x)
+# define  ULL_(_x)	(_x##ULL)
+# define  ULL(_x)	ULL_(_x)
+# define  L_(_x)	(_x##L)
+# define  L(_x)	L_(_x)
+# define  LL_(_x)	(_x##LL)
+# define  LL(_x)	LL_(_x)
 
 #endif
 
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 724624c..404b7f9 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -427,6 +427,23 @@
 .endm
 
 /*
+ * Clear a bit in a system register. Can clear multiple bits but is limited by
+ *  the way the BIC instrucion encodes them.
+ *
+ * see sysreg_bit_set for usage
+ */
+.macro sysreg_bit_clear _reg:req, _bit:req
+	mrs	x1, \_reg
+	bic	x1, x1, #\_bit
+	msr	\_reg, x1
+.endm
+
+.macro override_vector_table _table:req
+	adr	x1, \_table
+	msr	vbar_el3, x1
+.endm
+
+/*
  * Apply erratum
  *
  * _cpu:
@@ -497,6 +514,27 @@
 	endfunc check_erratum_\_cpu\()_\_id
 .endm
 
+.macro check_erratum_chosen _cpu:req, _cve:req, _id:req, _chosen:req
+	func check_erratum_\_cpu\()_\_id
+		.if \_chosen
+			mov	x0, #ERRATA_APPLIES
+		.else
+			mov	x0, #ERRATA_MISSING
+		.endif
+		ret
+	endfunc check_erratum_\_cpu\()_\_id
+.endm
+
+/* provide a shorthand for the name format for annoying errata */
+.macro check_erratum_custom_start _cpu:req, _cve:req, _id:req
+	func check_erratum_\_cpu\()_\_id
+.endm
+
+.macro check_erratum_custom_end _cpu:req, _cve:req, _id:req
+	endfunc check_erratum_\_cpu\()_\_id
+.endm
+
+
 /*******************************************************************************
  * CPU reset function wrapper
  ******************************************************************************/
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index f8f9555..b280435 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -64,6 +64,10 @@
 #define CVE(year, id)		year, id
 #define NO_ISB			1
 #define NO_ASSERT		0
+#define NO_APPLY_AT_RESET	0
+#define APPLY_AT_RESET		1
+/* useful for errata that end up always being worked around */
+#define ERRATUM_ALWAYS_CHOSEN	1
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 9894483..7ddeed9 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -5,6 +5,7 @@
  */
 /*
  * Portions copyright (c) 2018-2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2023, Intel Corporation. All rights reserved.
  * All rights reserved.
  */
 
@@ -14,6 +15,7 @@
 #include <stddef.h>
 
 void *memcpy(void *dst, const void *src, size_t len);
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize);
 void *memmove(void *dst, const void *src, size_t len);
 int memcmp(const void *s1, const void *s2, size_t len);
 int strcmp(const char *s1, const char *s2);
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 4d7e58e..01dc3cb 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -319,13 +319,13 @@
 	int (*pwr_domain_on)(u_register_t mpidr);
 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
 	int (*pwr_domain_off_early)(const psci_power_state_t *target_state);
+#if PSCI_OS_INIT_MODE
+	int (*pwr_domain_validate_suspend)(
+				const psci_power_state_t *target_state);
+#endif
 	void (*pwr_domain_suspend_pwrdown_early)(
 				const psci_power_state_t *target_state);
-#if PSCI_OS_INIT_MODE
-	int (*pwr_domain_suspend)(const psci_power_state_t *target_state);
-#else
 	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
-#endif
 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
 	void (*pwr_domain_on_finish_late)(
 				const psci_power_state_t *target_state);
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index 63637d5..fb2b3a2 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -20,7 +20,7 @@
 						SMCCC_VERSION_MINOR_SHIFT))
 
 #define SMCCC_MAJOR_VERSION U(1)
-#define SMCCC_MINOR_VERSION U(2)
+#define SMCCC_MINOR_VERSION U(4)
 
 /*******************************************************************************
  * Bit definitions inside the function id as per the SMC calling convention
diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h
index 5ce33ed..dccd362 100644
--- a/include/services/el3_spmc_logical_sp.h
+++ b/include/services/el3_spmc_logical_sp.h
@@ -49,8 +49,7 @@
  * Function & variable prototypes.
  ******************************************************************************/
 int el3_sp_desc_validate(void);
-uintptr_t handle_el3_sp(uint32_t smc_fid, void *cookie, void *handle,
-						unsigned int flags);
+
 IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_START__,	EL3_LP_DESCS_START);
 IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_END__,	EL3_LP_DESCS_END);
 
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index a37ba81..4e9bdfc 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -34,38 +34,51 @@
 #define CVE_FORMAT	"%s: %s: CPU workaround for CVE %u_%u was %s\n"
 #define ERRATUM_FORMAT	"%s: %s: CPU workaround for erratum %u was %s\n"
 
-#define PRINT_STATUS_DISPATCH(status, ...)					\
-	do {									\
-		assert(status <= ERRATA_MISSING);				\
-		switch (status) {						\
-		case ERRATA_NOT_APPLIES:					\
-			VERBOSE(__VA_ARGS__, "not applied");			\
-			break;							\
-		case ERRATA_APPLIES:						\
-			INFO(__VA_ARGS__, "applied");				\
-			break;							\
-		case ERRATA_MISSING:						\
-			WARN(__VA_ARGS__, "missing!");				\
-			break;							\
-		}								\
-	} while (0)
 
+static __unused void print_status(int status, char *cpu_str, uint16_t cve, uint32_t id)
+{
+	if (status == ERRATA_MISSING) {
+		if (cve) {
+			WARN(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "missing!");
+		} else {
+			WARN(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "missing!");
+		}
+	} else if (status == ERRATA_APPLIES) {
+		if (cve) {
+			INFO(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "applied");
+		}  else {
+			INFO(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "applied");
+		}
+	} else {
+		if (cve) {
+			VERBOSE(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "not applied");
+		}  else {
+			VERBOSE(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "not applied");
+		}
+	}
+}
 
 #if !REPORT_ERRATA
 void print_errata_status(void) {}
 #else /* !REPORT_ERRATA */
-/* New errata status message printer */
+/*
+ * New errata status message printer
+ * The order checking function is hidden behind the FEATURE_DETECTION flag to
+ * save space. This functionality is only useful on development and platform
+ * bringup builds, when FEATURE_DETECTION should be used anyway
+ */
 void __unused generic_errata_report(void)
 {
 	struct cpu_ops *cpu_ops = get_cpu_ops_ptr();
 	struct erratum_entry *entry = cpu_ops->errata_list_start;
 	struct erratum_entry *end = cpu_ops->errata_list_end;
 	long rev_var = cpu_get_rev_var();
+#if FEATURE_DETECTION
 	uint32_t last_erratum_id = 0;
 	uint16_t last_cve_yr = 0;
 	bool check_cve = false;
-	/* unused because assert goes away on release */
-	bool failed __unused = false;
+	bool failed = false;
+#endif /* FEATURE_DETECTION */
 
 	for (; entry != end; entry += 1) {
 		uint64_t status = entry->check_func(rev_var);
@@ -81,10 +94,10 @@
 			status = ERRATA_MISSING;
 		}
 
-		if (entry->cve) {
-			PRINT_STATUS_DISPATCH(status, CVE_FORMAT, BL_STRING,
-				cpu_ops->cpu_str, entry->cve, entry->id);
+		print_status(status, cpu_ops->cpu_str, entry->cve, entry->id);
 
+#if FEATURE_DETECTION
+		if (entry->cve) {
 			if (last_cve_yr > entry->cve ||
 			   (last_cve_yr == entry->cve && last_erratum_id >= entry->id)) {
 				ERROR("CVE %u_%u was out of order!\n",
@@ -94,9 +107,6 @@
 			check_cve = true;
 			last_cve_yr = entry->cve;
 		} else {
-			PRINT_STATUS_DISPATCH(status, ERRATUM_FORMAT, BL_STRING,
-				cpu_ops->cpu_str, entry->id);
-
 			if (last_erratum_id >= entry->id || check_cve) {
 				ERROR("Erratum %u was out of order!\n",
 				      entry->id);
@@ -104,13 +114,16 @@
 			}
 		}
 		last_erratum_id = entry->id;
+#endif /* FEATURE_DETECTION */
 	}
 
+#if FEATURE_DETECTION
 	/*
 	 * enforce errata and CVEs are in ascending order and that CVEs are
 	 * after errata
 	 */
 	assert(!failed);
+#endif /* FEATURE_DETECTION */
 }
 
 /*
diff --git a/lib/extensions/pauth/pauth_helpers.S b/lib/extensions/pauth/pauth_helpers.S
index d483c7df..fb5fa97 100644
--- a/lib/extensions/pauth/pauth_helpers.S
+++ b/lib/extensions/pauth/pauth_helpers.S
@@ -45,7 +45,7 @@
 endfunc pauth_init_enable_el1
 
 /* -------------------------------------------------------------
- * Disable pointer authentication in EL3
+ * Disable pointer authentication in EL1
  * -------------------------------------------------------------
  */
 func pauth_disable_el1
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 13081b0..58956d6 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -83,7 +83,7 @@
 
 	/*
 	 * In case of BL1, fw_config dtb information is already
-	 * populated in global dtb_infos array by 'set_fw_config_info'
+	 * populated in global dtb_infos array by 'set_config_info'
 	 * function, Below check is present to avoid re-population of
 	 * fw_config information.
 	 *
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index b75d09c..5eb8b52 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -11,6 +11,7 @@
 			memchr.c			\
 			memcmp.c			\
 			memcpy.c			\
+			memcpy_s.c			\
 			memmove.c			\
 			memrchr.c			\
 			memset.c			\
diff --git a/lib/libc/memcpy_s.c b/lib/libc/memcpy_s.c
new file mode 100644
index 0000000..01e88b0
--- /dev/null
+++ b/lib/libc/memcpy_s.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize)
+{
+	unsigned int *s = (unsigned int *)src;
+	unsigned int *d = (unsigned int *)dst;
+
+	/*
+	 * Check source and destination size is NULL
+	 */
+	if ((dst == NULL) || (src == NULL)) {
+		return -ENOMEM;
+	}
+
+	/*
+	 * Check source and destination size validity
+	 */
+	if ((dsize == 0) || (ssize == 0)) {
+		return -ERANGE;
+	}
+
+	/*
+	 * Check both source and destination size range
+	 */
+	if ((ssize > dsize) || (dsize > ssize)) {
+		return -EINVAL;
+	}
+
+	/*
+	 * Check both source and destination address overlapping
+	 * When (s > d < s + ssize)
+	 * Or (d > s < d + dsize)
+	 */
+
+	if (d > s) {
+		if ((d) < (s + ssize)) {
+			return -EOPNOTSUPP;
+		}
+	}
+
+	if (s > d) {
+		if ((s) < (d + dsize)) {
+			return -EOPNOTSUPP;
+		}
+	}
+
+	/*
+	 * Start copy process when there is no error
+	 */
+	while (ssize--) {
+		d[ssize] = s[ssize];
+	}
+
+	return 0;
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index c893476..bfc09cc 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -451,8 +451,8 @@
  * enter. This function will be called after coordination of requested power
  * states has been done for each power level.
  *****************************************************************************/
-static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
-					const psci_power_state_t *target_state)
+void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+				      const psci_power_state_t *target_state)
 {
 	unsigned int parent_idx, lvl;
 	const plat_local_state_t *pd_state = target_state->pwr_domain_state;
@@ -474,7 +474,6 @@
 	}
 }
 
-
 /*******************************************************************************
  * PSCI helper function to get the parent nodes corresponding to a cpu_index.
  ******************************************************************************/
@@ -595,9 +594,6 @@
 		state_info->pwr_domain_state[lvl] = PSCI_LOCAL_STATE_RUN;
 
 	}
-
-	/* Update the target state in the power domain nodes */
-	psci_set_target_local_pwr_states(end_pwrlvl, state_info);
 }
 
 #if PSCI_OS_INIT_MODE
@@ -684,9 +680,6 @@
 		return rc;
 	}
 
-	/* Update the target state in the power domain nodes */
-	psci_set_target_local_pwr_states(end_pwrlvl, state_info);
-
 	return rc;
 }
 #endif
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 9f36ac7..f83753f 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -104,6 +104,9 @@
 	 */
 	psci_do_state_coordination(end_pwrlvl, &state_info);
 
+	/* Update the target state in the power domain nodes */
+	psci_set_target_local_pwr_states(end_pwrlvl, &state_info);
+
 #if ENABLE_PSCI_STAT
 	/* Update the last cpu for each level till end_pwrlvl */
 	psci_stats_update_pwr_down(end_pwrlvl, &state_info);
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index b9987fe..04f93bd 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -298,6 +298,8 @@
 #endif
 void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
 				      psci_power_state_t *target_state);
+void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+				      const psci_power_state_t *target_state);
 int psci_validate_entry_point(entry_point_info_t *ep,
 			uintptr_t entrypoint, u_register_t context_id);
 void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 861b875..d93e60d 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -219,6 +219,19 @@
 	}
 #endif
 
+#if PSCI_OS_INIT_MODE
+	if (psci_plat_pm_ops->pwr_domain_validate_suspend != NULL) {
+		rc = psci_plat_pm_ops->pwr_domain_validate_suspend(state_info);
+		if (rc != PSCI_E_SUCCESS) {
+			skip_wfi = true;
+			goto exit;
+		}
+	}
+#endif
+
+	/* Update the target state in the power domain nodes */
+	psci_set_target_local_pwr_states(end_pwrlvl, state_info);
+
 #if ENABLE_PSCI_STAT
 	/* Update the last cpu for each level till end_pwrlvl */
 	psci_stats_update_pwr_down(end_pwrlvl, state_info);
@@ -234,15 +247,7 @@
 	 * program the power controller etc.
 	 */
 
-#if PSCI_OS_INIT_MODE
-	rc = psci_plat_pm_ops->pwr_domain_suspend(state_info);
-	if (rc != PSCI_E_SUCCESS) {
-		skip_wfi = true;
-		goto exit;
-	}
-#else
 	psci_plat_pm_ops->pwr_domain_suspend(state_info);
-#endif
 
 #if ENABLE_PSCI_STAT
 	plat_psci_stat_accounting_start(state_info);
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index a3289b6..b8c97f8 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -228,11 +228,7 @@
  * FVP handler called when a power domain is about to be suspended. The
  * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
-#if PSCI_OS_INIT_MODE
-static int fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
-#else
 static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
-#endif
 {
 	unsigned long mpidr;
 
@@ -242,11 +238,7 @@
 	 */
 	if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
 					ARM_LOCAL_STATE_RET)
-#if PSCI_OS_INIT_MODE
-		return PSCI_E_SUCCESS;
-#else
 		return;
-#endif
 
 	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
 					ARM_LOCAL_STATE_OFF);
@@ -279,11 +271,7 @@
 	/* Program the power controller to power off this cpu. */
 	fvp_pwrc_write_ppoffr(read_mpidr_el1());
 
-#if PSCI_OS_INIT_MODE
-	return PSCI_E_SUCCESS;
-#else
 	return;
-#endif
 }
 
 /*******************************************************************************
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index 8e59529..4c3201e 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -36,35 +36,52 @@
 }
 
 /*
- * Store a new non-volatile counter value.
- *
- * On some FVP versions, the non-volatile counters are read-only so this
- * function will always fail.
+ * Return the non-volatile counter address stored in the platform. The cookie
+ * will contain the OID of the counter in the certificate.
  *
  * Return: 0 = success, Otherwise = error
  */
-int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+static int plat_get_nv_ctr_addr(void *cookie, uintptr_t *nv_ctr_addr)
 {
-	const char *oid;
-	uintptr_t nv_ctr_addr;
+	const char *oid = (const char *)cookie;
 
-	assert(cookie != NULL);
-
-	oid = (const char *)cookie;
 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+		*nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
 						TRUSTED_NV_CTR_ID);
 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+		*nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
 						NON_TRUSTED_NV_CTR_ID);
 	} else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) {
 		/* FVP does not support the CCA NV Counter so use the Trusted NV */
-		nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+		*nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
 						TRUSTED_NV_CTR_ID);
 	} else {
 		return 1;
 	}
 
+	return 0;
+}
+
+/*
+ * Store a new non-volatile counter value.
+ *
+ * On some FVP versions, the non-volatile counters are read-only so this
+ * function will always fail.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+	uintptr_t nv_ctr_addr;
+	int rc;
+
+	assert(cookie != NULL);
+
+	rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr);
+	if (rc != 0) {
+		return rc;
+	}
+
 	mmio_write_32(nv_ctr_addr, nv_ctr);
 
 	/*
@@ -82,28 +99,18 @@
  */
 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
 {
-	const char *oid;
-	uint32_t *nv_ctr_addr;
+	uintptr_t nv_ctr_addr;
+	int rc;
 
 	assert(cookie != NULL);
 	assert(nv_ctr != NULL);
 
-	oid = (const char *)cookie;
-	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
-							TRUSTED_NV_CTR_ID);
-	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
-							NON_TRUSTED_NV_CTR_ID);
-	} else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) {
-		/* FVP does not support the CCA NV Counter so use the Trusted NV */
-		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
-							TRUSTED_NV_CTR_ID);
-	} else {
-		return 1;
+	rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr);
+	if (rc != 0) {
+		return rc;
 	}
 
-	*nv_ctr = (unsigned int)(*nv_ctr_addr);
+	*nv_ctr = *((unsigned int *)nv_ctr_addr);
 
 	return 0;
 }
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 927ffef..dc8032f 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -43,6 +43,7 @@
 mbedtls mbedtls_asn1_get_bitstring_null
 mbedtls mbedtls_asn1_get_bool
 mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_len
 mbedtls mbedtls_asn1_get_tag
 mbedtls mbedtls_free
 mbedtls mbedtls_md
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 0433b61..25c963b 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -197,6 +197,7 @@
 					lib/cpus/aarch64/cortex_a76ae.S		\
 					lib/cpus/aarch64/cortex_a77.S		\
 					lib/cpus/aarch64/cortex_a78.S		\
+					lib/cpus/aarch64/cortex_a78_ae.S	\
 					lib/cpus/aarch64/cortex_a78c.S		\
 					lib/cpus/aarch64/cortex_a710.S		\
 					lib/cpus/aarch64/neoverse_n_common.S	\
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c
index ae6af6c..820470b 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c
@@ -17,19 +17,3 @@
 {
 	/* v8-R64 does not include SCRs. */
 }
-
-/*******************************************************************************
- * Set the Secure EL1 required architectural state
- ******************************************************************************/
-void bl1_arch_next_el_setup(void)
-{
-	u_register_t next_sctlr;
-
-	/* Use the same endianness than the current BL */
-	next_sctlr = (read_sctlr_el2() & SCTLR_EE_BIT);
-
-	/* Set SCTLR Secure EL1 */
-	next_sctlr |= SCTLR_EL1_RES1;
-
-	write_sctlr_el1(next_sctlr);
-}
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 8932aa0..327a345 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -41,6 +41,7 @@
 mbedtls mbedtls_asn1_get_bitstring_null
 mbedtls mbedtls_asn1_get_bool
 mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_len
 mbedtls mbedtls_asn1_get_tag
 mbedtls mbedtls_free
 mbedtls mbedtls_md
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 2b9ed25..430aab6 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -52,8 +52,8 @@
 		PLAT_ARM_GICD_BASE >> 16
 	},
 	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 479},
-		{PLAT_ARM_GICD_BASE, 512, 959}
+		{PLAT_ARM_GICD_BASE, 32, 511},
+		{PLAT_ARM_GICD_BASE, 512, 991}
 	}
 };
 
diff --git a/plat/aspeed/ast2700/include/plat_macros.S b/plat/aspeed/ast2700/include/plat_macros.S
new file mode 100644
index 0000000..a58fd74
--- /dev/null
+++ b/plat/aspeed/ast2700/include/plat_macros.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant platform 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/aspeed/ast2700/include/platform_def.h b/plat/aspeed/ast2700/include/platform_def.h
new file mode 100644
index 0000000..3f2468f
--- /dev/null
+++ b/plat/aspeed/ast2700/include/platform_def.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <plat/common/common_def.h>
+#include <platform_reg.h>
+
+#define PLATFORM_STACK_SIZE		UL(0x1000)
+
+/* cpu topology */
+#define PLATFORM_SYSTEM_COUNT		U(1)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CORE_PRIMARY		U(0)
+#define PLATFORM_CORE_COUNT_PER_CLUSTER U(4)
+#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)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/* cache line size */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* translation tables */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 40)
+#define MAX_XLAT_TABLES			U(8)
+#define MAX_MMAP_REGIONS		U(32)
+
+/* BL31 region */
+#define BL31_BASE			ULL(0x400000000)
+#define BL31_SIZE			ULL(0x400000)
+#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
+
+/* BL32 region */
+#define BL32_BASE			BL31_LIMIT
+#define BL32_SIZE			ULL(0x400000)
+#define BL32_LIMIT			(BL32_BASE + BL32_SIZE)
+
+/* console */
+#define CONSOLE_UART_BASE		UART12_BASE
+#define CONSOLE_UART_CLKIN_HZ		U(1846153)
+#define CONSOLE_UART_BAUDRATE		U(115200)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/aspeed/ast2700/include/platform_reg.h b/plat/aspeed/ast2700/include/platform_reg.h
new file mode 100644
index 0000000..20ae32a
--- /dev/null
+++ b/plat/aspeed/ast2700/include/platform_reg.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_REG_H
+#define PLATFORM_REG_H
+
+/* GIC */
+#define GICD_BASE	U(0x12200000)
+#define GICD_SIZE	U(0x10000)
+#define GICR_BASE	U(0x12280000)
+#define GICR_SIZE	U(0x100000)
+
+/* UART */
+#define UART_BASE	U(0x14c33000)
+#define UART12_BASE	(UART_BASE + 0xb00)
+
+/* CPU-die SCU */
+#define SCU_CPU_BASE		U(0x12c02000)
+#define SCU_CPU_SMP_READY	(SCU_CPU_BASE + 0x780)
+#define SCU_CPU_SMP_EP1		(SCU_CPU_BASE + 0x788)
+#define SCU_CPU_SMP_EP2		(SCU_CPU_BASE + 0x790)
+#define SCU_CPU_SMP_EP3		(SCU_CPU_BASE + 0x798)
+#define SCU_CPU_SMP_POLLINSN	(SCU_CPU_BASE + 0x7a0)
+
+#endif /* PLATFORM_REG_H */
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
new file mode 100644
index 0000000..36e7338
--- /dev/null
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/console.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+static console_t console;
+
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static unsigned int plat_mpidr_to_core_pos(u_register_t mpidr)
+{
+	/* to workaround the return type mismatch */
+	return plat_core_pos_by_mpidr(mpidr);
+}
+
+static const gicv3_driver_data_t plat_gic_data = {
+	.gicd_base = GICD_BASE,
+	.gicr_base = GICR_BASE,
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+	.mpidr_to_core_pos = plat_mpidr_to_core_pos,
+};
+
+static const mmap_region_t plat_mmap[] = {
+	MAP_REGION_FLAT(GICD_BASE, GICD_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(GICR_BASE, GICR_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(UART_BASE, PAGE_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SCU_CPU_BASE, PAGE_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	{ 0 }
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	console_16550_register(CONSOLE_UART_BASE, CONSOLE_UART_CLKIN_HZ,
+			       CONSOLE_UART_BAUDRATE, &console);
+
+	console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+
+	bl31_params_parse_helper(arg0, &bl32_ep_info, &bl33_ep_info);
+}
+
+void bl31_plat_arch_setup(void)
+{
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	mmap_add_region(BL_CODE_END, BL_CODE_END,
+			BL_END - BL_CODE_END,
+			MT_RW_DATA | MT_SECURE);
+
+	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE,
+			MT_MEMORY | MT_RW);
+
+	mmap_add(plat_mmap);
+
+	init_xlat_tables();
+
+	enable_mmu_el3(0);
+}
+
+void bl31_platform_setup(void)
+{
+	gicv3_driver_init(&plat_gic_data);
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *ep_info;
+
+	ep_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+
+	if (!ep_info->pc) {
+		return NULL;
+	}
+
+	return ep_info;
+}
diff --git a/plat/aspeed/ast2700/plat_helpers.S b/plat/aspeed/ast2700/plat_helpers.S
new file mode 100644
index 0000000..1457692
--- /dev/null
+++ b/plat/aspeed/ast2700/plat_helpers.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <arch.h>
+#include <cortex_a35.h>
+#include <platform_def.h>
+
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_get_syscnt_freq2
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+
+/* unsigned int plat_is_my_cpu_primary(void); */
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp	x0, #PLATFORM_CORE_PRIMARY
+	cset	w0, eq
+	ret
+endfunc plat_is_my_cpu_primary
+
+/* unsigned int plat_my_core_pos(void); */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	mov	x2, #PLATFORM_CORE_COUNT_PER_CLUSTER
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	madd	x0, x0, x2, x1
+	ret
+endfunc plat_my_core_pos
+
+/* 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
+	mov_imm	x1, CONSOLE_UART_CLKIN_HZ
+	mov_imm	x2, CONSOLE_UART_BAUDRATE
+	b	console_16550_core_init
+endfunc plat_crash_console_init
+
+/* int plat_crash_console_putc(int); */
+func plat_crash_console_putc
+	mov_imm	x1, CONSOLE_UART_BASE
+	b	console_16550_core_putc
+endfunc plat_crash_console_putc
+
+/* void plat_crash_console_flush(void); */
+func plat_crash_console_flush
+	mov_imm	x0, CONSOLE_UART_BASE
+	b	console_16550_core_flush
+endfunc plat_crash_console_flush
diff --git a/plat/aspeed/ast2700/plat_pm.c b/plat/aspeed/ast2700/plat_pm.c
new file mode 100644
index 0000000..8e69243
--- /dev/null
+++ b/plat/aspeed/ast2700/plat_pm.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/console.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+static uintptr_t sec_ep;
+
+static int plat_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned int cpu = plat_core_pos_by_mpidr(mpidr);
+	uintptr_t ep_reg;
+
+	switch (cpu) {
+	case 1U:
+		ep_reg = SCU_CPU_SMP_EP1;
+		break;
+	case 2U:
+		ep_reg = SCU_CPU_SMP_EP2;
+		break;
+	case 3U:
+		ep_reg = SCU_CPU_SMP_EP3;
+		break;
+	default:
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	mmio_write_64(ep_reg, sec_ep);
+
+	dsbsy();
+
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void plat_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+static const plat_psci_ops_t plat_psci_ops = {
+	.pwr_domain_on = plat_pwr_domain_on,
+	.pwr_domain_on_finish = plat_pwr_domain_on_finish,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	sec_ep = sec_entrypoint;
+	*psci_ops = &plat_psci_ops;
+
+	return 0;
+}
diff --git a/plat/aspeed/ast2700/plat_topology.c b/plat/aspeed/ast2700/plat_topology.c
new file mode 100644
index 0000000..1476fba
--- /dev/null
+++ b/plat/aspeed/ast2700/plat_topology.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023, Aspeed Technology Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+
+static const unsigned char ast2700_power_domain_tree_desc[] = {
+	PLATFORM_SYSTEM_COUNT,
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+};
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return ast2700_power_domain_tree_desc;
+}
+
+unsigned int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
+		return -1;
+	}
+
+	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -1;
+	}
+
+	if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
+		return -1;
+	}
+
+	return (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER) + cpu_id;
+}
diff --git a/plat/aspeed/ast2700/platform.mk b/plat/aspeed/ast2700/platform.mk
new file mode 100644
index 0000000..16ecf0a
--- /dev/null
+++ b/plat/aspeed/ast2700/platform.mk
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2023, Aspeed Technology Inc.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_AST2700 := plat/aspeed/ast2700
+
+PLAT_INCLUDES := \
+	-I${PLAT_AST2700}/include
+
+BL31_SOURCES += \
+	common/desc_image_load.c		\
+	lib/cpus/aarch64/cortex_a35.S		\
+	plat/common/plat_gicv3.c		\
+	plat/common/plat_psci_common.c		\
+	drivers/ti/uart/aarch64/16550_console.S	\
+	${PLAT_AST2700}/plat_helpers.S		\
+	${PLAT_AST2700}/plat_topology.c		\
+	${PLAT_AST2700}/plat_bl31_setup.c	\
+	${PLAT_AST2700}/plat_pm.c		\
+	${GICV3_SOURCES}			\
+	${XLAT_TABLES_LIB_SRCS}
+
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+COLD_BOOT_SINGLE_CPU := 1
+
+ENABLE_SVE_FOR_NS := 0
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 6708edb..0668301 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -167,6 +167,7 @@
 #define INTEL_SIP_SMC_V2_REG_WRITE				0xC2000402
 #define INTEL_SIP_SMC_V2_REG_UPDATE				0xC2000403
 #define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES			0xC2000404
+#define INTEL_SIP_SMC_V2_RSU_UPDATE_ADDR			0xC2000405
 
 /* V2: Mailbox function identifier */
 #define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND			0xC2000420
@@ -185,7 +186,7 @@
 /*
  * Increase if there is new SMC function ID being added
  */
-#define SIP_SVC_VERSION_MINOR					1
+#define SIP_SVC_VERSION_MINOR					2
 
 
 /* Structure Definitions */
@@ -219,6 +220,9 @@
 uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
 				 uint32_t val, uint32_t *retval);
 
+/* Set RSU update address*/
+uint32_t intel_rsu_update(uint64_t update_address);
+
 /* Miscellaneous HPS services */
 uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask);
 
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index ff050e4..1a18ee1 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -442,7 +442,7 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-static uint32_t intel_rsu_update(uint64_t update_address)
+uint32_t intel_rsu_update(uint64_t update_address)
 {
 	if (update_address > SIZE_MAX) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
diff --git a/plat/intel/soc/common/socfpga_sip_svc_v2.c b/plat/intel/soc/common/socfpga_sip_svc_v2.c
index 791c714..e9996d3 100644
--- a/plat/intel/soc/common/socfpga_sip_svc_v2.c
+++ b/plat/intel/soc/common/socfpga_sip_svc_v2.c
@@ -158,6 +158,10 @@
 		status = intel_hps_set_bridges(x2, x3);
 		SMC_RET2(handle, status, x1);
 
+	case INTEL_SIP_SMC_V2_RSU_UPDATE_ADDR:
+		status = intel_rsu_update(x2);
+		SMC_RET2(handle, status, x1);
+
 	case INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND:
 		status = intel_v2_mbox_send_cmd(x1, (uint32_t *)x2, x3);
 		SMC_RET2(handle, status, x1);
diff --git a/plat/mediatek/drivers/apusys/apusys.c b/plat/mediatek/drivers/apusys/apusys.c
index c82b3a7..dfe1dcf 100644
--- a/plat/mediatek/drivers/apusys/apusys.c
+++ b/plat/mediatek/drivers/apusys/apusys.c
@@ -9,7 +9,10 @@
 
 /* Vendor header */
 #include "apusys.h"
+#include "apusys_devapc.h"
 #include "apusys_power.h"
+#include "apusys_rv.h"
+#include "apusys_security_ctrl_plat.h"
 #include <lib/mtk_init/mtk_init.h>
 #include <mtk_sip_svc.h>
 
@@ -32,6 +35,39 @@
 	case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF:
 		ret = apusys_kernel_apusys_pwr_top_off();
 		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER:
+		ret = apusys_kernel_apusys_rv_setup_reviser();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP:
+		ret = apusys_kernel_apusys_rv_reset_mp();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT:
+		ret = apusys_kernel_apusys_rv_setup_boot();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP:
+		ret = apusys_kernel_apusys_rv_start_mp();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP:
+		ret = apusys_kernel_apusys_rv_stop_mp();
+		break;
+	case MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX:
+		ret = apusys_devapc_rcx_init();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM:
+		ret = apusys_kernel_apusys_rv_setup_sec_mem();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR:
+		ret = apusys_kernel_apusys_rv_disable_wdt_isr();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR:
+		ret = apusys_kernel_apusys_rv_clear_wdt_isr();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING:
+		ret = apusys_kernel_apusys_rv_cg_gating();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING:
+		ret = apusys_kernel_apusys_rv_cg_ungating();
+		break;
 	default:
 		ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops);
 		break;
@@ -43,7 +79,17 @@
 
 int apusys_init(void)
 {
-	apusys_power_init();
+	if (apusys_power_init() != 0) {
+		return -1;
+	}
+
+	if (apusys_devapc_ao_init() != 0) {
+		return -1;
+	}
+
+	apusys_security_ctrl_init();
+	apusys_rv_mbox_mpu_init();
+
 	return 0;
 }
 MTK_PLAT_SETUP_1_INIT(apusys_init);
diff --git a/plat/mediatek/drivers/apusys/apusys.h b/plat/mediatek/drivers/apusys/apusys.h
index 1592cff..ed4e195 100644
--- a/plat/mediatek/drivers/apusys/apusys.h
+++ b/plat/mediatek/drivers/apusys/apusys.h
@@ -10,8 +10,19 @@
 #define MODULE_TAG "[APUSYS]"
 
 enum MTK_APUSYS_KERNEL_OP {
-	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON,	/*  0 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,/*  1 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON,		/*  0 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,	/*  1 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER,	/*  2 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP,	/*  3 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT,	/*  4 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP,	/*  5 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP,		/*  6 */
+	MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX,		/*  7 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM,	/*  8 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR,	/*  9 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR,	/* 10 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING,	/* 11 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING,	/* 12 */
 	MTK_APUSYS_KERNEL_OP_NUM,
 };
 
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
new file mode 100644
index 0000000..c1b3de0
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TF-A system header */
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+
+/* Vendor header */
+#include "apusys.h"
+#include "apusys_rv.h"
+#include "apusys_rv_mbox_mpu.h"
+#include "emi_mpu.h"
+
+static spinlock_t apusys_rv_lock;
+
+void apusys_rv_mbox_mpu_init(void)
+{
+	int i;
+
+	for (i = 0; i < APU_MBOX_NUM; i++) {
+		mmio_write_32(APU_MBOX_FUNC_CFG(i),
+			      (MBOX_CTRL_LOCK |
+			       (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT)));
+		mmio_write_32(APU_MBOX_DOMAIN_CFG(i),
+			      (MBOX_CTRL_LOCK |
+			       (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) |
+			       (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) |
+			       (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) |
+			       (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT)));
+	}
+}
+
+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);
+
+	mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN);
+
+	mmio_write_32(UP_NORMAL_DOMAIN_NS,
+		      (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT));
+	mmio_write_32(UP_PRI_DOMAIN_NS,
+		      (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT));
+
+	mmio_write_32(UP_CORE0_VABASE0,
+		      VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT));
+	mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
+
+	mmio_write_32(UP_CORE0_VABASE1,
+		      VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT));
+	mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
+
+	spin_unlock(&apusys_rv_lock);
+
+	return 0;
+}
+
+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);
+
+	udelay(RESET_DEALY_US);
+
+	mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN |
+		      MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN |
+		      MD32_SOFT_RSTN);
+
+	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
+	mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN);
+	mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN);
+
+	spin_unlock(&apusys_rv_lock);
+
+	return 0;
+}
+
+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) |
+		      (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
+		      (PREDEFINE_CACHE << PREDEF_4G_OFS));
+
+	spin_unlock(&apusys_rv_lock);
+	return 0;
+}
+
+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;
+}
+
+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__);
+	}
+
+	spin_unlock(&apusys_rv_lock);
+	return ret;
+}
+
+int apusys_kernel_apusys_rv_disable_wdt_isr(void)
+{
+	spin_lock(&apusys_rv_lock);
+	mmio_clrbits_32(WDT_CTRL0, WDT_EN);
+	spin_unlock(&apusys_rv_lock);
+
+	return 0;
+}
+
+int apusys_kernel_apusys_rv_clear_wdt_isr(void)
+{
+	spin_lock(&apusys_rv_lock);
+	mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
+	mmio_write_32(WDT_INT, WDT_INT_W1C);
+	spin_unlock(&apusys_rv_lock);
+
+	return 0;
+}
+
+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);
+
+	return 0;
+}
+
+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);
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
new file mode 100644
index 0000000..8a43890
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_H
+#define APUSYS_RV_H
+
+#include <platform_def.h>
+
+#define APU_SEC_FW_IOVA			(0x200000UL)
+
+/* APU_SCTRL_REVISER */
+#define UP_NORMAL_DOMAIN_NS		(APU_REVISER + 0x0000)
+#define UP_PRI_DOMAIN_NS		(APU_REVISER + 0x0004)
+#define UP_IOMMU_CTRL			(APU_REVISER + 0x0008)
+#define UP_CORE0_VABASE0		(APU_REVISER + 0x000c)
+#define UP_CORE0_MVABASE0		(APU_REVISER + 0x0010)
+#define UP_CORE0_VABASE1		(APU_REVISER + 0x0014)
+#define UP_CORE0_MVABASE1		(APU_REVISER + 0x0018)
+#define UP_CORE0_VABASE2		(APU_REVISER + 0x001c)
+#define UP_CORE0_MVABASE2		(APU_REVISER + 0x0020)
+#define UP_CORE0_VABASE3		(APU_REVISER + 0x0024)
+#define UP_CORE0_MVABASE3		(APU_REVISER + 0x0028)
+#define USERFW_CTXT			(APU_REVISER + 0x1000)
+#define SECUREFW_CTXT			(APU_REVISER + 0x1004)
+#define UP_NORMAL_DOMAIN		(7)
+#define UP_NORMAL_NS			(1)
+#define UP_PRI_DOMAIN			(5)
+#define UP_PRI_NS			(1)
+#define UP_DOMAIN_SHIFT			(0)
+#define UP_NS_SHIFT			(4)
+#define MMU_EN				BIT(0)
+#define MMU_CTRL			BIT(1)
+#define MMU_CTRL_LOCK			BIT(2)
+#define VLD				BIT(0)
+#define PARTIAL_ENABLE			BIT(1)
+#define THREAD_NUM_PRI			(1)
+#define THREAD_NUM_NORMAL		(0)
+#define THREAD_NUM_SHIFT		(2)
+#define VASIZE_1MB			BIT(0)
+#define CFG_4GB_SEL_EN			BIT(2)
+#define CFG_4GB_SEL			(0)
+#define MVA_34BIT_SHIFT			(2)
+
+/* APU_MD32_SYSCTRL */
+#define MD32_SYS_CTRL			(APU_MD32_SYSCTRL + 0x0000)
+#define UP_INT_EN2			(APU_MD32_SYSCTRL + 0x000c)
+#define MD32_CLK_CTRL			(APU_MD32_SYSCTRL + 0x00b8)
+#define UP_WAKE_HOST_MASK0		(APU_MD32_SYSCTRL + 0x00bc)
+#define UP_WAKE_HOST_MASK1		(APU_MD32_SYSCTRL + 0x00c0)
+#define MD32_SYS_CTRL_RST		(0)
+#define MD32_G2B_CG_EN			BIT(11)
+#define MD32_DBG_EN			BIT(10)
+#define MD32_DM_AWUSER_IOMMU_EN		BIT(9)
+#define MD32_DM_ARUSER_IOMMU_EN		BIT(7)
+#define MD32_PM_AWUSER_IOMMU_EN		BIT(5)
+#define MD32_PM_ARUSER_IOMMU_EN		BIT(3)
+#define MD32_SOFT_RSTN			BIT(0)
+#define MD32_CLK_EN			(1)
+#define MD32_CLK_DIS			(0)
+#define WDT_IRQ_EN			BIT(0)
+#define MBOX0_IRQ_EN			BIT(21)
+#define MBOX1_IRQ_EN			BIT(22)
+#define MBOX2_IRQ_EN			BIT(23)
+#define RESET_DEALY_US			(10)
+#define DBG_APB_EN			BIT(31)
+
+/* APU_AO_CTRL */
+#define MD32_PRE_DEFINE			(APU_AO_CTRL + 0x0000)
+#define MD32_BOOT_CTRL			(APU_AO_CTRL + 0x0004)
+#define MD32_RUNSTALL			(APU_AO_CTRL + 0x0008)
+#define PREDEFINE_NON_CACHE		(0)
+#define PREDEFINE_TCM			(1)
+#define PREDEFINE_CACHE			(2)
+#define PREDEFINE_CACHE_TCM		(3)
+#define PREDEF_1G_OFS			(0)
+#define PREDEF_2G_OFS			(2)
+#define PREDEF_3G_OFS			(4)
+#define PREDEF_4G_OFS			(6)
+#define MD32_RUN			(0)
+#define MD32_STALL			(1)
+
+/* APU_MD32_WDT */
+#define WDT_INT				(APU_MD32_WDT + 0x0)
+#define WDT_CTRL0			(APU_MD32_WDT + 0x4)
+#define WDT_INT_W1C			(1)
+#define WDT_EN				BIT(31)
+
+/* APU MBOX */
+#define MBOX_FUNC_CFG			(0xb0)
+#define MBOX_DOMAIN_CFG			(0xe0)
+#define MBOX_CTRL_LOCK			BIT(0)
+#define MBOX_NO_MPU_SHIFT		(16)
+#define MBOX_RX_NS_SHIFT		(16)
+#define MBOX_RX_DOMAIN_SHIFT		(17)
+#define MBOX_TX_NS_SHIFT		(24)
+#define MBOX_TX_DOMAIN_SHIFT		(25)
+#define MBOX_SIZE			(0x100)
+#define MBOX_NUM			(8)
+
+#define APU_MBOX(i)		(((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
+						  (APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
+#define APU_MBOX_FUNC_CFG(i)	(APU_MBOX(i) + MBOX_FUNC_CFG)
+#define APU_MBOX_DOMAIN_CFG(i)	(APU_MBOX(i) + MBOX_DOMAIN_CFG)
+
+void apusys_rv_mbox_mpu_init(void);
+int apusys_kernel_apusys_rv_setup_reviser(void);
+int apusys_kernel_apusys_rv_reset_mp(void);
+int apusys_kernel_apusys_rv_setup_boot(void);
+int apusys_kernel_apusys_rv_start_mp(void);
+int apusys_kernel_apusys_rv_stop_mp(void);
+int apusys_kernel_apusys_rv_setup_sec_mem(void);
+int apusys_kernel_apusys_rv_disable_wdt_isr(void);
+int apusys_kernel_apusys_rv_clear_wdt_isr(void);
+int apusys_kernel_apusys_rv_cg_gating(void);
+int apusys_kernel_apusys_rv_cg_ungating(void);
+
+#endif /* APUSYS_RV_H */
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h
new file mode 100644
index 0000000..0ee4878
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_MBOX_MPU_H
+#define APUSYS_RV_MBOX_MPU_H
+
+#define MPU_EN		(0)
+#define MPU_DIS		(1)
+#define MBOX0_TX_DOMAIN	(0)
+#define MBOX0_TX_NS	(1)
+#define MBOX4_RX_DOMAIN	(0)
+#define MBOX4_RX_NS	(0)
+#define MBOX5_TX_DOMAIN	(3)
+#define MBOX5_TX_NS	(0)
+#define MBOXN_RX_DOMAIN	(5)
+#define MBOXN_RX_NS	(1)
+#define MBOXN_TX_DOMAIN	(0)
+#define MBOXN_TX_NS	(0)
+
+struct mbox_mpu_setting {
+	uint32_t no_mpu;
+	uint32_t rx_ns;
+	uint32_t rx_domain;
+	uint32_t tx_ns;
+	uint32_t tx_domain;
+};
+
+static const struct mbox_mpu_setting mbox_mpu_setting_tab[] = {
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX0_TX_NS, MBOX0_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_DIS, MBOX4_RX_NS, MBOX4_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX5_TX_NS, MBOX5_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+	{ MPU_EN,  MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN },
+};
+
+#define APU_MBOX_NUM ARRAY_SIZE(mbox_mpu_setting_tab)
+
+#endif /* APUSYS_RV_MBOX_MPU_H */
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/rules.mk b/plat/mediatek/drivers/apusys/apusys_rv/2.0/rules.mk
new file mode 100644
index 0000000..031264d
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := apusys_rv_${MTK_SOC}
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/${MTK_SOC}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_rv.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c
new file mode 100644
index 0000000..4bd4272
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TF-A system header */
+#include <common/debug.h>
+#include <lib/utils_def.h>
+
+/* Vendor header */
+#include "apusys.h"
+#include "apusys_dapc_v1.h"
+#include <platform_def.h>
+
+enum apusys_apc_err_status set_apusys_dapc_v1(const struct apc_dom_16 *dapc,
+					      uint32_t size, dapc_cfg_func cfg)
+{
+	enum apusys_apc_err_status ret = APUSYS_APC_OK;
+	uint32_t i;
+
+	if ((dapc == NULL) || (cfg == NULL)) {
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	for (i = 0; i < size; i++) {
+		ret += cfg(i, DOMAIN_0,	 dapc[i].d0_permission);
+		ret += cfg(i, DOMAIN_1,	 dapc[i].d1_permission);
+		ret += cfg(i, DOMAIN_2,	 dapc[i].d2_permission);
+		ret += cfg(i, DOMAIN_3,	 dapc[i].d3_permission);
+		ret += cfg(i, DOMAIN_4,	 dapc[i].d4_permission);
+		ret += cfg(i, DOMAIN_5,	 dapc[i].d5_permission);
+		ret += cfg(i, DOMAIN_6,	 dapc[i].d6_permission);
+		ret += cfg(i, DOMAIN_7,	 dapc[i].d7_permission);
+		ret += cfg(i, DOMAIN_8,	 dapc[i].d8_permission);
+		ret += cfg(i, DOMAIN_9,	 dapc[i].d9_permission);
+		ret += cfg(i, DOMAIN_10, dapc[i].d10_permission);
+		ret += cfg(i, DOMAIN_11, dapc[i].d11_permission);
+		ret += cfg(i, DOMAIN_12, dapc[i].d12_permission);
+		ret += cfg(i, DOMAIN_13, dapc[i].d13_permission);
+		ret += cfg(i, DOMAIN_14, dapc[i].d14_permission);
+		ret += cfg(i, DOMAIN_15, dapc[i].d15_permission);
+	}
+
+	if (ret != APUSYS_APC_OK) {
+		ret = APUSYS_APC_ERR_GENERIC;
+	}
+
+	return ret;
+}
+
+void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uint32_t dom_num)
+{
+	uint32_t d, i;
+
+	if ((name == NULL) || (base == 0)) {
+		return;
+	}
+
+	for (d = 0; d < dom_num; d++) {
+		for (i = 0; i <= reg_num; i++) {
+			INFO(MODULE_TAG "[%s] D%d_APC_%d: 0x%x\n", name, d, i,
+			     mmio_read_32(base + d * DEVAPC_DOM_SIZE + i * DEVAPC_REG_SIZE));
+		}
+	}
+
+	INFO(MODULE_TAG "[%s] APC_CON: 0x%x\n", name, mmio_read_32(APUSYS_DAPC_CON(base)));
+}
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
new file mode 100644
index 0000000..2f5d47b
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DAPC_V1_H
+#define APUSYS_DAPC_V1_H
+
+#include <lib/mmio.h>
+
+/******************************************************************************
+ * STRUCTURE DEFINITION
+ ******************************************************************************/
+enum apusys_apc_err_status {
+	APUSYS_APC_OK		= 0x0,
+	APUSYS_APC_ERR_GENERIC	= 0x1,
+};
+
+enum apusys_apc_perm_type {
+	NO_PROTECTION	= 0,
+	SEC_RW_ONLY	= 1,
+	SEC_RW_NS_R	= 2,
+	FORBIDDEN	= 3,
+	PERM_NUM	= 4,
+};
+
+enum apusys_apc_domain_id {
+	DOMAIN_0	=  0,
+	DOMAIN_1	=  1,
+	DOMAIN_2	=  2,
+	DOMAIN_3	=  3,
+	DOMAIN_4	=  4,
+	DOMAIN_5	=  5,
+	DOMAIN_6	=  6,
+	DOMAIN_7	=  7,
+	DOMAIN_8	=  8,
+	DOMAIN_9	=  9,
+	DOMAIN_10	= 10,
+	DOMAIN_11	= 11,
+	DOMAIN_12	= 12,
+	DOMAIN_13	= 13,
+	DOMAIN_14	= 14,
+	DOMAIN_15	= 15,
+};
+
+struct apc_dom_16 {
+	unsigned char d0_permission;
+	unsigned char d1_permission;
+	unsigned char d2_permission;
+	unsigned char d3_permission;
+	unsigned char d4_permission;
+	unsigned char d5_permission;
+	unsigned char d6_permission;
+	unsigned char d7_permission;
+	unsigned char d8_permission;
+	unsigned char d9_permission;
+	unsigned char d10_permission;
+	unsigned char d11_permission;
+	unsigned char d12_permission;
+	unsigned char d13_permission;
+	unsigned char d14_permission;
+	unsigned char d15_permission;
+};
+
+#define APUSYS_APC_AO_ATTR(DEV_NAME,					       \
+			   PERM_ATTR0,  PERM_ATTR1,  PERM_ATTR2,  PERM_ATTR3,  \
+			   PERM_ATTR4,  PERM_ATTR5,  PERM_ATTR6,  PERM_ATTR7,  \
+			   PERM_ATTR8,  PERM_ATTR9,  PERM_ATTR10, PERM_ATTR11, \
+			   PERM_ATTR12, PERM_ATTR13, PERM_ATTR14, PERM_ATTR15) \
+	{(unsigned char)PERM_ATTR0,  (unsigned char)PERM_ATTR1,  \
+	 (unsigned char)PERM_ATTR2,  (unsigned char)PERM_ATTR3,  \
+	 (unsigned char)PERM_ATTR4,  (unsigned char)PERM_ATTR5,  \
+	 (unsigned char)PERM_ATTR6,  (unsigned char)PERM_ATTR7,  \
+	 (unsigned char)PERM_ATTR8,  (unsigned char)PERM_ATTR9,  \
+	 (unsigned char)PERM_ATTR10, (unsigned char)PERM_ATTR11, \
+	 (unsigned char)PERM_ATTR12, (unsigned char)PERM_ATTR13, \
+	 (unsigned char)PERM_ATTR14, (unsigned char)PERM_ATTR15}
+
+typedef enum apusys_apc_err_status (*dapc_cfg_func)(uint32_t slave,
+						    enum apusys_apc_domain_id domain_id,
+						    enum apusys_apc_perm_type perm);
+
+/* Register */
+#define DEVAPC_DOM_SIZE			(0x40)
+#define DEVAPC_REG_SIZE			(4)
+
+/* APUSYS APC offsets */
+#define APUSYS_DAPC_CON_VIO_MASK	(0x80000000)
+#define APUSYS_DAPC_CON(base)		((base) + 0x00f00)
+
+/******************************************************************************
+ * DAPC Common Function
+ ******************************************************************************/
+#define SET_APUSYS_DAPC_V1(dapc, cfg) \
+	set_apusys_dapc_v1(dapc, ARRAY_SIZE(dapc), cfg)
+
+#define DUMP_APUSYS_DAPC_V1(apc) \
+	dump_apusys_dapc_v1(#apc, apc##_BASE, \
+			    (apc##_SLAVE_NUM / apc##_SLAVE_NUM_IN_1_DOM), apc##_DOM_NUM)
+
+enum apusys_apc_err_status set_apusys_dapc_v1(const struct apc_dom_16 *dapc,
+					      uint32_t size, dapc_cfg_func cfg);
+
+void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uint32_t dom_num);
+
+/******************************************************************************
+ * DAPC Permission Policy
+ ******************************************************************************/
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW(domain)				 \
+	APUSYS_APC_AO_ATTR(domain,					 \
+			   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT(domain)		     \
+	APUSYS_APC_AO_ATTR(domain,					     \
+			   SEC_RW_ONLY, FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_NO_PROTECT(domain)			   \
+	APUSYS_APC_AO_ATTR(domain,					   \
+			   FORBIDDEN, FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN, FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN, FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT(domain)	     \
+	APUSYS_APC_AO_ATTR(domain,					     \
+			   SEC_RW_NS_R, FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D7_NO_PROTECT(domain)			   \
+	APUSYS_APC_AO_ATTR(domain,					   \
+			   FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,     \
+			   FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
+			   FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,     \
+			   FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_D7_NO_PROTECT(domain)			       \
+	APUSYS_APC_AO_ATTR(domain,					       \
+			   FORBIDDEN, FORBIDDEN,     FORBIDDEN, FORBIDDEN,     \
+			   FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION, \
+			   FORBIDDEN, FORBIDDEN,     FORBIDDEN, FORBIDDEN,     \
+			   FORBIDDEN, FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT(domain)			       \
+	APUSYS_APC_AO_ATTR(domain,					       \
+			   NO_PROTECTION, FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW(domain)			 \
+	APUSYS_APC_AO_ATTR(domain,						 \
+			   NO_PROTECTION, FORBIDDEN,     FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,     NO_PROTECTION, FORBIDDEN, FORBIDDEN,   \
+			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN,   \
+			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D3_SEC_RW_D5_NO_PROTECT(domain)		       \
+	APUSYS_APC_AO_ATTR(domain,					       \
+			   SEC_RW_ONLY, FORBIDDEN,     FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,   NO_PROTECTION, FORBIDDEN, FORBIDDEN,   \
+			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN,   \
+			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#endif /* APUSYS_DAPC_V1_H */
diff --git a/plat/mediatek/drivers/apusys/devapc/rules.mk b/plat/mediatek/drivers/apusys/devapc/rules.mk
new file mode 100644
index 0000000..6153b31
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/devapc/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := apusys_devapc
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_dapc_v1.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
new file mode 100644
index 0000000..da5242a
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TF-A system header */
+#include <common/debug.h>
+#include <lib/utils_def.h>
+
+/* Vendor header */
+#include "apusys.h"
+#include "apusys_devapc.h"
+#include "apusys_devapc_def.h"
+#include <platform_def.h>
+
+#define DUMP_APUSYS_DAPC	(0)
+
+static const struct apc_dom_16 APU_NOC_DAPC_RCX[] = {
+	/* ctrl index = 0 */
+	SLAVE_MD32_SRAM("slv16-0"),
+	SLAVE_MD32_SRAM("slv16-1"),
+	SLAVE_MD32_SRAM("slv16-2"),
+	SLAVE_MD32_SRAM("slv16-3"),
+	SLAVE_MD32_SRAM("slv16-4"),
+};
+
+static const struct apc_dom_16 APU_CTRL_DAPC_AO[] = {
+	/* ctrl index = 0 */
+	SLAVE_VCORE("apu_ao_ctl_o-0"),
+	SLAVE_RPC("apu_ao_ctl_o-2"),
+	SLAVE_PCU("apu_ao_ctl_o-3"),
+	SLAVE_AO_CTRL("apu_ao_ctl_o-4"),
+	SLAVE_PLL("apu_ao_ctl_o-5"),
+	SLAVE_ACC("apu_ao_ctl_o-6"),
+	SLAVE_SEC("apu_ao_ctl_o-7"),
+	SLAVE_ARE0("apu_ao_ctl_o-8"),
+	SLAVE_ARE1("apu_ao_ctl_o-9"),
+	SLAVE_ARE2("apu_ao_ctl_o-10"),
+
+	/* ctrl index = 10 */
+	SLAVE_UNKNOWN("apu_ao_ctl_o-11"),
+	SLAVE_AO_BCRM("apu_ao_ctl_o-12"),
+	SLAVE_AO_DAPC_WRAP("apu_ao_ctl_o-13"),
+	SLAVE_AO_DAPC_CON("apu_ao_ctl_o-14"),
+	SLAVE_RCX_ACX_BULK("apu_ao_ctl_o-15"),
+	SLAVE_UNKNOWN("apu_ao_ctl_o-16"),
+	SLAVE_UNKNOWN("apu_ao_ctl_o-17"),
+	SLAVE_APU_BULK("apu_ao_ctl_o-18"),
+	SLAVE_ACX0_BCRM("apu_ao_ctl_o-20"),
+	SLAVE_RPCTOP_LITE_ACX0("apu_ao_ctl_o-21"),
+
+	/* ctrl index = 20 */
+	SLAVE_ACX1_BCRM("apu_ao_ctl_o-22"),
+	SLAVE_RPCTOP_LITE_ACX1("apu_ao_ctl_o-23"),
+	SLAVE_RCX_TO_ACX0_0("apu_rcx2acx0_o-0"),
+	SLAVE_RCX_TO_ACX0_1("apu_rcx2acx0_o-1"),
+	SLAVE_SAE_TO_ACX0_0("apu_sae2acx0_o-0"),
+	SLAVE_SAE_TO_ACX0_1("apu_sae2acx0_o-1"),
+	SLAVE_RCX_TO_ACX1_0("apu_rcx2acx1_o-0"),
+	SLAVE_RCX_TO_ACX1_1("apu_rcx2acx1_o-1"),
+	SLAVE_SAE_TO_ACX1_0("apu_sae2acx1_o-0"),
+	SLAVE_SAE_TO_ACX1_1("apu_sae2acx1_o-1"),
+};
+
+static const struct apc_dom_16 APU_CTRL_DAPC_RCX[] = {
+	/* ctrl index = 0 */
+	SLAVE_MD32_SYSCTRL0("md32_apb_s-0"),
+	SLAVE_MD32_SYSCTRL1("md32_apb_s-1"),
+	SLAVE_MD32_WDT("md32_apb_s-2"),
+	SLAVE_MD32_CACHE("md32_apb_s-3"),
+	SLAVE_RPC("apusys_ao-0"),
+	SLAVE_PCU("apusys_ao-1"),
+	SLAVE_AO_CTRL("apusys_ao-2"),
+	SLAVE_PLL("apusys_ao-3"),
+	SLAVE_ACC("apusys_ao-4"),
+	SLAVE_SEC("apusys_ao-5"),
+
+	/* ctrl index = 10 */
+	SLAVE_ARE0("apusys_ao-6"),
+	SLAVE_ARE1("apusys_ao-7"),
+	SLAVE_ARE2("apusys_ao-8"),
+	SLAVE_UNKNOWN("apusys_ao-9"),
+	SLAVE_AO_BCRM("apusys_ao-10"),
+	SLAVE_AO_DAPC_WRAP("apusys_ao-11"),
+	SLAVE_AO_DAPC_CON("apusys_ao-12"),
+	SLAVE_VCORE("apusys_ao-13"),
+	SLAVE_ACX0_BCRM("apusys_ao-15"),
+	SLAVE_ACX1_BCRM("apusys_ao-16"),
+
+	/* ctrl index = 20 */
+	SLAVE_NOC_AXI("noc_axi"),
+	SLAVE_MD32_DBG("md32_dbg"),
+	SLAVE_DBG_CRTL("apb_infra_dbg"),
+	SLAVE_IOMMU0_BANK0("apu_n_mmu_r0"),
+	SLAVE_IOMMU0_BANK1("apu_n_mmu_r1"),
+	SLAVE_IOMMU0_BANK2("apu_n_mmu_r2"),
+	SLAVE_IOMMU0_BANK3("apu_n_mmu_r3"),
+	SLAVE_IOMMU0_BANK4("apu_n_mmu_r4"),
+	SLAVE_IOMMU1_BANK0("apu_s_mmu_r0"),
+	SLAVE_IOMMU1_BANK1("apu_s_mmu_r1"),
+
+	/* ctrl index = 30 */
+	SLAVE_IOMMU1_BANK2("apu_s_mmu_r2"),
+	SLAVE_IOMMU1_BANK3("apu_s_mmu_r3"),
+	SLAVE_IOMMU1_BANK4("apu_s_mmu_r4"),
+	SLAVE_S0_SSC("apu_s0_ssc_cfg"),
+	SLAVE_N0_SSC("apu_n0_ssc_cfg"),
+	SLAVE_ACP_SSC("apu_acp_ssc_cfg"),
+	SLAVE_S1_SSC("apu_s1_ssc_cfg"),
+	SLAVE_N1_SSC("apu_n1_ssc_cfg"),
+	SLAVE_CFG("apu_rcx_cfg"),
+	SLAVE_SEMA_STIMER("apu_sema_stimer"),
+
+	/* ctrl index = 40 */
+	SLAVE_EMI_CFG("apu_emi_cfg"),
+	SLAVE_LOG("apu_logtop"),
+	SLAVE_CPE_SENSOR("apu_cpe_sensor"),
+	SLAVE_CPE_COEF("apu_cpe_coef"),
+	SLAVE_CPE_CTRL("apu_cpe_ctrl"),
+	SLAVE_UNKNOWN("apu_xpu_rsi"),
+	SLAVE_DFD_REG_SOC("apu_dfd"),
+	SLAVE_SENSOR_WRAP_ACX0_DLA0("apu_sen_ac0_dla0"),
+	SLAVE_SENSOR_WRAP_ACX0_DLA1("apu_sen_ac0_dla1"),
+	SLAVE_SENSOR_WRAP_ACX0_VPU0("apu_sen_ac0_vpu"),
+
+	/* ctrl index = 50 */
+	SLAVE_SENSOR_WRAP_ACX1_DLA0("apu_sen_ac1_dla0"),
+	SLAVE_SENSOR_WRAP_ACX1_DLA1("apu_sen_ac1_dla1"),
+	SLAVE_SENSOR_WRAP_ACX1_VPU0("apu_sen_ac1_vpu"),
+	SLAVE_REVISER("noc_cfg-0"),
+	SLAVE_NOC("noc_cfg-1"),
+	SLAVE_BCRM("infra_bcrm"),
+	SLAVE_DAPC_WRAP("infra_dapc_wrap"),
+	SLAVE_DAPC_CON("infra_dapc_con"),
+	SLAVE_NOC_DAPC_WRAP("noc_dapc_wrap"),
+	SLAVE_NOC_DAPC_CON("noc_dapc_con"),
+
+	/* ctrl index = 60 */
+	SLAVE_NOC_BCRM("noc_bcrm"),
+	SLAVE_ACS("apu_rcx_acs"),
+	SLAVE_HSE("apu_hse"),
+};
+
+static enum apusys_apc_err_status set_slave_ao_ctrl_apc(uint32_t slave,
+							enum apusys_apc_domain_id domain_id,
+							enum apusys_apc_perm_type perm)
+{
+	uint32_t apc_register_index;
+	uint32_t apc_set_index;
+	uint32_t base;
+	uint32_t clr_bit;
+	uint32_t set_bit;
+
+	if ((perm < 0) || (perm >= PERM_NUM)) {
+		ERROR(MODULE_TAG "%s: permission type:0x%x is not supported!\n", __func__, perm);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	if ((slave >= APU_CTRL_DAPC_AO_SLAVE_NUM) ||
+	    ((domain_id < 0) || (domain_id >= APU_CTRL_DAPC_AO_DOM_NUM))) {
+		ERROR(MODULE_TAG "%s: out of boundary, slave:0x%x, domain_id:0x%x\n",
+		      __func__, slave, domain_id);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	apc_register_index = slave / APU_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM;
+	apc_set_index = slave % APU_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM;
+
+	clr_bit = (DEVAPC_MASK << (apc_set_index * DEVAPC_DOM_SHIFT));
+	set_bit = (uint32_t)perm << (apc_set_index * DEVAPC_DOM_SHIFT);
+
+	base = (APU_CTRL_DAPC_AO_BASE + domain_id * DEVAPC_DOM_SIZE +
+		apc_register_index * DEVAPC_REG_SIZE);
+
+	mmio_clrsetbits_32(base, clr_bit, set_bit);
+	return APUSYS_APC_OK;
+}
+
+static enum apusys_apc_err_status set_slave_noc_dapc_rcx(uint32_t slave,
+							 enum apusys_apc_domain_id domain_id,
+							 enum apusys_apc_perm_type perm)
+{
+	uint32_t apc_register_index;
+	uint32_t apc_set_index;
+	uint32_t base;
+	uint32_t clr_bit;
+	uint32_t set_bit;
+
+	if ((perm >= PERM_NUM) || (perm < 0)) {
+		ERROR(MODULE_TAG "%s: permission type:0x%x is not supported!\n", __func__, perm);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	if ((slave >= APU_NOC_DAPC_RCX_SLAVE_NUM) ||
+	    ((domain_id < 0) || (domain_id >= APU_NOC_DAPC_RCX_DOM_NUM))) {
+		ERROR(MODULE_TAG "%s: out of boundary, slave:0x%x, domain_id:0x%x\n",
+		      __func__, slave, domain_id);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	apc_register_index = slave / APU_NOC_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
+	apc_set_index = slave % APU_NOC_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
+
+	clr_bit = (DEVAPC_MASK << (apc_set_index * DEVAPC_DOM_SHIFT));
+	set_bit = ((uint32_t)perm) << (apc_set_index * DEVAPC_DOM_SHIFT);
+	base = (APU_NOC_DAPC_RCX_BASE + domain_id * DEVAPC_DOM_SIZE +
+		apc_register_index * DEVAPC_REG_SIZE);
+
+	mmio_clrsetbits_32(base, clr_bit, set_bit);
+	return APUSYS_APC_OK;
+}
+
+static enum apusys_apc_err_status set_slave_rcx_ctrl_apc(uint32_t slave,
+							 enum apusys_apc_domain_id domain_id,
+							 enum apusys_apc_perm_type perm)
+{
+	uint32_t apc_register_index;
+	uint32_t apc_set_index;
+	uint32_t base;
+	uint32_t clr_bit;
+	uint32_t set_bit;
+
+	if ((perm < 0) || (perm >= PERM_NUM)) {
+		ERROR(MODULE_TAG "%s: permission type:0x%x is not supported!\n", __func__, perm);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	if ((slave >= APU_CTRL_DAPC_RCX_SLAVE_NUM) ||
+	    ((domain_id < 0) || (domain_id >= APU_CTRL_DAPC_RCX_DOM_NUM))) {
+		ERROR(MODULE_TAG "%s: out of boundary, slave:0x%x, domain_id:0x%x\n",
+		      __func__, slave, domain_id);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	apc_register_index = slave / APU_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
+	apc_set_index = slave % APU_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
+
+	clr_bit = (DEVAPC_MASK << (apc_set_index * DEVAPC_DOM_SHIFT));
+	set_bit = (uint32_t)perm << (apc_set_index * DEVAPC_DOM_SHIFT);
+	base = (APU_CTRL_DAPC_RCX_BASE + domain_id * DEVAPC_DOM_SIZE +
+		apc_register_index * DEVAPC_REG_SIZE);
+
+	mmio_clrsetbits_32(base, clr_bit, set_bit);
+	return APUSYS_APC_OK;
+}
+
+static void apusys_devapc_init(const char *name, uint32_t base)
+{
+	mmio_write_32(APUSYS_DAPC_CON(base), APUSYS_DAPC_CON_VIO_MASK);
+}
+
+int apusys_devapc_ao_init(void)
+{
+	enum apusys_apc_err_status ret;
+
+	apusys_devapc_init("APUAPC_CTRL_AO", APU_CTRL_DAPC_AO_BASE);
+
+	ret = SET_APUSYS_DAPC_V1(APU_CTRL_DAPC_AO, set_slave_ao_ctrl_apc);
+	if (ret != APUSYS_APC_OK) {
+		ERROR(MODULE_TAG "%s: set_apusys_ao_ctrl_dap FAILED!\n", __func__);
+		return -1;
+	}
+
+#if DUMP_APUSYS_DAPC
+	DUMP_APUSYS_DAPC_V1(APU_CTRL_DAPC_AO);
+#endif
+
+	return 0;
+}
+
+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);
+
+	ret = SET_APUSYS_DAPC_V1(APU_CTRL_DAPC_RCX, set_slave_rcx_ctrl_apc);
+	if (ret != APUSYS_APC_OK) {
+		ERROR(MODULE_TAG "%s: set_slave_rcx_ctrl_apc FAILED!\n", __func__);
+		return -1;
+	}
+
+#if DUMP_APUSYS_DAPC
+	DUMP_APUSYS_DAPC_V1(APU_CTRL_DAPC_RCX);
+#endif
+
+	ret = SET_APUSYS_DAPC_V1(APU_NOC_DAPC_RCX, set_slave_noc_dapc_rcx);
+	if (ret != APUSYS_APC_OK) {
+		ERROR(MODULE_TAG "%s: set_slave_noc_dapc_rcx FAILED\n", __func__);
+		return -1;
+	}
+
+#if DUMP_APUSYS_DAPC
+	DUMP_APUSYS_DAPC_V1(APU_NOC_DAPC_RCX);
+#endif
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h
new file mode 100644
index 0000000..de76459
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DEVAPC_H
+#define APUSYS_DEVAPC_H
+
+int apusys_devapc_ao_init(void);
+int apusys_devapc_rcx_init(void);
+
+#endif /* APUSYS_DEVAPC_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h
new file mode 100644
index 0000000..e74b022
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DEVAPC_DEF_H
+#define APUSYS_DEVAPC_DEF_H
+
+#include <lib/mmio.h>
+#include "../devapc/apusys_dapc_v1.h"
+
+/* NoC */
+#define SLAVE_MD32_SRAM			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+
+/* Control */
+#define SLAVE_VCORE			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_RPC			SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT
+#define SLAVE_PCU			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_AO_CTRL			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_PLL			SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT
+#define SLAVE_ACC			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_SEC			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_ARE0			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_ARE1			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_ARE2			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_UNKNOWN			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_APU_BULK			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_AO_BCRM			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_AO_DAPC_WRAP		SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_AO_DAPC_CON		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_RCX_ACX_BULK		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_ACX0_BCRM			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_RPCTOP_LITE_ACX0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_ACX1_BCRM			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_RPCTOP_LITE_ACX1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_RCX_TO_ACX0_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_RCX_TO_ACX0_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_SAE_TO_ACX0_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_SAE_TO_ACX0_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_RCX_TO_ACX1_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_RCX_TO_ACX1_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_SAE_TO_ACX1_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_SAE_TO_ACX1_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_MD32_SYSCTRL0		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_MD32_SYSCTRL1		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT
+#define SLAVE_MD32_WDT			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_MD32_CACHE		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_NOC_AXI			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_MD32_DBG			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_DBG_CRTL			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU0_BANK0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_IOMMU0_BANK1		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU0_BANK2		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU0_BANK3		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU0_BANK4		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU1_BANK0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_IOMMU1_BANK1		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU1_BANK2		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU1_BANK3		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_IOMMU1_BANK4		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_S0_SSC			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_N0_SSC			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_ACP_SSC			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_S1_SSC			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_N1_SSC			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_CFG			SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT
+#define SLAVE_SEMA_STIMER		SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_EMI_CFG			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_LOG			SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT
+#define SLAVE_CPE_SENSOR		SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_CPE_COEF			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_CPE_CTRL			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_DFD_REG_SOC		SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_SENSOR_WRAP_ACX0_DLA0	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_SENSOR_WRAP_ACX0_DLA1	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_SENSOR_WRAP_ACX0_VPU0	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_SENSOR_WRAP_ACX1_DLA0	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_SENSOR_WRAP_ACX1_DLA1	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_SENSOR_WRAP_ACX1_VPU0	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_REVISER			SLAVE_FORBID_EXCEPT_D0_SEC_RW
+#define SLAVE_NOC			SLAVE_FORBID_EXCEPT_D0_D3_SEC_RW_D5_NO_PROTECT
+#define SLAVE_BCRM			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_DAPC_WRAP			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_DAPC_CON			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_NOC_DAPC_WRAP		SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_NOC_DAPC_CON		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_NOC_BCRM			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+#define SLAVE_ACS			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
+#define SLAVE_HSE			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
+
+
+/* Power Domain: AO */
+#define APU_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM	(16)
+#define APU_CTRL_DAPC_AO_DOM_NUM		(16)
+#define APU_CTRL_DAPC_AO_SLAVE_NUM		(30)
+#define DEVAPC_MASK				(0x3U)
+#define DEVAPC_DOM_SHIFT			(2)
+
+/* Power Domain: RCX */
+#define APU_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM	(16)
+#define APU_CTRL_DAPC_RCX_DOM_NUM		(16)
+#define APU_CTRL_DAPC_RCX_SLAVE_NUM		(63)
+
+#define APU_NOC_DAPC_RCX_SLAVE_NUM_IN_1_DOM	(16)
+#define APU_NOC_DAPC_RCX_DOM_NUM		(16)
+#define APU_NOC_DAPC_RCX_SLAVE_NUM		(5)
+
+#endif /* APUSYS_DEVAPC_DEF_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
index ac62f2f..cdfc133 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
@@ -17,6 +17,7 @@
 /* Vendor header */
 #include "apusys.h"
 #include "apusys_power.h"
+#include "apusys_rv.h"
 #include <mtk_mmap_pool.h>
 
 static spinlock_t apu_lock;
@@ -47,6 +48,43 @@
 	return -1;
 }
 
+static void apu_backup_restore(enum APU_BACKUP_RESTORE_CTRL ctrl)
+{
+	int i;
+	static struct apu_restore_data apu_restore_data[] = {
+		{ UP_NORMAL_DOMAIN_NS, 0 },
+		{ UP_PRI_DOMAIN_NS, 0 },
+		{ UP_IOMMU_CTRL, 0 },
+		{ UP_CORE0_VABASE0, 0 },
+		{ UP_CORE0_MVABASE0, 0 },
+		{ UP_CORE0_VABASE1, 0 },
+		{ UP_CORE0_MVABASE1, 0 },
+		{ UP_CORE0_VABASE2, 0 },
+		{ UP_CORE0_MVABASE2, 0 },
+		{ UP_CORE0_VABASE3, 0 },
+		{ UP_CORE0_MVABASE3, 0 },
+		{ MD32_SYS_CTRL, 0 },
+		{ MD32_CLK_CTRL, 0 },
+		{ UP_WAKE_HOST_MASK0, 0 }
+	};
+
+	switch (ctrl) {
+	case APU_CTRL_BACKUP:
+		for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) {
+			apu_restore_data[i].data = mmio_read_32(apu_restore_data[i].reg);
+		}
+		break;
+	case APU_CTRL_RESTORE:
+		for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) {
+			mmio_write_32(apu_restore_data[i].reg, apu_restore_data[i].data);
+		}
+		break;
+	default:
+		ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, ctrl);
+		break;
+	}
+}
+
 static void apu_xpu2apusys_d4_slv_en(enum APU_D4_SLV_CTRL en)
 {
 	switch (en) {
@@ -120,6 +158,8 @@
 
 	apu_xpu2apusys_d4_slv_en(D4_SLV_OFF);
 
+	apu_backup_restore(APU_CTRL_RESTORE);
+
 	apusys_top_on = true;
 
 	spin_unlock(&apu_lock);
@@ -153,6 +193,8 @@
 		return 0;
 	}
 
+	apu_backup_restore(APU_CTRL_BACKUP);
+
 	apu_xpu2apusys_d4_slv_en(D4_SLV_ON);
 
 	if (mmio_read_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG) == 0) {
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
index b4968d6..460cc50 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
@@ -29,6 +29,16 @@
 	D4_SLV_ON,
 };
 
+enum APU_BACKUP_RESTORE_CTRL {
+	APU_CTRL_BACKUP		= 0,
+	APU_CTRL_RESTORE	= 1,
+};
+
+struct apu_restore_data {
+	uint32_t reg;
+	uint32_t data;
+};
+
 #define APU_POLL_STEP_US			(5)
 
 #define OUT_CLK_FREQ_MIN			(1500)
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
new file mode 100644
index 0000000..86bebe5
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TF-A system header */
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+/* Vendor header */
+#include "apusys_security_ctrl_plat.h"
+
+static void apusys_domain_remap_init(void)
+{
+	const uint32_t remap_domains[] = {
+		D0_REMAP_DOMAIN,  D1_REMAP_DOMAIN,  D2_REMAP_DOMAIN,  D3_REMAP_DOMAIN,
+		D4_REMAP_DOMAIN,  D5_REMAP_DOMAIN,  D6_REMAP_DOMAIN,  D7_REMAP_DOMAIN,
+		D8_REMAP_DOMAIN,  D9_REMAP_DOMAIN,  D10_REMAP_DOMAIN, D11_REMAP_DOMAIN,
+		D12_REMAP_DOMAIN, D13_REMAP_DOMAIN, D14_REMAP_DOMAIN, D15_REMAP_DOMAIN
+	};
+	uint32_t lower_domain = 0;
+	uint32_t higher_domain = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(remap_domains); i++) {
+		if (i < REG_DOMAIN_NUM) {
+			lower_domain |= (remap_domains[i] << (i * REG_DOMAIN_BITS));
+		} else {
+			higher_domain |= (remap_domains[i] <<
+					  ((i - REG_DOMAIN_NUM) * REG_DOMAIN_BITS));
+		}
+	}
+
+	mmio_write_32(SOC2APU_SET1_0, lower_domain);
+	mmio_write_32(SOC2APU_SET1_1, higher_domain);
+	mmio_setbits_32(APU_SEC_CON, DOMAIN_REMAP_SEL);
+}
+
+void apusys_security_ctrl_init(void)
+{
+	apusys_domain_remap_init();
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
new file mode 100644
index 0000000..f9181ae
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_SECURITY_CTRL_PLAT_H
+#define APUSYS_SECURITY_CTRL_PLAT_H
+
+#include <platform_def.h>
+
+#define SOC2APU_SET1_0	(APU_SEC_CON + 0x0c)
+#define SOC2APU_SET1_1	(APU_SEC_CON + 0x10)
+
+#define REG_DOMAIN_NUM		(8)
+#define REG_DOMAIN_BITS		(4)
+#define DOMAIN_REMAP_SEL	BIT(6)
+
+#define D0_REMAP_DOMAIN		(0)
+#define D1_REMAP_DOMAIN		(1)
+#define D2_REMAP_DOMAIN		(2)
+#define D3_REMAP_DOMAIN		(3)
+#define D4_REMAP_DOMAIN		(4)
+#define D5_REMAP_DOMAIN		(14)
+#define D6_REMAP_DOMAIN		(6)
+#define D7_REMAP_DOMAIN		(14)
+#define D8_REMAP_DOMAIN		(8)
+#define D9_REMAP_DOMAIN		(9)
+#define D10_REMAP_DOMAIN	(10)
+#define D11_REMAP_DOMAIN	(11)
+#define D12_REMAP_DOMAIN	(12)
+#define D13_REMAP_DOMAIN	(13)
+#define D14_REMAP_DOMAIN	(14)
+#define D15_REMAP_DOMAIN	(15)
+
+void apusys_security_ctrl_init(void);
+
+#endif /* APUSYS_SECURITY_CTRL_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/rules.mk b/plat/mediatek/drivers/apusys/mt8188/rules.mk
index f676b6e..c358067 100644
--- a/plat/mediatek/drivers/apusys/mt8188/rules.mk
+++ b/plat/mediatek/drivers/apusys/mt8188/rules.mk
@@ -8,6 +8,8 @@
 
 MODULE := apusys_${MTK_SOC}
 
-LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_power.c
+LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_devapc.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_plat.c
 
 $(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk
index 1aa67bc..498925c 100644
--- a/plat/mediatek/drivers/apusys/rules.mk
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -10,10 +10,12 @@
 
 LOCAL_SRCS-y:= ${LOCAL_DIR}/apusys.c
 
-PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC}
+PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC} -I${LOCAL_DIR}/apusys_rv/2.0
 
 $(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
 
 SUB_RULES-y := ${LOCAL_DIR}/${MTK_SOC}
+SUB_RULES-y += ${LOCAL_DIR}/devapc
+SUB_RULES-y += ${LOCAL_DIR}/apusys_rv/2.0
 
 $(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
index 66a369e..9c1ebb5 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -60,5 +60,6 @@
 int emi_mpu_init(void);
 int emi_mpu_set_protection(struct emi_region_info_t *region_info);
 void set_emi_mpu_regions(void);
+int set_apu_emi_mpu_region(void);
 
 #endif
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index 558533d..59ab315 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,3 +12,20 @@
 	/* TODO: set emi mpu region */
 	INFO("%s, emi mpu is not setting currently\n", __func__);
 }
+
+int set_apu_emi_mpu_region(void)
+{
+	struct emi_region_info_t region_info;
+
+	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;
+
+	SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
+			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
+			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
+			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, FORBIDDEN,
+			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     SEC_RW);
+
+	return emi_mpu_set_protection(&region_info);
+}
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 1ee7397..cc7f7f1 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,4 +42,9 @@
 
 #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)
+
 #endif
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index fc9725e..0a7ae6d 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -28,17 +28,25 @@
  * APUSYS related constants
  ******************************************************************************/
 #define BCRM_FMEM_PDN_BASE	(IO_PHYS + 0x00276000)
+#define APU_MD32_SYSCTRL	(IO_PHYS + 0x09001000)
+#define APU_MD32_WDT		(IO_PHYS + 0x09002000)
 #define APU_RCX_CONFIG		(IO_PHYS + 0x09020000)
+#define APU_CTRL_DAPC_RCX_BASE	(IO_PHYS + 0x09034000)
+#define APU_NOC_DAPC_RCX_BASE	(IO_PHYS + 0x09038000)
+#define APU_REVISER		(IO_PHYS + 0x0903c000)
 #define APU_RCX_VCORE_CONFIG	(IO_PHYS + 0x090e0000)
 #define APU_MBOX0		(IO_PHYS + 0x090e1000)
+#define APU_MBOX1		(IO_PHYS + 0x090e2000)
 #define APU_RPCTOP		(IO_PHYS + 0x090f0000)
 #define APU_PCUTOP		(IO_PHYS + 0x090f1000)
 #define APU_AO_CTRL		(IO_PHYS + 0x090f2000)
 #define APU_PLL			(IO_PHYS + 0x090f3000)
 #define APU_ACC			(IO_PHYS + 0x090f4000)
+#define APU_SEC_CON		(IO_PHYS + 0x090f5000)
 #define APU_ARETOP_ARE0		(IO_PHYS + 0x090f6000)
 #define APU_ARETOP_ARE1		(IO_PHYS + 0x090f7000)
 #define APU_ARETOP_ARE2		(IO_PHYS + 0x090f8000)
+#define APU_CTRL_DAPC_AO_BASE	(IO_PHYS + 0x090fc000)
 #define APU_ACX0_RPC_LITE	(IO_PHYS + 0x09140000)
 #define BCRM_FMEM_PDN_SIZE	(0x1000)
 
@@ -193,7 +201,7 @@
  * Platform memory map related constants
  ******************************************************************************/
 #define TZRAM_BASE			(0x54600000)
-#define TZRAM_SIZE			(0x00030000)
+#define TZRAM_SIZE			(0x00040000)
 
 /*******************************************************************************
  * BL31 specific defines.
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 0b84e96..f309efd 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -55,6 +55,11 @@
 	/* Initialize the console to provide early debug support */
 	qemu_console_init();
 
+/* Platform names have to be lowercase. */
+#ifdef PLAT_qemu_sbsa
+	sip_svc_init();
+#endif
+
 	/*
 	 * Check params passed from BL2
 	 */
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 199ca01..e80a88d 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,9 @@
 const mmap_region_t *plat_qemu_get_mmap(void);
 
 void qemu_console_init(void);
+#ifdef PLAT_qemu_sbsa
+void sip_svc_init(void);
+#endif
 
 void plat_qemu_gic_init(void);
 void qemu_pwr_gic_on_finish(void);
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index 85fbb4d..deaf16e 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -215,6 +215,8 @@
 /*
  * GIC related constants
  * We use GICv3 where CPU Interface registers are not memory mapped
+ *
+ * Legacy values - on platform version 0.1+ they are read from DT
  */
 #define GICD_BASE			0x40060000
 #define GICR_BASE			0x40080000
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 8b8d76b..60d6b7e 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2021, Linaro Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, Linaro Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -89,14 +89,15 @@
 include drivers/arm/gic/v3/gicv3.mk
 
 QEMU_GIC_SOURCES	:=	${GICV3_SOURCES}				\
-				plat/common/plat_gicv3.c			\
-				${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c
+				plat/common/plat_gicv3.c
 
 BL31_SOURCES		+=	${QEMU_CPU_LIBS}				\
 				lib/semihosting/semihosting.c			\
 				lib/semihosting/${ARCH}/semihosting_call.S	\
 				plat/common/plat_psci_common.c			\
+				${PLAT_QEMU_PATH}/sbsa_gic.c 			\
 				${PLAT_QEMU_PATH}/sbsa_pm.c			\
+				${PLAT_QEMU_PATH}/sbsa_sip_svc.c		\
 				${PLAT_QEMU_PATH}/sbsa_topology.c		\
 				${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S	\
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c	\
diff --git a/plat/qemu/qemu_sbsa/sbsa_gic.c b/plat/qemu/qemu_sbsa/sbsa_gic.c
new file mode 100644
index 0000000..962dbb3
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_gic.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/gicv3.h>
+#include <plat/common/platform.h>
+
+static const interrupt_prop_t qemu_interrupt_props[] = {
+	PLATFORM_G1S_PROPS(INTR_GROUP1S),
+	PLATFORM_G0_PROPS(INTR_GROUP0)
+};
+
+static uintptr_t qemu_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static unsigned int qemu_mpidr_to_core_pos(unsigned long mpidr)
+{
+	return plat_core_pos_by_mpidr(mpidr);
+}
+
+static gicv3_driver_data_t sbsa_gic_driver_data = {
+	/* we set those two values for compatibility with older QEMU */
+	.gicd_base = GICD_BASE,
+	.gicr_base = GICR_BASE,
+	.interrupt_props = qemu_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(qemu_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = qemu_rdistif_base_addrs,
+	.mpidr_to_core_pos = qemu_mpidr_to_core_pos
+};
+
+void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base)
+{
+	sbsa_gic_driver_data.gicd_base = gicd_base;
+	sbsa_gic_driver_data.gicr_base = gicr_base;
+}
+
+uintptr_t sbsa_get_gicd(void)
+{
+	return sbsa_gic_driver_data.gicd_base;
+}
+
+uintptr_t sbsa_get_gicr(void)
+{
+	return sbsa_gic_driver_data.gicr_base;
+}
+
+void plat_qemu_gic_init(void)
+{
+	gicv3_driver_init(&sbsa_gic_driver_data);
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void qemu_pwr_gic_on_finish(void)
+{
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void qemu_pwr_gic_off(void)
+{
+	gicv3_cpuif_disable(plat_my_core_pos());
+	gicv3_rdistif_off(plat_my_core_pos());
+}
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
new file mode 100644
index 0000000..37460d7
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/fdt_wrappers.h>
+#include <common/runtime_svc.h>
+#include <libfdt.h>
+#include <smccc_helpers.h>
+
+/* default platform version is 0.0 */
+static int platform_version_major;
+static int platform_version_minor;
+
+#define SMC_FASTCALL       0x80000000
+#define SMC64_FUNCTION     (SMC_FASTCALL   | 0x40000000)
+#define SIP_FUNCTION       (SMC64_FUNCTION | 0x02000000)
+#define SIP_FUNCTION_ID(n) (SIP_FUNCTION   | (n))
+
+/*
+ * We do not use SMCCC_ARCH_SOC_ID here because qemu_sbsa is virtual platform
+ * which uses SoC present in QEMU. And they can change on their own while we
+ * need version of whole 'virtual hardware platform'.
+ */
+#define SIP_SVC_VERSION  SIP_FUNCTION_ID(1)
+
+#define SIP_SVC_GET_GIC  SIP_FUNCTION_ID(100)
+
+void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
+uintptr_t sbsa_get_gicd(void);
+uintptr_t sbsa_get_gicr(void);
+
+void read_platform_config_from_dt(void *dtb)
+{
+	int node;
+	const fdt64_t *data;
+	int err;
+	uintptr_t gicd_base;
+	uintptr_t gicr_base;
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 *
+	 * intc {
+		reg = < 0x00 0x40060000 0x00 0x10000
+			0x00 0x40080000 0x00 0x4000000>;
+	};
+	 */
+	node = fdt_path_offset(dtb, "/intc");
+	if (node < 0) {
+		return;
+	}
+
+	data = fdt_getprop(dtb, node, "reg", NULL);
+	if (data == NULL) {
+		return;
+	}
+
+	err = fdt_get_reg_props_by_index(dtb, node, 0, &gicd_base, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICD reg property of GIC node\n");
+		return;
+	}
+	INFO("GICD base = 0x%lx\n", gicd_base);
+
+	err = fdt_get_reg_props_by_index(dtb, node, 1, &gicr_base, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICR reg property of GIC node\n");
+		return;
+	}
+	INFO("GICR base = 0x%lx\n", gicr_base);
+
+	sbsa_set_gic_bases(gicd_base, gicr_base);
+}
+
+void read_platform_version(void *dtb)
+{
+	int node;
+
+	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));
+	}
+}
+
+void sip_svc_init(void)
+{
+	/* Read DeviceTree data before MMU is enabled */
+
+	void *dtb = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
+	int err;
+
+	err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
+	if (err < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
+		return;
+	}
+
+	err = fdt_check_header(dtb);
+	if (err < 0) {
+		ERROR("Invalid DTB file passed\n");
+		return;
+	}
+
+	read_platform_version(dtb);
+	INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
+
+	read_platform_config_from_dt(dtb);
+}
+
+/*
+ * This function is responsible for handling all SiP calls from the NS world
+ */
+uintptr_t sbsa_sip_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)
+{
+	uint32_t ns;
+
+	/* Determine which security state this SMC originated from */
+	ns = is_caller_non_secure(flags);
+	if (!ns) {
+		ERROR("%s: wrong world SMC (0x%x)\n", __func__, smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
+	switch (smc_fid) {
+	case SIP_SVC_VERSION:
+		INFO("Platform version requested\n");
+		SMC_RET3(handle, NULL, platform_version_major, platform_version_minor);
+
+	case SIP_SVC_GET_GIC:
+		SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr());
+
+	default:
+		ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
+		      smc_fid - SIP_FUNCTION);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+int sbsa_sip_smc_setup(void)
+{
+	return 0;
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	sbsa_sip_svc,
+	OEN_SIP_START,
+	OEN_SIP_END,
+	SMC_TYPE_FAST,
+	sbsa_sip_smc_setup,
+	sbsa_sip_smc_handler
+);
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 1405ca6..487a56e 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -191,18 +191,6 @@
 	}
 }
 
-#if PSCI_OS_INIT_MODE
-static int qti_node_suspend(const psci_power_state_t *target_state)
-{
-	qtiseclib_psci_node_suspend((const uint8_t *)target_state->
-				    pwr_domain_state);
-	if (is_cpu_off(target_state)) {
-		plat_qti_gic_cpuif_disable();
-		qti_set_cpupwrctlr_val();
-	}
-	return PSCI_E_SUCCESS;
-}
-#else
 static void qti_node_suspend(const psci_power_state_t *target_state)
 {
 	qtiseclib_psci_node_suspend((const uint8_t *)target_state->
@@ -212,7 +200,6 @@
 		qti_set_cpupwrctlr_val();
 	}
 }
-#endif
 
 static void qti_node_suspend_finish(const psci_power_state_t *target_state)
 {
diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c
index d004dcf..e4a5338 100644
--- a/plat/st/common/stm32cubeprogrammer_uart.c
+++ b/plat/st/common/stm32cubeprogrammer_uart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -481,6 +481,8 @@
 		}
 	}
 
+	stm32_uart_flush(&handle.uart);
+
 	return 0;
 }
 
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 8cac4b5..df5593a 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -647,11 +647,12 @@
 /*******************************************************************************
  * Device Tree defines
  ******************************************************************************/
-#define DT_BSEC_COMPAT			"st,stm32mp15-bsec"
 #if STM32MP13
+#define DT_BSEC_COMPAT			"st,stm32mp13-bsec"
 #define DT_DDR_COMPAT			"st,stm32mp13-ddr"
 #endif
 #if STM32MP15
+#define DT_BSEC_COMPAT			"st,stm32mp15-bsec"
 #define DT_DDR_COMPAT			"st,stm32mp1-ddr"
 #endif
 #define DT_IWDG_COMPAT			"st,stm32mp1-iwdg"
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index 8e1c1cf..ff2218f 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -161,17 +161,15 @@
 static int stm32_validate_power_state(unsigned int power_state,
 				      psci_power_state_t *req_state)
 {
-	int pstate = psci_get_pstate_type(power_state);
-
-	if (pstate != 0) {
+	if (psci_get_pstate_type(power_state) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
-	if (psci_get_pstate_pwrlvl(power_state)) {
+	if (psci_get_pstate_pwrlvl(power_state) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
-	if (psci_get_pstate_id(power_state)) {
+	if (psci_get_pstate_id(power_state) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index ed3946f..d1c5303 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -26,18 +26,18 @@
 	uint64_t flags;
 };
 
-/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */
-struct xfsbl_atf_handoff_params {
+/* Structure for handoff parameters to TrustedFirmware-A (TF-A) */
+struct xfsbl_tfa_handoff_params {
 	uint8_t magic[4];
 	uint32_t num_entries;
 	struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
 };
 
-#define ATF_HANDOFF_PARAMS_MAX_SIZE	sizeof(struct xfsbl_atf_handoff_params)
+#define TFA_HANDOFF_PARAMS_MAX_SIZE	sizeof(struct xfsbl_tfa_handoff_params)
 
-enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32,
+enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
-					uint64_t atf_handoff_addr);
+					uint64_t tfa_handoff_addr);
 
 /* JEDEC Standard Manufacturer's Identification Code and Bank ID JEP106 */
 #define JEDEC_XILINX_MFID	U(0x49)
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 539aba2..007c045 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +15,7 @@
 
 
 /*
- * ATFHandoffParams
+ * TFAHandoffParams
  * Parameter		bitfield	encoding
  * -----------------------------------------------------------------------------
  * Exec State		0		0 -> Aarch64, 1-> Aarch32
@@ -133,7 +134,7 @@
  * Populates the bl32 and bl33 image info structures
  * @bl32:	BL32 image info structure
  * @bl33:	BL33 image info structure
- * atf_handoff_addr:  ATF handoff address
+ * tfa_handoff_addr:  TF-A handoff address
  *
  * Process the handoff parameters from the FSBL and populate the BL32 and BL33
  * image info structures accordingly.
@@ -141,31 +142,31 @@
  * Return: Return the status of the handoff. The value will be from the
  *         fsbl_handoff enum.
  */
-enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32,
+enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
-					uint64_t atf_handoff_addr)
+					uint64_t tfa_handoff_addr)
 {
-	const struct xfsbl_atf_handoff_params *ATFHandoffParams;
-	if (!atf_handoff_addr) {
-		WARN("BL31: No ATF handoff structure passed\n");
+	const struct xfsbl_tfa_handoff_params *TFAHandoffParams;
+	if (!tfa_handoff_addr) {
+		WARN("BL31: No TFA handoff structure passed\n");
 		return FSBL_HANDOFF_NO_STRUCT;
 	}
 
-	ATFHandoffParams = (struct xfsbl_atf_handoff_params *)atf_handoff_addr;
-	if ((ATFHandoffParams->magic[0] != 'X') ||
-	    (ATFHandoffParams->magic[1] != 'L') ||
-	    (ATFHandoffParams->magic[2] != 'N') ||
-	    (ATFHandoffParams->magic[3] != 'X')) {
-		ERROR("BL31: invalid ATF handoff structure at %" PRIx64 "\n",
-		      atf_handoff_addr);
+	TFAHandoffParams = (struct xfsbl_tfa_handoff_params *)tfa_handoff_addr;
+	if ((TFAHandoffParams->magic[0] != 'X') ||
+	    (TFAHandoffParams->magic[1] != 'L') ||
+	    (TFAHandoffParams->magic[2] != 'N') ||
+	    (TFAHandoffParams->magic[3] != 'X')) {
+		ERROR("BL31: invalid TF-A handoff structure at %" PRIx64 "\n",
+		      tfa_handoff_addr);
 		return FSBL_HANDOFF_INVAL_STRUCT;
 	}
 
-	VERBOSE("BL31: ATF handoff params at:0x%" PRIx64 ", entries:%u\n",
-		atf_handoff_addr, ATFHandoffParams->num_entries);
-	if (ATFHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
-		ERROR("BL31: ATF handoff params: too many partitions (%u/%u)\n",
-		      ATFHandoffParams->num_entries, FSBL_MAX_PARTITIONS);
+	VERBOSE("BL31: TF-A handoff params at:0x%" PRIx64 ", entries:%u\n",
+		tfa_handoff_addr, TFAHandoffParams->num_entries);
+	if (TFAHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
+		ERROR("BL31: TF-A handoff params: too many partitions (%u/%u)\n",
+		      TFAHandoffParams->num_entries, FSBL_MAX_PARTITIONS);
 		return FSBL_HANDOFF_TOO_MANY_PARTS;
 	}
 
@@ -174,29 +175,29 @@
 	 * (bl32, bl33). I.e. the last applicable images in the handoff
 	 * structure will be used for the hand off
 	 */
-	for (size_t i = 0; i < ATFHandoffParams->num_entries; i++) {
+	for (size_t i = 0; i < TFAHandoffParams->num_entries; i++) {
 		entry_point_info_t *image;
 		int32_t target_estate, target_secure, target_cpu;
 		uint32_t target_endianness, target_el;
 
 		VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
-			ATFHandoffParams->partition[i].entry_point,
-			ATFHandoffParams->partition[i].flags);
+			TFAHandoffParams->partition[i].entry_point,
+			TFAHandoffParams->partition[i].flags);
 
-		target_cpu = get_fsbl_cpu(&ATFHandoffParams->partition[i]);
+		target_cpu = get_fsbl_cpu(&TFAHandoffParams->partition[i]);
 		if (target_cpu != FSBL_FLAGS_A53_0) {
 			WARN("BL31: invalid target CPU (%i)\n", target_cpu);
 			continue;
 		}
 
-		target_el = get_fsbl_el(&ATFHandoffParams->partition[i]);
+		target_el = get_fsbl_el(&TFAHandoffParams->partition[i]);
 		if ((target_el == FSBL_FLAGS_EL3) ||
 		    (target_el == FSBL_FLAGS_EL0)) {
 			WARN("BL31: invalid exception level (%i)\n", target_el);
 			continue;
 		}
 
-		target_secure = get_fsbl_ss(&ATFHandoffParams->partition[i]);
+		target_secure = get_fsbl_ss(&TFAHandoffParams->partition[i]);
 		if (target_secure == FSBL_FLAGS_SECURE &&
 		    target_el == FSBL_FLAGS_EL2) {
 			WARN("BL31: invalid security state (%i) for exception level (%i)\n",
@@ -204,8 +205,8 @@
 			continue;
 		}
 
-		target_estate = get_fsbl_estate(&ATFHandoffParams->partition[i]);
-		target_endianness = get_fsbl_endian(&ATFHandoffParams->partition[i]);
+		target_estate = get_fsbl_estate(&TFAHandoffParams->partition[i]);
+		target_endianness = get_fsbl_endian(&TFAHandoffParams->partition[i]);
 
 		if (target_secure == FSBL_FLAGS_SECURE) {
 			image = bl32;
@@ -245,9 +246,9 @@
 
 		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
 			target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
-			ATFHandoffParams->partition[i].entry_point,
+			TFAHandoffParams->partition[i].entry_point,
 			target_el);
-		image->pc = ATFHandoffParams->partition[i].entry_point;
+		image->pc = TFAHandoffParams->partition[i].entry_point;
 
 		if (target_endianness == SPSR_E_BIG) {
 			EP_SET_EE(image->h.attr, EP_EE_BIG);
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 2f47cca..dcdd2dc 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -572,7 +572,7 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 	uint32_t module_id;
 
-	/* Return version of API which are implemented in ATF only */
+	/* Return version of API which are implemented in TF-A only */
 	switch (api_id) {
 	case PM_GET_CALLBACK_DATA:
 	case PM_GET_TRUSTZONE_VERSION:
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 54ebc22..e5e095a 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -67,10 +67,10 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	uint64_t atf_handoff_addr;
-	uint32_t payload[PAYLOAD_ARG_CNT], max_size = ATF_HANDOFF_PARAMS_MAX_SIZE;
+	uint64_t tfa_handoff_addr;
+	uint32_t payload[PAYLOAD_ARG_CNT], max_size = TFA_HANDOFF_PARAMS_MAX_SIZE;
 	enum pm_ret_status ret_status;
-	uint64_t addr[ATF_HANDOFF_PARAMS_MAX_SIZE];
+	uint64_t addr[TFA_HANDOFF_PARAMS_MAX_SIZE];
 
 	if (VERSAL_CONSOLE_IS(pl011) || (VERSAL_CONSOLE_IS(pl011_1))) {
 		static console_t versal_runtime_console;
@@ -119,15 +119,15 @@
 	ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 	if (ret_status == PM_RET_SUCCESS) {
 		INFO("BL31: GET_HANDOFF_PARAMS call success=%d\n", ret_status);
-		atf_handoff_addr = (uintptr_t)&addr;
+		tfa_handoff_addr = (uintptr_t)&addr;
 	} else {
-		ERROR("BL31: GET_HANDOFF_PARAMS Failed, read atf_handoff_addr from reg\n");
-		atf_handoff_addr = mmio_read_32(PMC_GLOBAL_GLOB_GEN_STORAGE4);
+		ERROR("BL31: GET_HANDOFF_PARAMS Failed, read tfa_handoff_addr from reg\n");
+		tfa_handoff_addr = mmio_read_32(PMC_GLOBAL_GLOB_GEN_STORAGE4);
 	}
 
-	enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info,
+	enum fsbl_handoff ret = fsbl_tfa_handover(&bl32_image_ep_info,
 						  &bl33_image_ep_info,
-						  atf_handoff_addr);
+						  tfa_handoff_addr);
 	if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) {
 		bl31_set_default_config();
 	} else if (ret == FSBL_HANDOFF_TOO_MANY_PARTS) {
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 81a5445..af5263d 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -121,6 +121,48 @@
 	case 57:
 		dev_idx = XPM_NODEIDX_DEV_GEM_0;
 		break;
+	case 58:
+	case 59:
+		dev_idx = XPM_NODEIDX_DEV_GEM_1;
+		break;
+	case 60:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_0;
+		break;
+	case 61:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_1;
+		break;
+	case 62:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_2;
+		break;
+	case 63:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_3;
+		break;
+	case 64:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_4;
+		break;
+	case 65:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_5;
+		break;
+	case 66:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_6;
+		break;
+	case 67:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_7;
+		break;
+	case 74:
+		dev_idx = XPM_NODEIDX_DEV_USB_0;
+		break;
+	case 126:
+	case 127:
+		dev_idx = XPM_NODEIDX_DEV_SDIO_0;
+		break;
+	case 128:
+	case 129:
+		dev_idx = XPM_NODEIDX_DEV_SDIO_1;
+		break;
+	case 142:
+		dev_idx = XPM_NODEIDX_DEV_RTC;
+		break;
 	default:
 		dev_idx = XPM_NODEIDX_DEV_MIN;
 		break;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 2197b96..b00513e 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -71,7 +71,7 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	uint64_t atf_handoff_addr;
+	uint64_t tfa_handoff_addr;
 
 	if (ZYNQMP_CONSOLE_IS(cadence) || (ZYNQMP_CONSOLE_IS(cadence1))) {
 		/* Register the console to provide early debug support */
@@ -107,15 +107,15 @@
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
-	atf_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
+	tfa_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
 
 	if (zynqmp_get_bootmode() == ZYNQMP_BOOTMODE_JTAG) {
 		bl31_set_default_config();
 	} else {
 		/* use parameters from FSBL */
-		enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info,
+		enum fsbl_handoff ret = fsbl_tfa_handover(&bl32_image_ep_info,
 							  &bl33_image_ep_info,
-							  atf_handoff_addr);
+							  tfa_handoff_addr);
 		if (ret != FSBL_HANDOFF_SUCCESS) {
 			panic();
 		}
@@ -212,7 +212,7 @@
 
 	/* Reserve memory used by Trusted Firmware. */
 	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE,
-				    BL31_LIMIT - BL31_BASE + 1)) {
+				   (size_t) (BL31_LIMIT - BL31_BASE))) {
 		WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
 	}
 
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index f6d9ce1..0c83a56 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -47,10 +47,10 @@
 # define BL31_LIMIT			U(0x80000)
 #endif
 #else
-# define BL31_BASE			(ZYNQMP_ATF_MEM_BASE)
-# define BL31_LIMIT			(ZYNQMP_ATF_MEM_BASE + ZYNQMP_ATF_MEM_SIZE)
+# define BL31_BASE			U(ZYNQMP_ATF_MEM_BASE)
+# define BL31_LIMIT			(UL(ZYNQMP_ATF_MEM_BASE) + U(ZYNQMP_ATF_MEM_SIZE))
 # ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
-#  define BL31_PROGBITS_LIMIT		(ZYNQMP_ATF_MEM_BASE + ZYNQMP_ATF_MEM_PROGBITS_SIZE)
+#  define BL31_PROGBITS_LIMIT		(UL(ZYNQMP_ATF_MEM_BASE) + U(ZYNQMP_ATF_MEM_PROGBITS_SIZE))
 # endif
 #endif
 
@@ -61,8 +61,8 @@
 # define BL32_BASE			U(0x60000000)
 # define BL32_LIMIT			U(0x80000000)
 #else
-# define BL32_BASE			(ZYNQMP_BL32_MEM_BASE)
-# define BL32_LIMIT			(ZYNQMP_BL32_MEM_BASE + ZYNQMP_BL32_MEM_SIZE)
+# define BL32_BASE			U(ZYNQMP_BL32_MEM_BASE)
+# define BL32_LIMIT			(UL(ZYNQMP_BL32_MEM_BASE) + U(ZYNQMP_BL32_MEM_SIZE))
 #endif
 
 /*******************************************************************************
@@ -71,7 +71,7 @@
 #ifndef PRELOADED_BL33_BASE
 # define PLAT_ARM_NS_IMAGE_BASE	U(0x8000000)
 #else
-# define PLAT_ARM_NS_IMAGE_BASE	PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE	U(PRELOADED_BL33_BASE)
 #endif
 
 /*******************************************************************************
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 54b1f7a..afd664e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -727,7 +727,7 @@
  * pm_update_ioctl_bitmask() -  API to get supported IOCTL ID mask
  * @bit_mask		Returned bit mask of supported IOCTL IDs
  */
-enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask)
+enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
 {
 	uint8_t supported_ids[] = {
 		IOCTL_GET_RPU_OPER_MODE,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 27056ba..6b094db 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -55,5 +55,5 @@
 				uint32_t arg1,
 				uint32_t arg2,
 				uint32_t *value);
-enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask);
+enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask);
 #endif /* PM_API_IOCTL_H */
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 85e1464..75cb54f 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -38,7 +38,7 @@
 
 /**
  * struct eemi_api_dependency - Dependent EEMI APIs which are implemented
- * on both the ATF and firmware
+ * on both the TF-A and firmware
  *
  * @id:		EEMI API id or IOCTL id to be checked
  * @api_id:	Dependent EEMI API
@@ -48,7 +48,7 @@
 	uint8_t api_id;
 } eemi_api_dependency;
 
-/* Dependent APIs for ATF to check their version from firmware */
+/* Dependent APIs for TF-A to check their version from firmware */
 static const eemi_api_dependency api_dep_table[] = {
 	{
 		.id = PM_SELF_SUSPEND,
@@ -216,8 +216,8 @@
 	},
 };
 
-/* Expected firmware API version to ATF */
-static const uint8_t atf_expected_ver_id[] = {
+/* Expected firmware API version to TF-A */
+static const uint8_t tfa_expected_ver_id[] = {
 	[PM_SELF_SUSPEND] = FW_API_BASE_VERSION,
 	[PM_REQ_WAKEUP] = FW_API_BASE_VERSION,
 	[PM_ABORT_SUSPEND] = FW_API_BASE_VERSION,
@@ -764,8 +764,8 @@
 				return ret;
 			}
 
-			/* Check if fw version matches ATF expected version */
-			if (version != atf_expected_ver_id[api_dep_table[i].api_id]) {
+			/* Check if fw version matches TF-A expected version */
+			if (version != tfa_expected_ver_id[api_dep_table[i].api_id]) {
 				return PM_RET_ERROR_NOTSUPPORTED;
 			}
 		}
@@ -775,13 +775,13 @@
 }
 
 /**
- * feature_check_atf() - These are API's completely implemented in ATF
+ * feature_check_tfa() - These are API's completely implemented in TF-A
  * @api_id	API ID to check
  * @version	Returned supported API version
  *
  * @return	Returns status, either success or error+reason
  */
-static enum pm_ret_status feature_check_atf(uint32_t api_id, uint32_t *version,
+static enum pm_ret_status feature_check_tfa(uint32_t api_id, uint32_t *version,
 					    uint32_t *bit_mask)
 {
 	switch (api_id) {
@@ -793,7 +793,7 @@
 	case PM_GET_CALLBACK_DATA:
 	case PM_GET_TRUSTZONE_VERSION:
 	case PM_SET_SUSPEND_MODE:
-		*version = ATF_API_BASE_VERSION;
+		*version = TFA_API_BASE_VERSION;
 		return PM_RET_SUCCESS;
 	default:
 		return PM_RET_ERROR_NO_FEATURE;
@@ -801,14 +801,14 @@
 }
 
 /**
- * get_atf_version_for_partial_apis() - Return ATF version for partially
+ * get_tfa_version_for_partial_apis() - Return TF-A version for partially
  * implemented APIs
  * @api_id	API ID to check
  * @version	Returned supported API version
  *
  * @return	Returns status, either success or error+reason
  */
-static enum pm_ret_status get_atf_version_for_partial_apis(uint32_t api_id,
+static enum pm_ret_status get_tfa_version_for_partial_apis(uint32_t api_id,
 							   uint32_t *version)
 {
 	switch (api_id) {
@@ -830,7 +830,7 @@
 	case PM_PLL_SET_MODE:
 	case PM_PLL_GET_MODE:
 	case PM_REGISTER_ACCESS:
-		*version = ATF_API_BASE_VERSION;
+		*version = TFA_API_BASE_VERSION;
 		return PM_RET_SUCCESS;
 	case PM_FEATURE_CHECK:
 		*version = FW_API_VERSION_2;
@@ -842,7 +842,7 @@
 
 /**
  * feature_check_partial() - These are API's partially implemented in
- * ATF and firmware both
+ * TF-A and firmware both
  * @api_id	API ID to check
  * @version	Returned supported API version
  *
@@ -877,7 +877,7 @@
 		if (status != PM_RET_SUCCESS) {
 			return status;
 		}
-		return get_atf_version_for_partial_apis(api_id, version);
+		return get_tfa_version_for_partial_apis(api_id, version);
 	default:
 		return PM_RET_ERROR_NO_FEATURE;
 	}
@@ -898,13 +898,13 @@
 	uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
 	uint32_t status;
 
-	/* Get API version implemented in ATF */
-	status = feature_check_atf(api_id, version, bit_mask);
+	/* Get API version implemented in TF-A */
+	status = feature_check_tfa(api_id, version, bit_mask);
 	if (status != PM_RET_ERROR_NO_FEATURE) {
 		return status;
 	}
 
-	/* Get API version implemented by firmware and ATF both */
+	/* Get API version implemented by firmware and TF-A both */
 	status = feature_check_partial(api_id, version);
 	if (status != PM_RET_ERROR_NO_FEATURE) {
 		return status;
@@ -913,7 +913,7 @@
 	/* Get API version implemented by firmware */
 	status = fw_api_version(api_id, ret_payload, 3);
 	/* IOCTL call may return failure whose ID is not implemented in
-	 * firmware but implemented in ATF
+	 * firmware but implemented in TF-A
 	 */
 	if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
 		return status;
@@ -921,7 +921,7 @@
 
 	*version = ret_payload[0];
 
-	/* Update IOCTL bit mask which are implemented in ATF */
+	/* Update IOCTL bit mask which are implemented in TF-A */
 	if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
 		if (len < 2) {
 			return PM_RET_ERROR_ARGS;
@@ -929,8 +929,8 @@
 		bit_mask[0] = ret_payload[1];
 		bit_mask[1] = ret_payload[2];
 		if (api_id == PM_IOCTL) {
-			/* Get IOCTL's implemented by ATF */
-			status = atf_ioctl_bitmask(bit_mask);
+			/* Get IOCTL's implemented by TF-A */
+			status = tfa_ioctl_bitmask(bit_mask);
 		}
 	} else {
 		/* Requires for MISRA */
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
index 658e9eb..6dff07e 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
@@ -30,8 +30,8 @@
 #define FW_API_BASE_VERSION		(1U)
 /* Expected version of firmware API for feature check */
 #define FW_API_VERSION_2		(2U)
-/* Version of APIs implemented in ATF */
-#define ATF_API_BASE_VERSION		(1U)
+/* Version of APIs implemented in TF-A */
+#define TFA_API_BASE_VERSION		(1U)
 /* Updating the QUERY_DATA API versioning as the bitmask functionality
  * support is added in the v2.*/
 #define TFA_API_QUERY_DATA_VERSION	(2U)
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 7b15443..54b0007 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -95,7 +95,7 @@
  *
  * When WDT event is received in PMU, PMU needs to notify master to do cleanup
  * if required. PMU sets up timer and starts timer to overflow in zero time upon
- * WDT event. ATF handles this timer event and takes necessary action required
+ * WDT event. TF-A handles this timer event and takes necessary action required
  * for warm restart.
  *
  * In presence of non-secure software layers (EL1/2) sets the interrupt
@@ -131,7 +131,7 @@
  *
  * Function registered as INTR_TYPE_EL3 interrupt handler
  *
- * On receiving WDT event from PMU, ATF generates SGI7 to all running CPUs.
+ * On receiving WDT event from PMU, TF-A generates SGI7 to all running CPUs.
  * In response to SGI7 interrupt, each CPUs do clean up if required and last
  * running CPU calls system restart.
  */
diff --git a/plat/xilinx/zynqmp/zynqmp_sdei.c b/plat/xilinx/zynqmp/zynqmp_sdei.c
index 8a6d894..984252e 100644
--- a/plat/xilinx/zynqmp/zynqmp_sdei.c
+++ b/plat/xilinx/zynqmp/zynqmp_sdei.c
@@ -16,7 +16,10 @@
 
 int arm_validate_ns_entrypoint(uintptr_t entrypoint)
 {
-	return (entrypoint < BL31_BASE || entrypoint > BL31_LIMIT) ? 0 : -1;
+	uint64_t base = BL31_BASE;
+	uint64_t limit = BL31_LIMIT;
+
+	return (entrypoint < base || entrypoint > limit) ? 0 : -1;
 }
 
 /* Private event mappings */
diff --git a/poetry.lock b/poetry.lock
index 92b38da..07cd572 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,10 +1,9 @@
-# This file is automatically @generated by Poetry and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand.
 
 [[package]]
 name = "alabaster"
 version = "0.7.13"
 description = "A configurable sidebar-enabled Sphinx theme"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -16,7 +15,6 @@
 name = "anytree"
 version = "2.8.0"
 description = "Powerful and Lightweight Python Tree Data Structure.."
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -35,7 +33,6 @@
 name = "babel"
 version = "2.12.1"
 description = "Internationalization utilities"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -50,7 +47,6 @@
 name = "build"
 version = "0.10.0"
 description = "A simple, correct Python build frontend"
-category = "dev"
 optional = false
 python-versions = ">= 3.7"
 files = [
@@ -74,7 +70,6 @@
 name = "certifi"
 version = "2022.12.7"
 description = "Python package for providing Mozilla's CA Bundle."
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -86,7 +81,6 @@
 name = "charset-normalizer"
 version = "3.1.0"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "dev"
 optional = false
 python-versions = ">=3.7.0"
 files = [
@@ -171,7 +165,6 @@
 name = "click"
 version = "8.1.3"
 description = "Composable command line interface toolkit"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -186,7 +179,6 @@
 name = "colorama"
 version = "0.4.6"
 description = "Cross-platform colored terminal text."
-category = "dev"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
 files = [
@@ -198,7 +190,6 @@
 name = "docutils"
 version = "0.18.1"
 description = "Docutils -- Python Documentation Utilities"
-category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 files = [
@@ -210,7 +201,6 @@
 name = "idna"
 version = "3.4"
 description = "Internationalized Domain Names in Applications (IDNA)"
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -222,7 +212,6 @@
 name = "imagesize"
 version = "1.4.1"
 description = "Getting image size from png/jpeg/jpeg2000/gif file"
-category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 files = [
@@ -234,7 +223,6 @@
 name = "importlib-metadata"
 version = "6.6.0"
 description = "Read metadata from Python packages"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -254,7 +242,6 @@
 name = "jinja2"
 version = "3.1.2"
 description = "A very fast and expressive template engine."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -272,7 +259,6 @@
 name = "markdown-it-py"
 version = "2.2.0"
 description = "Python port of markdown-it. Markdown parsing, done right!"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -297,7 +283,6 @@
 name = "markupsafe"
 version = "2.1.2"
 description = "Safely add untrusted strings to HTML/XML markup."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -357,7 +342,6 @@
 name = "mdit-py-plugins"
 version = "0.3.5"
 description = "Collection of plugins for markdown-it-py"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -377,7 +361,6 @@
 name = "mdurl"
 version = "0.1.2"
 description = "Markdown URL utilities"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -389,7 +372,6 @@
 name = "myst-parser"
 version = "0.18.1"
 description = "An extended commonmark compliant parser, with bridges to docutils & sphinx."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -416,7 +398,6 @@
 name = "packaging"
 version = "23.1"
 description = "Core utilities for Python packages"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -428,7 +409,6 @@
 name = "pip"
 version = "23.1.2"
 description = "The PyPA recommended tool for installing Python packages."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -440,7 +420,6 @@
 name = "pip-tools"
 version = "6.13.0"
 description = "pip-tools keeps your pinned dependencies fresh."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -463,7 +442,6 @@
 name = "prettytable"
 version = "3.7.0"
 description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -481,7 +459,6 @@
 name = "pyelftools"
 version = "0.29"
 description = "Library for analyzing ELF files and DWARF debugging information"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -493,7 +470,6 @@
 name = "pygments"
 version = "2.15.1"
 description = "Pygments is a syntax highlighting package written in Python."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -508,7 +484,6 @@
 name = "pyproject-hooks"
 version = "1.0.0"
 description = "Wrappers to call pyproject.toml-based build backend hooks."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -523,7 +498,6 @@
 name = "pytz"
 version = "2023.3"
 description = "World timezone definitions, modern and historical"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -535,7 +509,6 @@
 name = "pyyaml"
 version = "6.0"
 description = "YAML parser and emitter for Python"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -585,7 +558,6 @@
 name = "requests"
 version = "2.30.0"
 description = "Python HTTP for Humans."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -607,7 +579,6 @@
 name = "setuptools"
 version = "67.7.2"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -624,7 +595,6 @@
 name = "six"
 version = "1.16.0"
 description = "Python 2 and 3 compatibility utilities"
-category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
 files = [
@@ -636,7 +606,6 @@
 name = "snowballstemmer"
 version = "2.2.0"
 description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -648,7 +617,6 @@
 name = "sphinx"
 version = "5.3.0"
 description = "Python documentation generator"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -684,7 +652,6 @@
 name = "sphinx-rtd-theme"
 version = "1.2.0"
 description = "Read the Docs theme for Sphinx"
-category = "dev"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
 files = [
@@ -704,7 +671,6 @@
 name = "sphinxcontrib-applehelp"
 version = "1.0.4"
 description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
-category = "dev"
 optional = false
 python-versions = ">=3.8"
 files = [
@@ -720,7 +686,6 @@
 name = "sphinxcontrib-devhelp"
 version = "1.0.2"
 description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -736,7 +701,6 @@
 name = "sphinxcontrib-htmlhelp"
 version = "2.0.1"
 description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
-category = "dev"
 optional = false
 python-versions = ">=3.8"
 files = [
@@ -752,7 +716,6 @@
 name = "sphinxcontrib-jquery"
 version = "4.1"
 description = "Extension to include jQuery on newer Sphinx releases"
-category = "dev"
 optional = false
 python-versions = ">=2.7"
 files = [
@@ -767,7 +730,6 @@
 name = "sphinxcontrib-jsmath"
 version = "1.0.1"
 description = "A sphinx extension which renders display math in HTML via JavaScript"
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -782,7 +744,6 @@
 name = "sphinxcontrib-plantuml"
 version = "0.24.1"
 description = "Sphinx \"plantuml\" extension"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -799,7 +760,6 @@
 name = "sphinxcontrib-qthelp"
 version = "1.0.3"
 description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -815,7 +775,6 @@
 name = "sphinxcontrib-serializinghtml"
 version = "1.1.5"
 description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -828,10 +787,26 @@
 test = ["pytest"]
 
 [[package]]
+name = "sphinxcontrib-svg2pdfconverter"
+version = "1.2.2"
+description = "Sphinx SVG to PDF converter extension"
+optional = false
+python-versions = "~=3.4"
+files = [
+    {file = "sphinxcontrib-svg2pdfconverter-1.2.2.tar.gz", hash = "sha256:80a55ca61f70eae93efc65f3814f2f177c86ba55934a9f6c5022f1778b62146b"},
+    {file = "sphinxcontrib_svg2pdfconverter-1.2.2-py3-none-any.whl", hash = "sha256:04ec767b55780a6b18d89cc1a8ada6d900c6efde9d1683abdb98a49b144465ca"},
+]
+
+[package.dependencies]
+Sphinx = ">=1.6.3"
+
+[package.extras]
+cairosvg = ["cairosvg (>=1.0)"]
+
+[[package]]
 name = "tomli"
 version = "2.0.1"
 description = "A lil' TOML parser"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -843,7 +818,6 @@
 name = "typing-extensions"
 version = "4.5.0"
 description = "Backported and Experimental Type Hints for Python 3.7+"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -855,7 +829,6 @@
 name = "urllib3"
 version = "2.0.2"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -873,7 +846,6 @@
 name = "wcwidth"
 version = "0.2.6"
 description = "Measures the displayed width of unicode strings in a terminal"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -885,7 +857,6 @@
 name = "wheel"
 version = "0.40.0"
 description = "A built-package format for Python"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -900,7 +871,6 @@
 name = "zipp"
 version = "3.15.0"
 description = "Backport of pathlib-compatible object wrapper for zip files"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -915,4 +885,4 @@
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "9c25ef33612d10c7caafa551a3cf6a12753167c6400f49cc261fddd18c7eaf6e"
+content-hash = "62d9ce9ca1c9f4669c7b40724acfc93968cde31c0460d1d7515d289739dc9464"
diff --git a/pyproject.toml b/pyproject.toml
index 44e78d3..19ba4d8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,6 +21,7 @@
 sphinxcontrib-plantuml = "^0.24.1"
 sphinx-rtd-theme = "^1.1.1"
 pip-tools = "^6.4.0"
+sphinxcontrib-svg2pdfconverter = "^1.2.2"
 
 [tool.poetry.group.ci.dependencies]
 click = "^8.1.3"
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
index 1f8e7ff..15c7e91 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -80,6 +80,13 @@
 		return NULL;
 	}
 
+	/* Ensure that descriptor size is aligned */
+	if (!is_aligned(desc_size, 16)) {
+		WARN("%s(0x%zx) desc_size not 16-byte aligned\n",
+		     __func__, desc_size);
+		return NULL;
+	}
+
 	obj_size = spmc_shmem_obj_size(desc_size);
 
 	/* Ensure the obj size has not overflowed. */
@@ -248,25 +255,6 @@
 }
 
 /**
- * spmc_shmem_obj_ffa_constituent_size - Calculate variable size part of obj.
- * @obj:    Object containing ffa_memory_region_descriptor.
- *
- * Return: Size of ffa_constituent_memory_region_descriptors in @obj.
- */
-static size_t
-spmc_shmem_obj_ffa_constituent_size(struct spmc_shmem_obj *obj,
-				    uint32_t ffa_version)
-{
-	struct ffa_comp_mrd *comp_mrd;
-
-	comp_mrd = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
-	if (comp_mrd == NULL) {
-		return 0;
-	}
-	return comp_mrd->address_range_count * sizeof(struct ffa_cons_mrd);
-}
-
-/**
  * spmc_shmem_obj_validate_id - Validate a partition ID is participating in
  *				a given memory transaction.
  * @sp_id:      Partition ID to validate.
@@ -371,10 +359,10 @@
  *
  * Return: the size required to store the descriptor store in the v1.1 format.
  */
-static size_t
+static uint64_t
 spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size)
 {
-	size_t size = 0;
+	uint64_t size = 0;
 	struct ffa_comp_mrd *mrd;
 	struct ffa_emad_v1_0 *emad_array = orig->emad;
 
@@ -391,11 +379,7 @@
 	mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
 	      emad_array[0].comp_mrd_offset);
 
-	/* Check the calculated address is within the memory descriptor. */
-	if (((uintptr_t) mrd + sizeof(struct ffa_comp_mrd)) >
-	    (uintptr_t)((uint8_t *) orig + desc_size)) {
-		return 0;
-	}
+	/* Add the size of the memory region descriptors. */
 	size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
 
 	return size;
@@ -776,130 +760,154 @@
 	return 0;
 }
 
+static inline const struct ffa_emad_v1_0 *
+emad_advance(const struct ffa_emad_v1_0 *emad, size_t offset)
+{
+	return (const struct ffa_emad_v1_0 *)((const uint8_t *)emad + offset);
+}
+
 /**
  * spmc_shmem_check_obj - Check that counts in descriptor match overall size.
  * @obj:	  Object containing ffa_memory_region_descriptor.
  * @ffa_version:  FF-A version of the provided descriptor.
  *
- * Return: 0 if object is valid, -EINVAL if constituent_memory_region_descriptor
- * offset or count is invalid.
+ * Return: 0 if object is valid, FFA_ERROR_INVALID_PARAMETER if
+ * constituent_memory_region_descriptor offset or count is invalid.
  */
 static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
 				uint32_t ffa_version)
 {
+	uint64_t total_page_count;
+	const struct ffa_emad_v1_0 *first_emad;
+	const struct ffa_emad_v1_0 *end_emad;
+	size_t emad_size;
 	uint32_t comp_mrd_offset = 0;
+	size_t header_emad_size;
+	size_t size;
+	size_t count;
+	size_t expected_size;
+	struct ffa_comp_mrd *comp;
 
-	if (obj->desc.emad_count == 0U) {
-		WARN("%s: unsupported attribute desc count %u.\n",
-		     __func__, obj->desc.emad_count);
-		return -EINVAL;
+	if (obj->desc_filled != obj->desc_size) {
+		ERROR("BUG: %s called on incomplete object (%zu != %zu)\n",
+		      __func__, obj->desc_filled, obj->desc_size);
+		panic();
 	}
 
-	for (size_t emad_num = 0; emad_num < obj->desc.emad_count; emad_num++) {
-		size_t size;
-		size_t count;
-		size_t expected_size;
-		size_t total_page_count;
-		size_t emad_size;
-		size_t header_emad_size;
-		uint32_t offset;
-		struct ffa_comp_mrd *comp;
-		struct ffa_emad_v1_0 *emad;
+	if (spmc_validate_mtd_start(&obj->desc, ffa_version,
+				    obj->desc_filled, obj->desc_size)) {
+		ERROR("BUG: %s called on object with corrupt memory region descriptor\n",
+		      __func__);
+		panic();
+	}
+
+	first_emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
+					     ffa_version, &emad_size);
+	end_emad = emad_advance(first_emad, obj->desc.emad_count * emad_size);
+	comp_mrd_offset = first_emad->comp_mrd_offset;
 
-		emad = spmc_shmem_obj_get_emad(&obj->desc, emad_num,
-					       ffa_version, &emad_size);
+	/* Loop through the endpoint descriptors, validating each of them. */
+	for (const struct ffa_emad_v1_0 *emad = first_emad;
+	     emad < end_emad;
+	     emad = emad_advance(emad, emad_size)) {
+		ffa_endpoint_id16_t ep_id;
 
 		/*
-		 * Validate the calculated emad address resides within the
-		 * descriptor.
+		 * If a partition ID resides in the secure world validate that
+		 * the partition ID is for a known partition. Ignore any
+		 * partition ID belonging to the normal world as it is assumed
+		 * the Hypervisor will have validated these.
 		 */
-		if ((uintptr_t) emad >=
-		    (uintptr_t)((uint8_t *) &obj->desc + obj->desc_size)) {
-			WARN("Invalid emad access.\n");
-			return -EINVAL;
+		ep_id = emad->mapd.endpoint_id;
+		if (ffa_is_secure_world_id(ep_id)) {
+			if (spmc_get_sp_ctx(ep_id) == NULL) {
+				WARN("%s: Invalid receiver id 0x%x\n",
+				     __func__, ep_id);
+				return FFA_ERROR_INVALID_PARAMETER;
+			}
 		}
 
-		offset = emad->comp_mrd_offset;
-
 		/*
 		 * The offset provided to the composite memory region descriptor
-		 * should be consistent across endpoint descriptors. Store the
-		 * first entry and compare against subsequent entries.
+		 * should be consistent across endpoint descriptors.
 		 */
-		if (comp_mrd_offset == 0) {
-			comp_mrd_offset = offset;
-		} else {
-			if (comp_mrd_offset != offset) {
-				ERROR("%s: mismatching offsets provided, %u != %u\n",
-				       __func__, offset, comp_mrd_offset);
-				return -EINVAL;
-			}
-			continue; /* Remainder only executed on first iteration. */
+		if (comp_mrd_offset != emad->comp_mrd_offset) {
+			ERROR("%s: mismatching offsets provided, %u != %u\n",
+			       __func__, emad->comp_mrd_offset, comp_mrd_offset);
+			return FFA_ERROR_INVALID_PARAMETER;
 		}
+	}
 
-		header_emad_size = (size_t)((uint8_t *)emad - (uint8_t *)&obj->desc) +
-			(obj->desc.emad_count * emad_size);
+	header_emad_size = (size_t)((const uint8_t *)end_emad -
+				    (const uint8_t *)&obj->desc);
 
-		if (offset < header_emad_size) {
-			WARN("%s: invalid object, offset %u < header + emad %zu\n",
-			     __func__, offset, header_emad_size);
-			return -EINVAL;
-		}
+	/*
+	 * Check that the composite descriptor
+	 * is after the endpoint descriptors.
+	 */
+	if (comp_mrd_offset < header_emad_size) {
+		WARN("%s: invalid object, offset %u < header + emad %zu\n",
+		     __func__, comp_mrd_offset, header_emad_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		size = obj->desc_size;
+	/* Ensure the composite descriptor offset is aligned. */
+	if (!is_aligned(comp_mrd_offset, 16)) {
+		WARN("%s: invalid object, unaligned composite memory "
+		     "region descriptor offset %u.\n",
+		     __func__, comp_mrd_offset);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		if (offset > size) {
-			WARN("%s: invalid object, offset %u > total size %zu\n",
-			     __func__, offset, obj->desc_size);
-			return -EINVAL;
-		}
-		size -= offset;
+	size = obj->desc_size;
 
-		if (size < sizeof(struct ffa_comp_mrd)) {
-			WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
-			     __func__, offset, obj->desc_size);
-			return -EINVAL;
-		}
-		size -= sizeof(struct ffa_comp_mrd);
+	/* Check that the composite descriptor is in bounds. */
+	if (comp_mrd_offset > size) {
+		WARN("%s: invalid object, offset %u > total size %zu\n",
+		     __func__, comp_mrd_offset, obj->desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+	size -= comp_mrd_offset;
 
-		count = size / sizeof(struct ffa_cons_mrd);
+	if (size < sizeof(struct ffa_comp_mrd)) {
+		WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
+		     __func__, comp_mrd_offset, obj->desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+	size -= sizeof(struct ffa_comp_mrd);
 
-		comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
+	count = size / sizeof(struct ffa_cons_mrd);
 
-		if (comp == NULL) {
-			WARN("%s: invalid comp_mrd offset\n", __func__);
-			return -EINVAL;
-		}
+	comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
 
-		if (comp->address_range_count != count) {
-			WARN("%s: invalid object, desc count %u != %zu\n",
-			     __func__, comp->address_range_count, count);
-			return -EINVAL;
-		}
+	if (comp->address_range_count != count) {
+		WARN("%s: invalid object, desc count %u != %zu\n",
+		     __func__, comp->address_range_count, count);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		expected_size = offset + sizeof(*comp) +
-				spmc_shmem_obj_ffa_constituent_size(obj,
-								    ffa_version);
+	expected_size = comp_mrd_offset + sizeof(*comp) +
+		count * sizeof(struct ffa_cons_mrd);
 
-		if (expected_size != obj->desc_size) {
-			WARN("%s: invalid object, computed size %zu != size %zu\n",
-			       __func__, expected_size, obj->desc_size);
-			return -EINVAL;
-		}
+	if (expected_size != obj->desc_size) {
+		WARN("%s: invalid object, computed size %zu != size %zu\n",
+		       __func__, expected_size, obj->desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		total_page_count = 0;
+	total_page_count = 0;
 
-		for (size_t i = 0; i < count; i++) {
-			total_page_count +=
-				comp->address_range_array[i].page_count;
-		}
-		if (comp->total_page_count != total_page_count) {
-			WARN("%s: invalid object, desc total_page_count %u != %zu\n",
-			     __func__, comp->total_page_count,
-			total_page_count);
-			return -EINVAL;
-		}
+	for (size_t i = 0; i < count; i++) {
+		total_page_count +=
+			comp->address_range_array[i].page_count;
 	}
+	if (comp->total_page_count != total_page_count) {
+		WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
+		     __func__, comp->total_page_count,
+		total_page_count);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+
 	return 0;
 }
 
@@ -910,7 +918,8 @@
  *				the memory is not in a valid state for lending.
  * @obj:    Object containing ffa_memory_region_descriptor.
  *
- * Return: 0 if object is valid, -EINVAL if invalid memory state.
+ * Return: 0 if object is valid, FFA_ERROR_INVALID_PARAMETER if invalid memory
+ * state.
  */
 static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
 				      uint32_t ffa_version)
@@ -923,7 +932,7 @@
 								  ffa_version);
 
 	if (requested_mrd == NULL) {
-		return -EINVAL;
+		return FFA_ERROR_INVALID_PARAMETER;
 	}
 
 	inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
@@ -939,11 +948,11 @@
 			other_mrd = spmc_shmem_obj_get_comp_mrd(inflight_obj,
 							  FFA_VERSION_COMPILED);
 			if (other_mrd == NULL) {
-				return -EINVAL;
+				return FFA_ERROR_INVALID_PARAMETER;
 			}
 			if (overlapping_memory_regions(requested_mrd,
 						       other_mrd)) {
-				return -EINVAL;
+				return FFA_ERROR_INVALID_PARAMETER;
 			}
 		}
 
@@ -973,9 +982,10 @@
 		goto err_arg;
 	}
 
-	if (fragment_length > mbox->rxtx_page_count * PAGE_SIZE_4KB) {
-		WARN("%s: bad fragment size %u > %u buffer size\n", __func__,
-		     fragment_length, mbox->rxtx_page_count * PAGE_SIZE_4KB);
+	CASSERT(sizeof(mbox->rxtx_page_count) == 4, assert_bogus_page_count);
+	if (fragment_length > (uint64_t)mbox->rxtx_page_count * PAGE_SIZE_4KB) {
+		WARN("%s: bad fragment size %u > %" PRIu64 " buffer size\n", __func__,
+		     fragment_length, (uint64_t)mbox->rxtx_page_count * PAGE_SIZE_4KB);
 		ret = FFA_ERROR_INVALID_PARAMETER;
 		goto err_arg;
 	}
@@ -1044,32 +1054,9 @@
 
 	ret = spmc_shmem_check_obj(obj, ffa_version);
 	if (ret != 0) {
-		ret = FFA_ERROR_INVALID_PARAMETER;
 		goto err_bad_desc;
 	}
 
-	/*
-	 * If a partition ID resides in the secure world validate that the
-	 * partition ID is for a known partition. Ignore any partition ID
-	 * belonging to the normal world as it is assumed the Hypervisor will
-	 * have validated these.
-	 */
-	for (size_t i = 0; i < obj->desc.emad_count; i++) {
-		emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
-					       &emad_size);
-
-		ffa_endpoint_id16_t ep_id = emad->mapd.endpoint_id;
-
-		if (ffa_is_secure_world_id(ep_id)) {
-			if (spmc_get_sp_ctx(ep_id) == NULL) {
-				WARN("%s: Invalid receiver id 0x%x\n",
-				     __func__, ep_id);
-				ret = FFA_ERROR_INVALID_PARAMETER;
-				goto err_bad_desc;
-			}
-		}
-	}
-
 	/* Ensure partition IDs are not duplicated. */
 	for (size_t i = 0; i < obj->desc.emad_count; i++) {
 		emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
@@ -1093,7 +1080,6 @@
 	ret = spmc_shmem_check_state_obj(obj, ffa_version);
 	if (ret) {
 		ERROR("%s: invalid memory region descriptor.\n", __func__);
-		ret = FFA_ERROR_INVALID_PARAMETER;
 		goto err_bad_desc;
 	}
 
@@ -1106,19 +1092,18 @@
 		uint64_t mem_handle;
 
 		/* Calculate the size that the v1.1 descriptor will required. */
-		size_t v1_1_desc_size =
+		uint64_t v1_1_desc_size =
 		    spmc_shm_get_v1_1_descriptor_size((void *) &obj->desc,
 						      obj->desc_size);
 
-		if (v1_1_desc_size == 0U) {
-			ERROR("%s: cannot determine size of descriptor.\n",
-			      __func__);
+		if (v1_1_desc_size > UINT32_MAX) {
+			ret = FFA_ERROR_NO_MEMORY;
 			goto err_arg;
 		}
 
 		/* Get a new obj to store the v1.1 descriptor. */
 		v1_1_obj =
-		    spmc_shmem_obj_alloc(&spmc_shmem_obj_state, v1_1_desc_size);
+		    spmc_shmem_obj_alloc(&spmc_shmem_obj_state, (size_t)v1_1_desc_size);
 
 		if (!v1_1_obj) {
 			ret = FFA_ERROR_NO_MEMORY;
@@ -1126,8 +1111,8 @@
 		}
 
 		/* Perform the conversion from v1.0 to v1.1. */
-		v1_1_obj->desc_size = v1_1_desc_size;
-		v1_1_obj->desc_filled = v1_1_desc_size;
+		v1_1_obj->desc_size = (uint32_t)v1_1_desc_size;
+		v1_1_obj->desc_filled = (uint32_t)v1_1_desc_size;
 		if (!spmc_shm_convert_shmem_obj_from_v1_0(v1_1_obj, obj)) {
 			ERROR("%s: Could not convert mtd!\n", __func__);
 			spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_1_obj);
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 80b506b..6b16373 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -249,6 +249,7 @@
 	SMC_RET0(&ctx->cpu_ctx);
 }
 
+#if (EL3_EXCEPTION_HANDLING == 0)
 /*******************************************************************************
  * spmd_group0_interrupt_handler_nwd
  * Group0 secure interrupt in the normal world are trapped to EL3. Delegate the
@@ -281,6 +282,7 @@
 
 	return 0U;
 }
+#endif
 
 /*******************************************************************************
  * spmd_handle_group0_intr_swd
@@ -561,6 +563,18 @@
 	}
 
 	/*
+	 * Permit configurations where the SPM resides at S-EL1/2 and upon a
+	 * Group0 interrupt triggering while the normal world runs, the
+	 * interrupt is routed either through the EHF or directly to the SPMD:
+	 *
+	 * EL3_EXCEPTION_HANDLING=0: the Group0 interrupt is routed to the SPMD
+	 *                   for handling by spmd_group0_interrupt_handler_nwd.
+	 *
+	 * EL3_EXCEPTION_HANDLING=1: the Group0 interrupt is routed to the EHF.
+	 *
+	 */
+#if (EL3_EXCEPTION_HANDLING == 0)
+	/*
 	 * Register an interrupt handler routing Group0 interrupts to SPMD
 	 * while the NWd is running.
 	 */
@@ -570,6 +584,8 @@
 	if (rc != 0) {
 		panic();
 	}
+#endif
+
 	return 0;
 }
 
diff --git a/tools/conventional-changelog-tf-a/index.js b/tools/conventional-changelog-tf-a/index.js
index 2a9d5b4..7d57c15 100644
--- a/tools/conventional-changelog-tf-a/index.js
+++ b/tools/conventional-changelog-tf-a/index.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -167,6 +167,17 @@
 
             writerOpts.transform = function (commit, context) {
                 /*
+                 * Feedback on the generated changelog has shown that having build system changes
+                 * appear at the top of a section throws some people off. We make an exception for
+                 * scopeless `build`-type changes and treat them as though they actually have the
+                 * `build` scope.
+                 */
+
+                if ((commit.type === "build") && (commit.scope == null)) {
+                    commit.scope = "build";
+                }
+
+                /*
                  * Fix up commit trailers, which for some reason are not correctly recognized and
                  * end up showing up in the breaking changes.
                  */
diff --git a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
index efaf567..4df4144 100644
--- a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
+++ b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
@@ -1,9 +1,11 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <stddef.h>
+
 #include <firmware_image_package.h>
 
 #include "tbbr_config.h"
@@ -13,6 +15,11 @@
 		.name = "STM32MP CONFIG CERT",
 		.uuid = UUID_STM32MP_CONFIG_CERT,
 		.cmdline_name = "stm32mp-cfg-cert"
+	},
+
+	{
+		.name = NULL,
+		.uuid = { {0} },
+		.cmdline_name = NULL,
 	}
 };
-
diff --git a/tools/memory/memory/buildparser.py b/tools/memory/memory/buildparser.py
index 6f467cd..dedff79 100755
--- a/tools/memory/memory/buildparser.py
+++ b/tools/memory/memory/buildparser.py
@@ -8,14 +8,16 @@
 from pathlib import Path
 
 from memory.elfparser import TfaElfParser
+from memory.mapparser import TfaMapParser
 
 
 class TfaBuildParser:
     """A class for performing analysis on the memory layout of a TF-A build."""
 
-    def __init__(self, path: Path):
+    def __init__(self, path: Path, map_backend=False):
         self._modules = dict()
         self._path = path
+        self.map_backend = map_backend
         self._parse_modules()
 
     def __getitem__(self, module: str):
@@ -23,15 +25,24 @@
         return self._modules[module]
 
     def _parse_modules(self):
-        """Parse ELF files in the build path."""
-        for elf_file in self._path.glob("**/*.elf"):
-            module_name = elf_file.name.split("/")[-1].split(".")[0]
-            with open(elf_file, "rb") as file:
-                self._modules[module_name] = TfaElfParser(file)
+        """Parse the build files using the selected backend."""
+        backend = TfaElfParser
+        files = list(self._path.glob("**/*.elf"))
+        io_perms = "rb"
+
+        if self.map_backend or len(files) == 0:
+            backend = TfaMapParser
+            files = self._path.glob("**/*.map")
+            io_perms = "r"
+
+        for file in files:
+            module_name = file.name.split("/")[-1].split(".")[0]
+            with open(file, io_perms) as f:
+                self._modules[module_name] = backend(f)
 
         if not len(self._modules):
             raise FileNotFoundError(
-                f"failed to find ELF files in path {self._path}!"
+                f"failed to find files to analyse in path {self._path}!"
             )
 
     @property
@@ -50,6 +61,27 @@
             reverse=True,
         )
 
+    def get_mem_usage_dict(self) -> dict:
+        """Returns map of memory usage per memory type for each module."""
+        mem_map = {}
+        for k, v in self._modules.items():
+            mod_mem_map = v.get_memory_layout()
+            if len(mod_mem_map):
+                mem_map[k] = mod_mem_map
+        return mem_map
+
+    def get_mem_tree_as_dict(self) -> dict:
+        """Returns _tree of modules, segments and segments and their total
+        memory usage."""
+        return {
+            k: {
+                "name": k,
+                **v.get_mod_mem_usage_dict(),
+                **{"children": v.get_seg_map_as_dict()},
+            }
+            for k, v in self._modules.items()
+        }
+
     @property
     def module_names(self):
         """Returns sorted list of module names."""
diff --git a/tools/memory/memory/elfparser.py b/tools/memory/memory/elfparser.py
index 3964e6c..2dd2513 100644
--- a/tools/memory/memory/elfparser.py
+++ b/tools/memory/memory/elfparser.py
@@ -4,11 +4,22 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+import re
+from dataclasses import asdict, dataclass
 from typing import BinaryIO
 
 from elftools.elf.elffile import ELFFile
 
 
+@dataclass(frozen=True)
+class TfaMemObject:
+    name: str
+    start: int
+    end: int
+    size: int
+    children: list
+
+
 class TfaElfParser:
     """A class representing an ELF file built for TF-A.
 
@@ -28,6 +39,123 @@
             for sym in elf.get_section_by_name(".symtab").iter_symbols()
         }
 
+        self.set_segment_section_map(elf.iter_segments(), elf.iter_sections())
+        self._memory_layout = self.get_memory_layout_from_symbols()
+        self._start = elf["e_entry"]
+        self._size, self._free = self._get_mem_usage()
+        self._end = self._start + self._size
+
     @property
     def symbols(self):
         return self._symbols.items()
+
+    @staticmethod
+    def tfa_mem_obj_factory(elf_obj, name=None, children=None, segment=False):
+        """Converts a pyelfparser Segment or Section to a TfaMemObject."""
+        # Ensure each segment is provided a name since they aren't in the
+        # program header.
+        assert not (
+            segment and name is None
+        ), "Attempting to make segment without a name"
+
+        if children is None:
+            children = list()
+
+        # Segment and sections header keys have different prefixes.
+        vaddr = "p_vaddr" if segment else "sh_addr"
+        size = "p_memsz" if segment else "sh_size"
+
+        # TODO figure out how to handle free space for sections and segments
+        return TfaMemObject(
+            name if segment else elf_obj.name,
+            elf_obj[vaddr],
+            elf_obj[vaddr] + elf_obj[size],
+            elf_obj[size],
+            [] if not children else children,
+        )
+
+    def _get_mem_usage(self) -> (int, int):
+        """Get total size and free space for this component."""
+        size = free = 0
+
+        # Use information encoded in the segment header if we can't get a
+        # memory configuration.
+        if not self._memory_layout:
+            return sum(s.size for s in self._segments.values()), 0
+
+        for v in self._memory_layout.values():
+            size += v["length"]
+            free += v["start"] + v["length"] - v["end"]
+
+        return size, free
+
+    def set_segment_section_map(self, segments, sections):
+        """Set segment to section mappings."""
+        segments = list(
+            filter(lambda seg: seg["p_type"] == "PT_LOAD", segments)
+        )
+
+        for sec in sections:
+            for n, seg in enumerate(segments):
+                if seg.section_in_segment(sec):
+                    if n not in self._segments.keys():
+                        self._segments[n] = self.tfa_mem_obj_factory(
+                            seg, name=f"{n:#02}", segment=True
+                        )
+
+                    self._segments[n].children.append(
+                        self.tfa_mem_obj_factory(sec)
+                    )
+
+    def get_memory_layout_from_symbols(self, expr=None) -> dict:
+        """Retrieve information about the memory configuration from the symbol
+        table.
+        """
+        assert len(self._symbols), "Symbol table is empty!"
+
+        expr = r".*(.?R.M)_REGION.*(START|END|LENGTH)" if not expr else expr
+        region_symbols = filter(lambda s: re.match(expr, s), self._symbols)
+        memory_layout = {}
+
+        for symbol in region_symbols:
+            region, _, attr = tuple(symbol.lower().strip("__").split("_"))
+            if region not in memory_layout:
+                memory_layout[region] = {}
+
+            # Retrieve the value of the symbol using the symbol as the key.
+            memory_layout[region][attr] = self._symbols[symbol]
+
+        return memory_layout
+
+    def get_seg_map_as_dict(self):
+        """Get a dictionary of segments and their section mappings."""
+        return [asdict(v) for k, v in self._segments.items()]
+
+    def get_memory_layout(self):
+        """Get the total memory consumed by this module from the memory
+        configuration.
+            {"rom": {"start": 0x0, "end": 0xFF, "length": ... }
+        """
+        mem_dict = {}
+
+        for mem, attrs in self._memory_layout.items():
+            limit = attrs["start"] + attrs["length"]
+            mem_dict[mem] = {
+                "start": attrs["start"],
+                "limit": limit,
+                "size": attrs["end"] - attrs["start"],
+                "free": limit - attrs["end"],
+                "total": attrs["length"],
+            }
+        return mem_dict
+
+    def get_mod_mem_usage_dict(self):
+        """Get the total memory consumed by the module, this combines the
+        information in the memory configuration.
+        """
+        return {
+            "start": self._start,
+            "end": self._end,
+            "size": self._size,
+            "free": self._free,
+        }
diff --git a/tools/memory/memory/mapparser.py b/tools/memory/memory/mapparser.py
new file mode 100644
index 0000000..b1a4b4c
--- /dev/null
+++ b/tools/memory/memory/mapparser.py
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from re import match, search
+from typing import TextIO
+
+
+class TfaMapParser:
+    """A class representing a map file built for TF-A.
+
+    Provides a basic interface for reading the symbol table. The constructor
+    accepts a file-like object with the contents a Map file. Only GNU map files
+    are supported at this stage.
+    """
+
+    def __init__(self, map_file: TextIO):
+        self._symbols = self.read_symbols(map_file)
+
+    @property
+    def symbols(self):
+        return self._symbols.items()
+
+    @staticmethod
+    def read_symbols(file: TextIO, pattern: str = None) -> dict:
+        pattern = r"\b(0x\w*)\s*(\w*)\s=" if not pattern else pattern
+        symbols = {}
+
+        for line in file.readlines():
+            match = search(pattern, line)
+
+            if match is not None:
+                value, name = match.groups()
+                symbols[name] = int(value, 16)
+
+        return symbols
+
+    def get_memory_layout(self) -> dict:
+        """Get the total memory consumed by this module from the memory
+        configuration.
+            {"rom": {"start": 0x0, "end": 0xFF, "length": ... }
+        """
+        assert len(self._symbols), "Symbol table is empty!"
+        expr = r".*(.?R.M)_REGION.*(START|END|LENGTH)"
+        memory_layout = {}
+
+        region_symbols = filter(lambda s: match(expr, s), self._symbols)
+
+        for symbol in region_symbols:
+            region, _, attr = tuple(symbol.lower().strip("__").split("_"))
+            if region not in memory_layout:
+                memory_layout[region] = {}
+
+            memory_layout[region][attr] = self._symbols[symbol]
+
+            if "start" and "length" and "end" in memory_layout[region]:
+                memory_layout[region]["limit"] = (
+                    memory_layout[region]["end"]
+                    + memory_layout[region]["length"]
+                )
+                memory_layout[region]["free"] = (
+                    memory_layout[region]["limit"]
+                    - memory_layout[region]["end"]
+                )
+                memory_layout[region]["total"] = memory_layout[region][
+                    "length"
+                ]
+                memory_layout[region]["size"] = (
+                    memory_layout[region]["end"]
+                    - memory_layout[region]["start"]
+                )
+
+        return memory_layout
diff --git a/tools/memory/memory/memmap.py b/tools/memory/memory/memmap.py
index 7057228..99149b5 100755
--- a/tools/memory/memory/memmap.py
+++ b/tools/memory/memory/memmap.py
@@ -36,11 +36,27 @@
     type=click.Choice(["debug", "release"], case_sensitive=False),
 )
 @click.option(
+    "-f",
+    "--footprint",
+    is_flag=True,
+    show_default=True,
+    help="Generate a high level view of memory usage by memory types.",
+)
+@click.option(
+    "-t",
+    "--tree",
+    is_flag=True,
+    help="Generate a hierarchical view of the modules, segments and sections.",
+)
+@click.option(
+    "--depth",
+    default=3,
+    help="Generate a virtual address map of important TF symbols.",
+)
+@click.option(
     "-s",
     "--symbols",
     is_flag=True,
-    show_default=True,
-    default=True,
     help="Generate a map of important TF symbols.",
 )
 @click.option("-w", "--width", type=int, envvar="COLUMNS")
@@ -50,24 +66,41 @@
     default=False,
     help="Display numbers in decimal base.",
 )
+@click.option(
+    "--no-elf-images",
+    is_flag=True,
+    help="Analyse the build's map files instead of ELF images.",
+)
 def main(
     root: Path,
     platform: str,
     build_type: str,
+    footprint: str,
+    tree: bool,
     symbols: bool,
+    depth: int,
     width: int,
     d: bool,
+    no_elf_images: bool,
 ):
     build_path = root if root else Path("build/", platform, build_type)
     click.echo(f"build-path: {build_path.resolve()}")
 
-    parser = TfaBuildParser(build_path)
+    parser = TfaBuildParser(build_path, map_backend=no_elf_images)
     printer = TfaPrettyPrinter(columns=width, as_decimal=d)
 
+    if footprint or not (tree or symbols):
+        printer.print_footprint(parser.get_mem_usage_dict())
+
+    if tree:
+        printer.print_mem_tree(
+            parser.get_mem_tree_as_dict(), parser.module_names, depth=depth
+        )
+
     if symbols:
         expr = (
             r"(.*)(TEXT|BSS|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF"
-            r"|R.M)(.*)(START|END)__$"
+            r"|R.M)(.*)(START|UNALIGNED|END)__$"
         )
         printer.print_symbol_table(
             parser.filter_symbols(parser.symbols, expr), parser.module_names
diff --git a/tools/memory/memory/printer.py b/tools/memory/memory/printer.py
index 11fd7f0..4b18560 100755
--- a/tools/memory/memory/printer.py
+++ b/tools/memory/memory/printer.py
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+from anytree import RenderTree
+from anytree.importer import DictImporter
+from prettytable import PrettyTable
+
 
 class TfaPrettyPrinter:
     """A class for printing the memory layout of ELF files.
@@ -15,6 +19,8 @@
 
     def __init__(self, columns: int = None, as_decimal: bool = False):
         self.term_size = columns if columns and columns > 120 else 120
+        self._tree = None
+        self._footprint = None
         self._symbol_map = None
         self.as_decimal = as_decimal
 
@@ -23,6 +29,10 @@
             fmt = f">{width}x" if not self.as_decimal else f">{width}"
         return [f"{arg:{fmt}}" if fmt else arg for arg in args]
 
+    def format_row(self, leading, *args, width=10, fmt=None):
+        formatted_args = self.format_args(*args, width=width, fmt=fmt)
+        return leading + " ".join(formatted_args)
+
     @staticmethod
     def map_elf_symbol(
         leading: str,
@@ -50,17 +60,51 @@
 
         return leading + sec_row_l + sec_row + sec_row_r
 
+    def print_footprint(
+        self, app_mem_usage: dict, sort_key: str = None, fields: list = None
+    ):
+        assert len(app_mem_usage), "Empty memory layout dictionary!"
+        if not fields:
+            fields = ["Component", "Start", "Limit", "Size", "Free", "Total"]
+
+        sort_key = fields[0] if not sort_key else sort_key
+
+        # Iterate through all the memory types, create a table for each
+        # type, rows represent a single module.
+        for mem in sorted(set(k for _, v in app_mem_usage.items() for k in v)):
+            table = PrettyTable(
+                sortby=sort_key,
+                title=f"Memory Usage (bytes) [{mem.upper()}]",
+                field_names=fields,
+            )
+
+            for mod, vals in app_mem_usage.items():
+                if mem in vals.keys():
+                    val = vals[mem]
+                    table.add_row(
+                        [
+                            mod.upper(),
+                            *self.format_args(
+                                *[val[k.lower()] for k in fields[1:]]
+                            ),
+                        ]
+                    )
+            print(table, "\n")
+
     def print_symbol_table(
         self,
         symbols: list,
         modules: list,
-        start: int = 11,
+        start: int = 12,
     ):
         assert len(symbols), "Empty symbol list!"
         modules = sorted(modules)
         col_width = int((self.term_size - start) / len(modules))
+        address_fixed_width = 11
 
-        num_fmt = "0=#010x" if not self.as_decimal else ">10"
+        num_fmt = (
+            f"0=#0{address_fixed_width}x" if not self.as_decimal else ">10"
+        )
 
         _symbol_map = [
             " " * start
@@ -91,3 +135,29 @@
         self._symbol_map = ["Memory Layout:"]
         self._symbol_map += list(reversed(_symbol_map))
         print("\n".join(self._symbol_map))
+
+    def print_mem_tree(
+        self, mem_map_dict, modules, depth=1, min_pad=12, node_right_pad=12
+    ):
+        # Start column should have some padding between itself and its data
+        # values.
+        anchor = min_pad + node_right_pad * (depth - 1)
+        headers = ["start", "end", "size"]
+
+        self._tree = [
+            (f"{'name':<{anchor}}" + " ".join(f"{arg:>10}" for arg in headers))
+        ]
+
+        for mod in sorted(modules):
+            root = DictImporter().import_(mem_map_dict[mod])
+            for pre, fill, node in RenderTree(root, maxlevel=depth):
+                leading = f"{pre}{node.name}".ljust(anchor)
+                self._tree.append(
+                    self.format_row(
+                        leading,
+                        node.start,
+                        node.end,
+                        node.size,
+                    )
+                )
+        print("\n".join(self._tree), "\n")