Merge "fix(rcar): add mandatory fields in 'reserved-memory' node" into integration
diff --git a/.gitignore b/.gitignore
index ab2c0c4..ac9a11d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@
 
 # Ignore build products from tools
 tools/**/*.o
+tools/**/*.d
 tools/renesas/rcar_layout_create/*.bin
 tools/renesas/rcar_layout_create/*.srec
 tools/renesas/rcar_layout_create/*.map
diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg
index 593dfa8..617400a 100755
--- a/.husky/prepare-commit-msg
+++ b/.husky/prepare-commit-msg
@@ -3,4 +3,6 @@
 # shellcheck source=./_/husky.sh
 . "$(dirname "$0")/_/husky.sh"
 
-"$(dirname "$0")/prepare-commit-msg.cz" "$@"
+if ! git config --get tf-a.disableCommitizen > /dev/null; then
+    "$(dirname "$0")/prepare-commit-msg.cz" "$@"
+fi
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 2b418ae..6207066 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -15,10 +15,12 @@
     python: "3.10"
   apt_packages:
     - plantuml
-
-python:
-  install:
-    - requirements: docs/requirements.txt
+  jobs:
+    post_create_environment:
+      - pip install poetry=="1.3.2"
+      - poetry config virtualenvs.create false
+    post_install:
+      - poetry install --with doc
 
 sphinx:
   configuration: docs/conf.py
diff --git a/.versionrc.js b/.versionrc.js
index f699a07..3a21ded 100644
--- a/.versionrc.js
+++ b/.versionrc.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
  */
@@ -81,10 +81,45 @@
             "type": "json"
         },
         {
+            "filename": "pyproject.toml",
+            "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 + '"'
+
+                    return contents.replace(/^(version\s=\s")((\d).?)*$/m, _ver)
+                }
+            },
+        },
+        {
             "filename": "package-lock.json",
             "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 b9ca664..f33a12e 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 2
-VERSION_MINOR			:= 8
+VERSION_MINOR			:= 9
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}
 
 # Default goal is build all images
@@ -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,160 +177,106 @@
 	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
-
-# 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
-# Will set march32-directive from platform configuration
+	target32-directive	= 	-target arm-none-eabi
+# Will set march-directive from platform configuration
 else
-target32-directive	= 	-target armv8a-none-eabi
+	target32-directive	= 	-target armv8a-none-eabi
+endif #(ARM_ARCH_MAJOR)
 
-# 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
+################################################################################
+# 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))
+	march-directive	:=	$(march-directive)+$(arch-features)
 # 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))),)
-		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi $(march32-directive)
-		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi $(march64-directive)
+		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi
+		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi
 		LD			:=	$(LINKER)
 	else
-		TF_CFLAGS_aarch32	=	$(target32-directive) $(march32-directive)
-		TF_CFLAGS_aarch64	:=	-target aarch64-elf $(march64-directive)
+		TF_CFLAGS_aarch32	=	$(target32-directive)
+		TF_CFLAGS_aarch64	:=	-target aarch64-elf
 		LD			:=	$(shell $(CC) --print-prog-name ld.lld)
 
 		AR			:=	$(shell $(CC) --print-prog-name llvm-ar)
@@ -294,62 +288,60 @@
 	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
+	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
+	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)
+ASFLAGS		+=	$(march-directive)
 
+##############################################################################
+# WARNINGS Configuration
+###############################################################################
 # General warnings
 WARNINGS		:=	-Wall -Wmissing-include-dirs -Wunused	\
 				-Wdisabled-optimization -Wvla -Wshadow	\
@@ -395,18 +387,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))),)
@@ -414,34 +406,40 @@
 WARNINGS	+=		-Wunused-but-set-variable -Wmaybe-uninitialized	\
 				-Wpacked-bitfield-compat -Wshift-overflow=2 \
 				-Wlogical-op
+
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
+TF_CFLAGS		+= 	$(call cc_option, --param=min-pagesize=0)
+
 else
 # 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))			\
+ASFLAGS			+=	$(CPPFLAGS)                 			\
 				-ffreestanding -Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
 				-ffunction-sections -fdata-sections		\
 				-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)
 
@@ -449,51 +447,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 \
@@ -511,18 +511,26 @@
 				drivers/console/multi_console.c		\
 				lib/${ARCH}/cache_helpers.S		\
 				lib/${ARCH}/misc_helpers.S		\
+				lib/extensions/pmuv3/${ARCH}/pmuv3.c	\
 				plat/common/plat_bl_common.c		\
 				plat/common/plat_log_common.c		\
 				plat/common/${ARCH}/plat_common.c	\
 				plat/common/${ARCH}/platform_helpers.S	\
 				${COMPILER_RT_SRCS}
 
+# Pointer Authentication sources
+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
+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				\
@@ -537,7 +545,6 @@
 ################################################################################
 # Generic definitions
 ################################################################################
-
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
 
 ifeq (${BUILD_BASE},)
@@ -550,91 +557,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
@@ -646,6 +659,14 @@
 
 include ${PLAT_MAKEFILE_FULL}
 
+################################################################################
+# Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
+# up with appropriate march values for compiler.
+################################################################################
+include ${MAKE_HELPERS_DIRECTORY}march.mk
+
+TF_CFLAGS   +=	$(march-directive)
+
 # This internal flag is common option which is set to 1 for scenarios
 # when the BL2 is running in EL3 level. This occurs in two scenarios -
 # 4 world system running BL2 at EL3 and two world system without BL1 running
@@ -653,9 +674,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
@@ -674,7 +696,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
@@ -683,13 +705,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)
@@ -697,18 +719,25 @@
 	BL32_CPPFLAGS	+=	-fpie
 	BL32_CFLAGS	+=	-fpie
 	BL32_LDFLAGS	+=	$(PIE_LDFLAGS)
-endif
+endif #(ENABLE_PIE)
 
-ifeq (${ARCH},aarch64)
+BL1_CPPFLAGS  += -DREPORT_ERRATA=${DEBUG}
+BL31_CPPFLAGS += -DREPORT_ERRATA=${DEBUG}
+BL32_CPPFLAGS += -DREPORT_ERRATA=${DEBUG}
+
 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
-BL2U_CPPFLAGS += -DIMAGE_AT_EL1
-BL31_CPPFLAGS += -DIMAGE_AT_EL3
-BL32_CPPFLAGS += -DIMAGE_AT_EL1
+	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
+else
+	BL32_CPPFLAGS += -DIMAGE_AT_EL3
 endif
 
 # Include the CPU specific operations makefile, which provides default
@@ -716,25 +745,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
@@ -744,201 +771,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
 
-# For RAS_EXTENSION, require that EAs are handled in EL3 first
+# RAS_EXTENSION is deprecated, provide alternate build options
 ifeq ($(RAS_EXTENSION),1)
-    ifneq ($(HANDLE_EA_EL3_FIRST_NS),1)
-        $(error For RAS_EXTENSION, HANDLE_EA_EL3_FIRST_NS must also be 1)
-    endif
+        $(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 #(RAS_FFH_SUPPORT)
+
-# When FAULT_INJECTION_SUPPORT is used, require that RAS_EXTENSION is enabled
+# When FAULT_INJECTION_SUPPORT is used, require that FEAT_RAS is enabled
 ifeq ($(FAULT_INJECTION_SUPPORT),1)
-    ifneq ($(RAS_EXTENSION),1)
-        $(error For FAULT_INJECTION_SUPPORT, RAS_EXTENSION must also be 1)
-    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 #(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
-    ifeq (${ENABLE_SME_FOR_NS},1)
-        $(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
+	# SME/SVE only supported on AArch64
+	ifneq (${ENABLE_SME_FOR_NS},0)
+                $(error "ENABLE_SME_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
+	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
 
-    # 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
+	# 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 #(ARCH=aarch32)
 
 # Ensure ENABLE_RME is not used with SME
 ifeq (${ENABLE_RME},1)
-    ifeq (${ENABLE_SME_FOR_NS},1)
-        $(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 #(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
-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)
-    ifeq (${ENABLE_SME_FOR_NS},1)
-        $(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
+	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 #(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
@@ -946,64 +1044,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
@@ -1012,43 +1110,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 PRINT_MEMORY_MAP
-PRINT_MEMORY_MAP_PATH		?=	tools/memory
-PRINT_MEMORY_MAP		?=	${PRINT_MEMORY_MAP_PATH}/print_memory_map.py
-
-# Variables for use with documentation build using Sphinx tool
-DOCS_PATH		?=	docs
-
-# Defination of SIMICS flag
-SIMICS_BUILD	?=	0
-
-################################################################################
 # Include BL specific makefiles
 ################################################################################
 
@@ -1072,124 +1133,133 @@
 # 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 \
-        ENABLE_AMU_AUXILIARY_COUNTERS \
-        ENABLE_AMU_FCONF \
-        AMU_RESTRICT_COUNTERS \
-        ENABLE_ASSERTIONS \
-        ENABLE_PIE \
-        ENABLE_PMF \
-        ENABLE_PSCI_STAT \
-        ENABLE_RUNTIME_INSTRUMENTATION \
-        ENABLE_SME_FOR_NS \
-        ENABLE_SME_FOR_SWD \
-        ENABLE_SPE_FOR_LOWER_ELS \
-        ENABLE_SVE_FOR_NS \
-        ENABLE_SVE_FOR_SWD \
-        ERROR_DEPRECATED \
-        FAULT_INJECTION_SUPPORT \
-        GENERATE_COT \
-        GICV2_G0_FOR_EL3 \
-        HANDLE_EA_EL3_FIRST_NS \
-        HW_ASSISTED_COHERENCY \
-        INVERTED_MEMMAP \
-        MEASURED_BOOT \
-        DRTM_SUPPORT \
-        NS_TIMER_SWITCH \
-        OVERRIDE_LIBC \
-        PL011_GENERIC_UART \
-        PLAT_RSS_NOT_SUPPORTED \
-        PROGRAMMABLE_RESET_ADDRESS \
-        PSCI_EXTENDED_STATE_ID \
-        RESET_TO_BL31 \
-        RESET_TO_BL31_WITH_PARAMS \
-        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_SYS_REG_TRACE_FOR_NS \
-        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 \
+	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 \
 	CONDITIONAL_CMO \
+	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_AMUv1 \
-        ENABLE_FEAT_AMUv1p1 \
-        ENABLE_FEAT_CSV2_2 \
-        ENABLE_FEAT_DIT \
-        ENABLE_FEAT_ECV \
-        ENABLE_FEAT_FGT \
-        ENABLE_FEAT_HCX \
-        ENABLE_FEAT_PAN \
-        ENABLE_FEAT_RNG \
-        ENABLE_FEAT_RNG_TRAP \
-        ENABLE_FEAT_SB \
-        ENABLE_FEAT_SEL2 \
-        ENABLE_FEAT_TCR2 \
-        ENABLE_FEAT_VHE \
-        ENABLE_MPAM_FOR_LOWER_ELS \
-        ENABLE_RME \
-        ENABLE_TRF_FOR_NS \
-        FW_ENC_STATUS \
-        NR_OF_FW_BANKS \
-        NR_OF_IMAGES_IN_FW_BANK \
-        RAS_EXTENSION \
-        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 \
+	DISABLE_MTPMU \
+	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 \
 )))
 
 ifdef KEY_SIZE
@@ -1208,153 +1278,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_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_SME_FOR_SWD \
-        ENABLE_SPE_FOR_LOWER_ELS \
-        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 \
-        RAS_EXTENSION \
-        RESET_TO_BL31 \
-        RESET_TO_BL31_WITH_PARAMS \
-        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 \
-        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_AMUv1 \
-        ENABLE_FEAT_ECV \
-        SIMICS_BUILD \
-        ENABLE_FEAT_AMUv1p1 \
-        ENABLE_FEAT_SEL2 \
-        ENABLE_FEAT_VHE \
-        ENABLE_FEAT_CSV2_2 \
-        ENABLE_FEAT_PAN \
-        ENABLE_FEAT_TCR2 \
-        FEATURE_DETECTION \
-        TWED_DELAY \
-        ENABLE_FEAT_TWED \
+	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 \
+	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
@@ -1375,7 +1454,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))
@@ -1383,11 +1462,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
@@ -1396,11 +1475,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}
@@ -1412,8 +1492,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
@@ -1429,8 +1509,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.
@@ -1440,23 +1520,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)
@@ -1466,7 +1546,7 @@
 	@${ECHO_BLANK_LINE}
 	@echo "Built SP Images successfully"
 	@${ECHO_BLANK_LINE}
-endif
+endif #(NEED_SP_PKG)
 
 locate-checkpatch:
 ifndef CHECKPATCH
@@ -1475,7 +1555,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"
@@ -1486,7 +1566,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
@@ -1501,7 +1581,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
@@ -1555,7 +1635,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})
@@ -1572,7 +1652,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})
@@ -1593,14 +1673,19 @@
 # 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
 
-# Call print_memory_map tool
 memmap: all
-	${Q}${PYTHON} ${PRINT_MEMORY_MAP} ${BUILD_PLAT} ${INVERTED_MEMMAP}
+ifdef UNIX_MK
+	${Q}PYTHONPATH=${CURDIR}/tools/memory \
+		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
+else
+	${Q}set PYTHONPATH=${CURDIR}/tools/memory && \
+		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
+endif
 
 doc:
 	@echo "  BUILD DOCUMENTATION"
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/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S
index c54219f..eaaf59a 100644
--- a/bl1/aarch64/bl1_exceptions.S
+++ b/bl1/aarch64/bl1_exceptions.S
@@ -218,9 +218,7 @@
 smc_handler:
 	/* -----------------------------------------------------
 	 * Save x0-x29 and ARMv8.3-PAuth (if enabled) registers.
-	 * If Secure Cycle Counter is not disabled in MDCR_EL3
-	 * when ARMv8.5-PMU is implemented, save PMCR_EL0 and
-	 * disable Cycle Counter.
+	 * Save PMCR_EL0 and disable Cycle Counter.
 	 * TODO: Revisit to store only SMCCC specified registers.
 	 * -----------------------------------------------------
 	 */
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index bec234b..49dda85 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,11 @@
 }
 
 SECTIONS {
+    ROM_REGION_START = ORIGIN(ROM);
+    ROM_REGION_LENGTH = LENGTH(ROM);
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
+
     . = BL1_RO_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -36,6 +41,7 @@
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -67,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);
@@ -97,6 +104,7 @@
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
         "cpu_ops not defined for this platform.")
 
+    ROM_REGION_END = .;
     . = BL1_RW_BASE;
 
     ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
@@ -157,4 +165,5 @@
 #endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL1_RW_LIMIT, "BL1's RW section has exceeded its limit.")
+    RAM_REGION_END = .;
 }
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 0c43f13..95fe50e 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -16,10 +16,6 @@
 				plat/common/${ARCH}/platform_up_stack.S \
 				${MBEDTLS_SOURCES}
 
-ifeq (${DISABLE_MTPMU},1)
-BL1_SOURCES		+=	lib/extensions/mtpmu/${ARCH}/mtpmu.S
-endif
-
 ifeq (${ARCH},aarch64)
 BL1_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S		\
 				lib/el3_runtime/aarch64/context.S
@@ -29,4 +25,10 @@
 BL1_SOURCES		+=	bl1/bl1_fwu.c
 endif
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL1_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL1_LDFLAGS	+=	--sort-section=alignment
+endif
+
 BL1_DEFAULT_LINKER_SCRIPT_SOURCE := bl1/bl1.ld.S
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 7399bc8..3f64e27 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -17,7 +17,7 @@
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/console.h>
-#include <lib/cpus/errata_report.h>
+#include <lib/cpus/errata.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 #include <smccc_helpers.h>
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 458a12b..db83a0c 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -16,6 +16,8 @@
 }
 
 SECTIONS {
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
     . = BL2_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -33,6 +35,7 @@
 
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -55,6 +58,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
 
         __RODATA_END__ = .;
@@ -116,6 +120,7 @@
 
     __RW_END__ = .;
     __BL2_END__ = .;
+    RAM_REGION_END = .;
 
     __BSS_SIZE__ = SIZEOF(.bss);
 
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 778e2c3..1663c52 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -15,6 +15,12 @@
 BL2_SOURCES		+=	common/aarch64/early_exceptions.S
 endif
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL2_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL2_LDFLAGS	+=	--sort-section=alignment
+endif
+
 ifeq (${ENABLE_RME},1)
 # Using RME, run BL2 at EL3
 include lib/gpt_rme/gpt_rme.mk
@@ -35,12 +41,7 @@
 BL2_SOURCES		+=	bl2/${ARCH}/bl2_el3_entrypoint.S	\
 				bl2/${ARCH}/bl2_el3_exceptions.S	\
 				bl2/${ARCH}/bl2_run_next_image.S        \
-				lib/cpus/${ARCH}/cpu_helpers.S		\
-				lib/cpus/errata_report.c
-
-ifeq (${DISABLE_MTPMU},1)
-BL2_SOURCES		+=	lib/extensions/mtpmu/${ARCH}/mtpmu.S
-endif
+				lib/cpus/${ARCH}/cpu_helpers.S
 
 ifeq (${ARCH},aarch64)
 BL2_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index aa457fa..4aa5cb0 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -31,7 +31,12 @@
 #endif /* !BL2_IN_XIP_MEM */
 
 SECTIONS {
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
 #if BL2_IN_XIP_MEM
+    ROM_REGION_START = ORIGIN(ROM);
+    ROM_REGION_LENGTH = LENGTH(ROM);
+
     . = BL2_RO_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -43,6 +48,11 @@
         "BL2_BASE address is not aligned on a page boundary.")
 #endif /* BL2_IN_XIP_MEM */
 
+#if SEPARATE_BL2_NOLOAD_REGION
+    RAM_NOLOAD_REGION_START = ORIGIN(RAM_NOLOAD);
+    RAM_NOLOAD_REGION_LENGTH = LENGTH(RAM_NOLOAD);
+#endif
+
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
@@ -55,6 +65,7 @@
 
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -68,6 +79,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
 
         __RODATA_END__ = .;
@@ -109,6 +121,7 @@
         "cpu_ops not defined for this platform.")
 
 #if BL2_IN_XIP_MEM
+    ROM_REGION_END = .;
     . = BL2_RW_BASE;
 
     ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
@@ -138,6 +151,7 @@
 
 #if SEPARATE_BL2_NOLOAD_REGION
     __BL2_NOLOAD_END__ = .;
+    RAM_NOLOAD_REGION_END = .;
 
     . = SAVED_ADDR;
 #endif /* SEPARATE_BL2_NOLOAD_REGION */
@@ -198,6 +212,7 @@
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
 #endif /* USE_COHERENT_MEM */
 
+    RAM_REGION_END = .;
 #if BL2_IN_XIP_MEM
     ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
 #else /* BL2_IN_XIP_MEM */
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 52a925b..7b1a101 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -18,6 +18,8 @@
 }
 
 SECTIONS {
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
     . = BL2U_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -30,6 +32,7 @@
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -51,6 +54,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
@@ -115,4 +119,5 @@
     __BSS_SIZE__ = SIZEOF(.bss);
 
     ASSERT(. <= BL2U_LIMIT, "BL2U image has exceeded its limit.")
+    RAM_REGION_END = .;
 }
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
index 9f29bde..9fe20f5 100644
--- a/bl2u/bl2u.mk
+++ b/bl2u/bl2u.mk
@@ -13,3 +13,9 @@
 endif
 
 BL2U_DEFAULT_LINKER_SCRIPT_SOURCE := bl2u/bl2u.ld.S
+
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL2U_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL2U_LDFLAGS	+=	--sort-section=alignment
+endif
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index b0c46dc..dfb14e9 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,19 +66,6 @@
 		_init_c_runtime=1				\
 		_exception_vectors=runtime_exceptions		\
 		_pie_fixup_size=BL31_LIMIT - BL31_BASE
-
-#if !RESET_TO_BL31_WITH_PARAMS
-	/* ---------------------------------------------------------------------
-	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
-	 * there's no argument to relay from a previous bootloader. Zero the
-	 * arguments passed to the platform layer to reflect that.
-	 * ---------------------------------------------------------------------
-	 */
-	mov	x20, 0
-	mov	x21, 0
-	mov	x22, 0
-	mov	x23, 0
-#endif /* RESET_TO_BL31_WITH_PARAMS */
 #endif /* RESET_TO_BL31 */
 
 	/* --------------------------------------------------------------------
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index 9419476..dd6b4dc 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -81,9 +81,7 @@
 1:
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
-	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
-	 * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
-	 * Also set the PSTATE to a known state.
+	 * Also save PMCR_EL0 and set the PSTATE to a known state.
 	 */
 	bl	prepare_el3_entry
 
@@ -123,9 +121,7 @@
 
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
-	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
-	 * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
-	 * Also set the PSTATE to a known state.
+	 * Also save PMCR_EL0 and set the PSTATE to a known state.
 	 */
 	bl	prepare_el3_entry
 
@@ -153,7 +149,7 @@
  * x1: EA syndrome
  */
 func delegate_sync_ea
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	/*
 	 * Check for Uncontainable error type. If so, route to the platform
 	 * fatal error handler rather than the generic EA one.
@@ -183,7 +179,7 @@
  * x1: EA syndrome
  */
 func delegate_async_ea
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	/* Check Exception Class to ensure SError, as this function should
 	 * only be invoked for SError. If that is not the case, which implies
 	 * either an HW error or programming error, panic.
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 500e87b..851ac47 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -50,16 +50,16 @@
 	/*
 	 * Macro that prepares entry to EL3 upon taking an exception.
 	 *
-	 * With RAS_EXTENSION, this macro synchronizes pending errors with an ESB
-	 * instruction. When an error is thus synchronized, the handling is
+	 * With RAS_FFH_SUPPORT, this macro synchronizes pending errors with an
+	 * ESB instruction. When an error is thus synchronized, the handling is
 	 * delegated to platform EA handler.
 	 *
-	 * Without RAS_EXTENSION, this macro synchronizes pending errors using
-         * a DSB, unmasks Asynchronous External Aborts and saves X30 before
+	 * Without RAS_FFH_SUPPORT, this macro synchronizes pending errors using
+	 * a DSB, unmasks Asynchronous External Aborts and saves X30 before
 	 * setting the flag CTX_IS_IN_EL3.
 	 */
 	.macro check_and_unmask_ea
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	/* Synchronize pending External Aborts */
 	esb
 
@@ -72,9 +72,7 @@
 
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
-	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
-	 * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
-	 * Also set the PSTATE to a known state.
+	 * Also save PMCR_EL0 and  set the PSTATE to a known state.
 	 */
 	bl	prepare_el3_entry
 
@@ -164,9 +162,7 @@
 
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
-	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
-	 * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
-	 * Also set the PSTATE to a known state.
+	 * Also save PMCR_EL0 and  set the PSTATE to a known state.
 	 */
 	bl	prepare_el3_entry
 
@@ -307,7 +303,7 @@
 end_vector_entry fiq_sp_elx
 
 vector_entry serror_sp_elx
-#if !RAS_EXTENSION
+#if !RAS_FFH_SUPPORT
 	/*
 	 * This will trigger if the exception was taken due to SError in EL3 or
 	 * because of pending asynchronous external aborts from lower EL that got
@@ -359,7 +355,7 @@
 vector_entry serror_aarch64
 	save_x30
 	apply_at_speculative_wa
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	msr	daifclr, #DAIF_ABT_BIT
 #else
 	check_and_unmask_ea
@@ -402,7 +398,7 @@
 vector_entry serror_aarch32
 	save_x30
 	apply_at_speculative_wa
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	msr	daifclr, #DAIF_ABT_BIT
 #else
 	check_and_unmask_ea
@@ -440,9 +436,7 @@
 
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
-	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
-	 * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
-	 * Also set the PSTATE to a known state.
+	 * Also save PMCR_EL0 and  set the PSTATE to a known state.
 	 */
 	bl	prepare_el3_entry
 
@@ -506,6 +500,17 @@
 	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
 	bfi	x7, x18, #0, #1
 
+	mov	sp, x12
+
+	/*
+	 * Per SMCCC documentation, bits [23:17] must be zero for Fast
+	 * SMCs. Other values are reserved for future use. Ensure that
+	 * these bits are zeroes, if not report as unknown SMC.
+	 */
+	tbz	x0, #FUNCID_TYPE_SHIFT, 2f  /* Skip check if its a Yield Call*/
+	tst	x0, #(FUNCID_FC_RESERVED_MASK << FUNCID_FC_RESERVED_SHIFT)
+	b.ne	smc_unknown
+
 	/*
 	 * Per SMCCCv1.3 a caller can set the SVE hint bit in the SMC FID
 	 * passed through x0. Copy the SVE hint bit to flags and mask the
@@ -513,11 +518,11 @@
 	 * A service/dispatcher can retrieve the SVE hint bit state from
 	 * flags using the appropriate helper.
 	 */
-	bfi	x7, x0, #FUNCID_SVE_HINT_SHIFT, #FUNCID_SVE_HINT_MASK
+2:
+	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)
 
-	mov	sp, x12
-
 	/* Get the unique owning entity number */
 	ubfx	x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
 	ubfx	x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
@@ -584,7 +589,7 @@
 	 * Unknown SMC call. Populate return value with SMC_UNK and call
 	 * el3_exit() which will restore the remaining architectural state
 	 * i.e., SYS, GP and PAuth registers(if any) prior to issuing the ERET
-         * to the desired lower EL.
+	 * to the desired lower EL.
 	 */
 	mov	x0, #SMC_UNK
 	str	x0, [x6, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index c829058..7a8c41a 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -26,6 +26,8 @@
 #endif /* PLAT_EXTRA_LD_SCRIPT */
 
 SECTIONS {
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
     . = BL31_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -40,6 +42,7 @@
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(SORT(.text*)))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -60,6 +63,7 @@
         . = ALIGN(8);
 
 #   include <lib/el3_runtime/pubsub_events.h>
+        __RODATA_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -132,7 +136,10 @@
     RELA_SECTION >RAM
 
 #ifdef BL31_PROGBITS_LIMIT
-    ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
+    ASSERT(
+        . <= BL31_PROGBITS_LIMIT,
+        "BL31 progbits has exceeded its limit. Consider disabling some features."
+    )
 #endif /* BL31_PROGBITS_LIMIT */
 
 #if SEPARATE_NOBITS_REGION
@@ -195,6 +202,7 @@
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
 #endif /* SEPARATE_NOBITS_REGION */
+    RAM_REGION_END = .;
 
     /DISCARD/ : {
         *(.dynsym .dynstr .hash .gnu.hash)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index e9590d5..0c1d657 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -54,10 +54,6 @@
 				${SPMC_SOURCES}					\
 				${SPM_SOURCES}
 
-ifeq (${DISABLE_MTPMU},1)
-BL31_SOURCES		+=	lib/extensions/mtpmu/aarch64/mtpmu.S
-endif
-
 ifeq (${ENABLE_PMF}, 1)
 BL31_SOURCES		+=	lib/pmf/pmf_main.c
 endif
@@ -87,11 +83,15 @@
 				services/std_svc/trng/trng_entropy_pool.c
 endif
 
-ifeq (${ENABLE_SPE_FOR_LOWER_ELS},1)
+ifneq (${ENABLE_SPE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/spe/spe.c
 endif
 
-ifeq (${ENABLE_AMU},1)
+ifeq (${ERRATA_ABI_SUPPORT},1)
+BL31_SOURCES		+=	services/std_svc/errata_abi/errata_abi_main.c
+endif
+
+ifneq (${ENABLE_FEAT_AMU},0)
 BL31_SOURCES		+=	${AMU_SOURCES}
 endif
 
@@ -99,16 +99,14 @@
 BL31_SOURCES		+=	${MPMM_SOURCES}
 endif
 
-ifeq (${ENABLE_SME_FOR_NS},1)
+ifneq (${ENABLE_SME_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sme/sme.c
-BL31_SOURCES		+=	lib/extensions/sve/sve.c
-else
-ifeq (${ENABLE_SVE_FOR_NS},1)
-BL31_SOURCES		+=	lib/extensions/sve/sve.c
 endif
+ifneq (${ENABLE_SVE_FOR_NS},0)
+BL31_SOURCES		+=	lib/extensions/sve/sve.c
 endif
 
-ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1)
+ifneq (${ENABLE_MPAM_FOR_LOWER_ELS},0)
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
 endif
 
@@ -120,7 +118,7 @@
 BL31_SOURCES		+=	lib/extensions/brbe/brbe.c
 endif
 
-ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
+ifneq (${ENABLE_SYS_REG_TRACE_FOR_NS},0)
 BL31_SOURCES		+=      lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
 endif
 
@@ -159,6 +157,12 @@
 
 BL31_DEFAULT_LINKER_SCRIPT_SOURCE := bl31/bl31.ld.S
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL31_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL31_LDFLAGS	+=	--sort-section=alignment
+endif
+
 # Flag used to indicate if Crash reporting via console should be included
 # in BL31. This defaults to being present in DEBUG builds only
 ifndef CRASH_REPORTING
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index e70eb55..8f1f043 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -112,6 +112,9 @@
  ******************************************************************************/
 void bl31_main(void)
 {
+	/* Init registers that never change for the lifetime of TF-A */
+	cm_manage_extensions_el3();
+
 	NOTICE("BL31: %s\n", version_string);
 	NOTICE("BL31: %s\n", build_message);
 
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index b12185d..2cfe14a 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -11,13 +12,19 @@
 
 int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx)
 {
-	switch (esr_el3 & ISS_SYSREG_OPCODE_MASK) {
+	uint64_t __unused opcode = esr_el3 & ISS_SYSREG_OPCODE_MASK;
+
 #if ENABLE_FEAT_RNG_TRAP
-	case ISS_SYSREG_OPCODE_RNDR:
-	case ISS_SYSREG_OPCODE_RNDRRS:
+	if ((opcode == ISS_SYSREG_OPCODE_RNDR) || (opcode == ISS_SYSREG_OPCODE_RNDRRS)) {
 		return plat_handle_rng_trap(esr_el3, ctx);
+	}
 #endif
-	default:
-		return TRAP_RET_UNHANDLED;
+
+#if IMPDEF_SYSREG_TRAP
+	if ((opcode & ISS_SYSREG_OPCODE_IMPDEF) == ISS_SYSREG_OPCODE_IMPDEF) {
+		return plat_handle_impdef_trap(esr_el3, ctx);
 	}
+#endif
+
+	return TRAP_RET_UNHANDLED;
 }
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 1695e1e..dd81973 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -20,6 +20,8 @@
 #endif /* PLAT_SP_MIN_EXTRA_LD_SCRIPT */
 
 SECTIONS {
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
     . = BL32_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -32,6 +34,7 @@
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -56,6 +59,7 @@
         . = ALIGN(8);
 
 #   include <lib/el3_runtime/pubsub_events.h>
+        __RODATA_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -149,4 +153,5 @@
     }
 
     ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.")
+    RAM_REGION_END = .;
 }
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 2a6612a..0b7bc57 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -20,15 +20,11 @@
 				services/std_svc/std_svc_setup.c	\
 				${PSCI_LIB_SOURCES}
 
-ifeq (${DISABLE_MTPMU},1)
-BL32_SOURCES		+=	lib/extensions/mtpmu/aarch32/mtpmu.S
-endif
-
 ifeq (${ENABLE_PMF}, 1)
 BL32_SOURCES		+=	lib/pmf/pmf_main.c
 endif
 
-ifeq (${ENABLE_AMU},1)
+ifneq (${ENABLE_FEAT_AMU},0)
 BL32_SOURCES		+=	${AMU_SOURCES}
 endif
 
@@ -46,7 +42,11 @@
 				services/std_svc/trng/trng_entropy_pool.c
 endif
 
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+BL32_SOURCES		+=	services/std_svc/errata_abi/errata_abi_main.c
+endif
+
-ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
+ifneq (${ENABLE_SYS_REG_TRACE_FOR_NS},0)
 BL32_SOURCES		+=	lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
 endif
 
@@ -56,6 +56,12 @@
 
 BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/sp_min/sp_min.ld.S
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL32_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL32_LDFLAGS	+=	--sort-section=alignment
+endif
+
 # Include the platform-specific SP_MIN Makefile
 # If no platform-specific SP_MIN Makefile exists, it means SP_MIN is not supported
 # on this platform.
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index a6658dd..22bf11d 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -16,6 +16,8 @@
 }
 
 SECTIONS {
+    RAM_REGION_START = ORIGIN(RAM);
+    RAM_REGION_LENGTH = LENGTH(RAM);
     . = BL32_BASE;
 
     ASSERT(. == ALIGN(PAGE_SIZE),
@@ -28,6 +30,7 @@
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
+        __TEXT_END_UNALIGNED__ = .;
 
         . = ALIGN(PAGE_SIZE);
 
@@ -41,6 +44,7 @@
 
         RODATA_COMMON
 
+        __RODATA_END_UNALIGNED__ = .;
         . = ALIGN(PAGE_SIZE);
 
         __RODATA_END__ = .;
@@ -121,4 +125,5 @@
 #endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.")
+    RAM_REGION_END = .;
 }
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index cfffbdb..4c18131 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -24,6 +24,12 @@
 
 BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/tsp/tsp.ld.S
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL32_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL32_LDFLAGS	+=	--sort-section=alignment
+endif
+
 # This flag determines if the TSPD initializes BL32 in tspd_init() (synchronous
 # method) or configures BL31 to pass control to BL32 instead of BL33
 # (asynchronous method).
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 268d329..1c8c68f 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -91,7 +91,7 @@
 	smc_args_t ffa_forward_result;
 	ffa_endpoint_id16_t receiver = arg5;
 
-	ffa_forward_result = ffa_msg_send_direct_req(ffa_endpoint_source(arg1),
+	ffa_forward_result = ffa_msg_send_direct_req(tsp_id,
 						     receiver,
 						     FF_A_ECHO_MESSAGE, arg4,
 						     0, 0, 0);
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index df9903b..1ab2260 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -50,6 +50,8 @@
 	     tsp_stats[linear_id].smc_count,
 	     tsp_stats[linear_id].eret_count,
 	     tsp_stats[linear_id].cpu_on_count);
+
+	console_flush();
 	return (uint64_t) &tsp_vector_table;
 }
 
@@ -263,7 +265,7 @@
 		results[1] /= service_arg1 ? service_arg1 : 1;
 		break;
 	case TSP_CHECK_DIT:
-		if (!is_armv8_4_dit_present()) {
+		if (!is_feat_dit_supported()) {
 			ERROR("DIT not supported\n");
 			results[0] = 0;
 			results[1] = 0xffff;
diff --git a/changelog.yaml b/changelog.yaml
index e100f82..47cfc1e 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -101,9 +101,15 @@
       - title: Extended Cache Index (FEAT_CCIDX)
         scope: ccidx
 
+      - title: Extended Translation Control Register (FEAT_TCR2).
+        scope: tcr2
+
       - title: CPU feature / ID register handling in general
         scope: cpufeat
 
+      - title: Guarded Control Stack (FEAT_GCS)
+        scope: gcs
+
       - title: Support for the `HCRX_EL2` register (FEAT_HCX)
         scope: hcx
 
@@ -122,7 +128,7 @@
       - title: Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)
         scope: rng-trap
 
-      - title: Scalable Matrix Extension (FEAT_SME)
+      - title: Scalable Matrix Extension (FEAT_SME, FEAT_SME2)
         scope: sme
 
       - title: Statistical profiling Extension (FEAT_SPE)
@@ -159,11 +165,15 @@
           - plat/arm
 
         subsections:
+          - title: A5DS
+            scope: a5ds
+
           - title: CSS
             scope: css
 
             deprecated:
               - plat/arm/css
+              - plat/css
 
           - title: FPGA
             scope: fpga
@@ -202,6 +212,9 @@
             scope: rd
 
             subsections:
+              - title: RD-N1 Edge
+                scope: rdn1edge
+
               - title: RD-N2
                 scope: rdn2
 
@@ -218,6 +231,9 @@
           - title: TC
             scope: tc
 
+            deprecated:
+              - plat/tc
+
             subsections:
               - title: TC0
                 scope: tc0
@@ -228,6 +244,13 @@
           - title: Corstone-1000
             scope: corstone-1000
 
+      - title: Aspeed
+        scope: aspeed
+
+        subsections:
+          - title: AST2700
+            scope: ast2700
+
       - title: Broadcom
         scope: brcm
 
@@ -329,6 +352,9 @@
               - title: Tegra 194
                 scope: tegra194
 
+              - title: Tegra 210
+                scope: tegra210
+
       - title: NXP
         scope: nxp
 
@@ -377,6 +403,16 @@
                     deprecated:
                       - plat/imx/imx8m/imx8mq
 
+              - title: i.MX 8
+                scope: imx8
+
+              - title: i.MX 9
+                scope: imx9
+
+                subsections:
+                  - title: i.MX93
+                    scope: imx93
+
           - title: Layerscape
             scope: layerscape
 
@@ -459,6 +495,10 @@
         deprecated:
           - plat/qemu
 
+        subsections:
+          - title: SBSA
+            scope: qemu-sbsa
+
       - title: QTI
         scope: qti
 
@@ -634,6 +674,9 @@
           - title: RMMD
             scope: rmmd
 
+          - title: RMM
+            scope: rmm
+
       - title: SPM
         scope: spm
 
@@ -656,6 +699,9 @@
       - title: TRNG
         scope: trng
 
+      - title: ERRATA_ABI
+        scope: errata_abi
+
   - title: Libraries
 
     subsections:
@@ -802,6 +848,9 @@
       - title: GUID Partition Tables Support
         scope: guid-partition
 
+        deprecated:
+          - partition
+
       - title: SCMI
         scope: scmi
 
@@ -871,6 +920,9 @@
                 deprecated:
                   - drivers/tzc380
 
+          - title: SBSA
+            scope: sbsa
+
       - title: Marvell
         scope: marvell-drivers
 
@@ -999,6 +1051,9 @@
           - title: TZC-380
             scope: nxp-tzc380
 
+          - title: TRDC
+            scope: imx-trdc
+
       - title: Renesas
         scope: renesas-drivers
 
@@ -1166,6 +1221,9 @@
       - title: PIE
         scope: pie
 
+      - title: PIE/POR
+        scope: pie/por
+
       - title: Security
         scope: security
 
@@ -1190,6 +1248,9 @@
             deprecated:
               - plat/nxp/common/psci
 
+      - title: UUID
+        scope: uuid
+
   - title: Documentation
     scope: docs
 
@@ -1219,6 +1280,9 @@
       - title: Threat Model
         scope: threat-model
 
+      - title: Porting Guide
+        scope: porting
+
   - title: Build System
     scope: build
 
@@ -1230,6 +1294,9 @@
       - title: Git Hooks
         scope: hooks
 
+        deprecated:
+          - git-hooks
+
   - title: Tools
 
     subsections:
@@ -1251,6 +1318,9 @@
       - title: Certificate Creation Tool
         scope: cert-create
 
+      - title: Memory Mapping Tool
+        scope: memmap
+
         deprecated:
           - cert_create
 
@@ -1275,4 +1345,3 @@
 
       - title: zlib
         scope: zlib
-
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 4099732..d2e94e9 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.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
  */
@@ -60,56 +60,6 @@
 	}
 }
 
-/******************************************
- * Feature : FEAT_SB (Speculation Barrier)
- *****************************************/
-static void read_feat_sb(void)
-{
-#if (ENABLE_FEAT_SB == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_0_feat_sb_present(), "SB");
-#endif
-}
-
-/******************************************************
- * Feature : FEAT_CSV2_2 (Cache Speculation Variant 2)
- *****************************************************/
-static void read_feat_csv2_2(void)
-{
-#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
-#endif
-}
-
-/***********************************************
- * Feature : FEAT_PAN (Privileged Access Never)
- **********************************************/
-static void read_feat_pan(void)
-{
-#if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_1_pan_present(), "PAN");
-#endif
-}
-
-/******************************************************
- * Feature : FEAT_VHE (Virtualization Host Extensions)
- *****************************************************/
-static void read_feat_vhe(void)
-{
-#if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_1_vhe_present(), "VHE");
-#endif
-}
-
-/*******************************************************************************
- * Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension)
- ******************************************************************************/
-static void read_feat_ras(void)
-{
-#if (RAS_EXTENSION == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
-#endif
-}
-
 /************************************************
  * Feature : FEAT_PAUTH (Pointer Authentication)
  ***********************************************/
@@ -120,48 +70,6 @@
 #endif
 }
 
-/************************************************************
- * Feature : FEAT_DIT (Data Independent Timing Instructions)
- ***********************************************************/
-static void read_feat_dit(void)
-{
-#if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
-#endif
-}
-
-/****************************************************************************
- * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
- ***************************************************************************/
-static void read_feat_mpam(void)
-{
-#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS)
-	feat_detect_panic(get_mpam_version() != 0U, "MPAM");
-#endif
-}
-
-/**************************************************************
- * Feature : FEAT_NV2 (Enhanced Nested Virtualization Support)
- *************************************************************/
-static void read_feat_nv2(void)
-{
-#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS)
-	unsigned int nv = get_armv8_4_feat_nv_support();
-
-	feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2");
-#endif
-}
-
-/***********************************
- * Feature : FEAT_SEL2 (Secure EL2)
- **********************************/
-static void read_feat_sel2(void)
-{
-#if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_4_sel2_present(), "SEL2");
-#endif
-}
-
 /************************************************
  * Feature : FEAT_MTE (Memory Tagging Extension)
  ***********************************************/
@@ -174,16 +82,6 @@
 #endif
 }
 
-/***********************************************
- * Feature : FEAT_RNG (Random Number Generator)
- **********************************************/
-static void read_feat_rng(void)
-{
-#if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_5_rng_present(), "RNG");
-#endif
-}
-
 /****************************************************
  * Feature : FEAT_BTI (Branch Target Identification)
  ***************************************************/
@@ -194,39 +92,6 @@
 #endif
 }
 
-/***********************************************
- * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
- **********************************************/
-static void read_feat_amuv1p1(void)
-{
-#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1");
-#endif
-}
-
-/*******************************************************
- * Feature : FEAT_ECV (Enhanced Counter Virtualization)
- ******************************************************/
-static void read_feat_ecv(void)
-{
-#if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS)
-	unsigned int ecv = get_armv8_6_ecv_support();
-
-	feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) ||
-			(ecv == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH)), "ECV");
-#endif
-}
-
-/***********************************************************
- * Feature : FEAT_TWED (Delayed Trapping of WFE Instruction)
- **********************************************************/
-static void read_feat_twed(void)
-{
-#if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_6_twed_present(), "TWED");
-#endif
-}
-
 /**************************************************
  * Feature : FEAT_RME (Realm Management Extension)
  *************************************************/
@@ -276,40 +141,63 @@
 	tainted = false;
 
 	/* v8.0 features */
-	read_feat_sb();
-	read_feat_csv2_2();
+	check_feature(ENABLE_FEAT_SB, read_feat_sb_id_field(), "SB", 1, 1);
+	check_feature(ENABLE_FEAT_CSV2_2, read_feat_csv2_id_field(),
+		      "CSV2_2", 2, 3);
+	/*
+	 * Even though the PMUv3 is an OPTIONAL feature, it is always
+	 * implemented and Arm prescribes so. So assume it will be there and do
+	 * away with a flag for it. This is used to check minor PMUv3px
+	 * revisions so that we catch them as they come along
+	 */
+	check_feature(FEAT_STATE_ALWAYS, read_feat_pmuv3_id_field(),
+		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P7);
 
 	/* v8.1 features */
-	read_feat_pan();
-	read_feat_vhe();
+	check_feature(ENABLE_FEAT_PAN, read_feat_pan_id_field(), "PAN", 1, 3);
+	check_feature(ENABLE_FEAT_VHE, read_feat_vhe_id_field(), "VHE", 1, 1);
 
 	/* v8.2 features */
-	read_feat_ras();
+	check_feature(ENABLE_SVE_FOR_NS, read_feat_sve_id_field(),
+		      "SVE", 1, 1);
+	check_feature(ENABLE_FEAT_RAS, read_feat_ras_id_field(), "RAS", 1, 2);
 
 	/* v8.3 features */
 	read_feat_pauth();
 
 	/* v8.4 features */
-	read_feat_dit();
-	check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(),
+	check_feature(ENABLE_FEAT_DIT, read_feat_dit_id_field(), "DIT", 1, 1);
+	check_feature(ENABLE_FEAT_AMU, read_feat_amu_id_field(),
 		      "AMUv1", 1, 2);
-	read_feat_mpam();
-	read_feat_nv2();
-	read_feat_sel2();
+	check_feature(ENABLE_MPAM_FOR_LOWER_ELS, read_feat_mpam_version(),
+		      "MPAM", 1, 17);
+	check_feature(CTX_INCLUDE_NEVE_REGS, read_feat_nv_id_field(),
+		      "NV2", 2, 2);
+	check_feature(ENABLE_FEAT_SEL2, read_feat_sel2_id_field(),
+		      "SEL2", 1, 1);
 	check_feature(ENABLE_TRF_FOR_NS, read_feat_trf_id_field(),
 		      "TRF", 1, 1);
 
 	/* v8.5 features */
 	read_feat_mte();
-	read_feat_rng();
+	check_feature(ENABLE_FEAT_RNG, read_feat_rng_id_field(), "RNG", 1, 1);
 	read_feat_bti();
 	read_feat_rng_trap();
 
 	/* v8.6 features */
-	read_feat_amuv1p1();
+	check_feature(ENABLE_FEAT_AMUv1p1, read_feat_amu_id_field(),
+		      "AMUv1p1", 2, 2);
 	check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT", 1, 1);
-	read_feat_ecv();
-	read_feat_twed();
+	check_feature(ENABLE_FEAT_ECV, read_feat_ecv_id_field(), "ECV", 1, 2);
+	check_feature(ENABLE_FEAT_TWED, read_feat_twed_id_field(),
+		      "TWED", 1, 1);
+
+	/*
+	 * even though this is a "DISABLE" it does confusingly perform feature
+	 * enablement duties like all other flags here. Check it against the HW
+	 * feature when we intend to diverge from the default behaviour
+	 */
+	check_feature(DISABLE_MTPMU, read_feat_mtpmu_id_field(), "MTPMU", 1, 1);
 
 	/* v8.7 features */
 	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX", 1, 1);
@@ -317,6 +205,14 @@
 	/* v8.9 features */
 	check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(),
 		      "TCR2", 1, 1);
+	check_feature(ENABLE_FEAT_S2PIE, read_feat_s2pie_id_field(),
+		      "S2PIE", 1, 1);
+	check_feature(ENABLE_FEAT_S1PIE, read_feat_s1pie_id_field(),
+		      "S1PIE", 1, 1);
+	check_feature(ENABLE_FEAT_S2POE, read_feat_s2poe_id_field(),
+		      "S2POE", 1, 1);
+	check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
+		      "S1POE", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
@@ -325,6 +221,14 @@
 		      "TRBE", 1, 1);
 
 	/* v9.2 features */
+	check_feature(ENABLE_SME_FOR_NS, read_feat_sme_id_field(),
+		      "SME", 1, 2);
+	check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
+		      "SME2", 2, 2);
+
+	/* v9.4 features */
+	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
+
 	read_feat_rme();
 
 	if (tainted) {
diff --git a/common/uuid.c b/common/uuid.c
index 3e47eb4..969eda1 100644
--- a/common/uuid.c
+++ b/common/uuid.c
@@ -1,12 +1,11 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include <errno.h>
-#include <stdint.h>
 #include <string.h>
 
 #include <common/debug.h>
diff --git a/docs/Makefile b/docs/Makefile
index 3dd7ebc..5bc24db 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+# Copyright (c) 2019-2023, ARM Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,13 +13,20 @@
 SOURCEDIR     = .
 BUILDDIR      = build
 
+V ?= 0
+ifeq ($(V),0)
+  Q := @
+else
+  Q :=
+endif
+
 # Put it first so that "make" without argument is like "make help".
 help:
-	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+	${Q}$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 .PHONY: help Makefile
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 %: Makefile
-	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+	${Q}$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/about/features.rst b/docs/about/features.rst
index cb8b552..4a2c77e 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -22,8 +22,8 @@
    Cache Coherent Network (CCN), Network Interconnect (NIC) and TrustZone
    Controller (TZC).
 
--  A generic |SCMI| driver to interface with conforming power controllers, for
-   example the Arm System Control Processor (SCP).
+-  Secure Monitor library code such as world switching, EL2/EL1 context
+   management and interrupt routing.
 
 -  SMC (Secure Monitor Call) handling, conforming to the `SMC Calling
    Convention`_ using an EL3 runtime services framework.
@@ -34,14 +34,22 @@
    is also suitable for integration with other AArch32 EL3 Runtime Software,
    for example an AArch32 Secure OS.
 
+-  A generic |SCMI| driver to interface with conforming power controllers, for
+   example the Arm System Control Processor (SCP).
+
 -  A minimal AArch32 Secure Payload (*SP_MIN*) to demonstrate |PSCI| library
    integration with AArch32 EL3 Runtime Software.
 
--  Secure Monitor library code such as world switching, EL1 context management
-   and interrupt routing.
-   When a Secure-EL1 Payload (SP) is present, for example a Secure OS, the
-   AArch64 EL3 Runtime Software must be integrated with a Secure Payload
-   Dispatcher (SPD) component to customize the interaction with the SP.
+-  Secure partition manager dispatcher(SPMD) with following two configurations:
+
+   -  S-EL2 SPMC implementation, widely compliant with FF-A v1.1 EAC0 and initial
+      support of FF-A v1.2.
+
+   -  EL3 SPMC implementation, compliant with a subset of FF-A v1.1 EAC0.
+
+-  Support for Arm CCA based on FEAT_RME which supports authenticated boot and
+   execution of RMM with the necessary routing of RMI commands as specified in
+   RMM Beta 0 Specification.
 
 -  A Test SP and SPD to demonstrate AArch64 Secure Monitor functionality and SP
    interaction with PSCI.
@@ -50,12 +58,20 @@
    `Trusty Secure OS`_ and `ProvenCore Secure OS`_.
 
 -  A Trusted Board Boot implementation, conforming to all mandatory TBBR
-   requirements. This includes image authentication, Firmware Update (or
-   recovery mode), and packaging of the various firmware images into a
+   requirements. This includes image authentication, Firmware recovery,
+   Firmware encryption and packaging of the various firmware images into a
    Firmware Image Package (FIP).
 
--  Pre-integration of TBB with the Arm CryptoCell product, to take advantage of
-   its hardware Root of Trust and crypto acceleration services.
+-  Measured boot support with PoC to showcase its interaction with firmware TPM
+   (fTPM) service implemneted on top of OP-TEE.
+
+-  Support for Dynamic Root of Trust for Measurement (DRTM).
+
+-  Following firmware update mechanisms available:
+
+   -  PSA Firmware Update (PSA FWU)
+
+   -  TBBR Firmware Update (TBBR FWU)
 
 -  Reliability, Availability, and Serviceability (RAS) functionality, including
 
@@ -81,6 +97,8 @@
    secure system processor, or where a non-TF-A ROM expects BL2 to be loaded
    at EL3.
 
+-  Support for Errata management firmware interface.
+
 -  Support for the GCC, LLVM and Arm Compiler 6 toolchains.
 
 -  Support for combining several libraries into a "romlib" image that may be
@@ -88,27 +106,13 @@
    in ROM but is accessed through a jump-table that may be stored
    in read-write memory, allowing for the library code to be patched.
 
--  Support for the Secure Partition Manager Dispatcher (SPMD) component as a
-   new standard service.
-
--  Support for ARMv8.3 pointer authentication in the normal and secure worlds.
-   The use of pointer authentication in the normal world is enabled whenever
-   architectural support is available, without the need for additional build
-   flags.
-
--  Position-Independent Executable (PIE) support. Currently for BL2, BL31, and
-   TSP, with further support to be added in a future release.
+-  Position-Independent Executable (PIE) support.
 
 Still to come
 -------------
 
 -  Support for additional platforms.
 
--  Refinements to Position Independent Executable (PIE) support.
-
--  Continued support for the FF-A v1.0 (formally known as SPCI) specification, to enable the
-   use of secure partition management in the secure world.
-
 -  Documentation enhancements.
 
 -  Ongoing support for new architectural features, CPUs and System IP.
@@ -125,4 +129,4 @@
 
 --------------
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 914c959..663859f 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -2,12 +2,11 @@
 ===================
 
 Trusted Firmware-A (TF-A) is an open governance community project. All
-contributions are ultimately merged by the maintainers listed below. Technical
-ownership of most parts of the codebase falls on the code owners listed
-below. An acknowledgement from these code owners is required before the
-maintainers merge a contribution.
+contributions are reviewed and merged by the community members listed below.
 
-More details may be found in the `Project Maintenance Process`_ document.
+For more details on the roles of `maintainers`, `code owners` and general
+information about code reviews in TF-A project, please refer to the :ref:`Code
+Review Guidelines`.
 
 .. |M| replace:: **Mail**
 .. |G| replace:: **GitHub ID**
@@ -18,6 +17,10 @@
 Maintainers
 -----------
 
+.. note::
+   If you wish to become a maintainer for TF-A project, please refer to the
+   :ref:`Project Maintenance Processes`.
+
 :|M|: Dan Handley <dan.handley@arm.com>
 :|G|: `danh-arm`_
 :|M|: Soby Mathew <soby.mathew@arm.com>
@@ -50,6 +53,8 @@
 :|G|: `raghuncstate`_
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
+:|M|: Yann Gautier <yann.gautier@st.com>
+:|G|: `Yann-lms`_
 
 LTS Maintainers
 ---------------
@@ -98,6 +103,8 @@
 :|G|: `ManishVB-Arm`_
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: drivers/auth/
 
 Secure Partition Manager Core (EL3 FF-A SPMC)
@@ -175,10 +182,14 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Joshua Slater <joshua.slater@arm.com>
 :|G|: `jslater8`_
-:|M|: Mikael Olsson <mikael.olsson@arm.com>
-:|G|: `mikaelolsson-arm`_
+:|M|: Åžtefana Simion <stefana.simion@arm.com>
+:|G|: `stefanasimion`_
 :|F|: drivers/arm/ethosn/
 :|F|: include/drivers/arm/ethosn.h
+:|F|: include/drivers/arm/ethosn_cert.h
+:|F|: include/drivers/arm/ethosn_fip.h
+:|F|: include/drivers/arm/ethosn_oid.h
+:|F|: plat/arm/board/juno/juno_ethosn_tzmp1_def.h
 :|F|: plat/arm/common/fconf/fconf_ethosn_getter.c
 :|F|: include/plat/arm/common/fconf_ethosn_getter.h
 :|F|: fdts/juno-ethosn.dtsi
@@ -351,6 +362,8 @@
 :|G|: `sandrine-bailleux-arm`_
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: drivers/measured_boot
 :|F|: include/drivers/measured_boot
 :|F|: docs/components/measured_boot
@@ -377,6 +390,8 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
 :|G|: `sandrine-bailleux-arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: include/lib/psa
 :|F|: lib/psa
 
@@ -473,8 +488,8 @@
 
 Arm Morello and N1SDP Platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Manoj Kumar <manoj.kumar3@arm.com>
-:|G|: `manojkumar-arm`_
+:|M|: Anurag Koul <anurag.koul@arm.com>
+:|G|: `anukou`_
 :|M|: Chandni Cherukuri <chandni.cherukuri@arm.com>
 :|G|: `chandnich`_
 :|F|: plat/arm/board/morello
@@ -512,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>
@@ -543,6 +567,10 @@
 :|G|: `mtk-rex-bc-chen`_
 :|M|: Leon Chen <leon.chen@mediatek.com>
 :|G|: `leon-chen-mtk`_
+:|M|: Jason-CH Chen <jason-ch.chen@mediatek.com>
+:|G|: `jason-ch-chen`_
+:|M|: Yidi Lin <yidilin@chromium.org>
+:|G|: `linyidi`_
 :|F|: docs/plat/mt\*.rst
 :|F|: plat/mediatek/
 
@@ -836,6 +864,8 @@
 :|G|: `ManishVB-Arm`_
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: tools/cert_create/
 
 Encrypt_fw tool
@@ -904,11 +934,12 @@
 .. _marex: https://github.com/marex
 .. _masahir0y: https://github.com/masahir0y
 .. _michalsimek: https://github.com/michalsimek
-.. _mikaelolsson-arm: https://github.com/mikaelolsson-arm
 .. _mmind: https://github.com/mmind
 .. _MrVan: https://github.com/MrVan
 .. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
 .. _leon-chen-mtk: https://github.com/leon-chen-mtk
+.. _jason-ch-chen: https://github.com/jason-ch-chen
+.. _linyidi: https://github.com/linyidi
 .. _niej: https://github.com/niej
 .. _npoushin: https://github.com/npoushin
 .. _prabhakarlad: https://github.com/prabhakarlad
@@ -921,6 +952,7 @@
 .. _smaeul: https://github.com/smaeul
 .. _soby-mathew: https://github.com/soby-mathew
 .. _sreekare: https://github.com/sreekare
+.. _stefanasimion: https://github.com/stefanasimion
 .. _stephan-gh: https://github.com/stephan-gh
 .. _sieumunt: https://github.com/sieumunt
 .. _BenjaminLimJL: https://github.com/BenjaminLimJL
@@ -944,7 +976,7 @@
 .. _raghuncstate: https://github.com/raghuncstate
 .. _CJKay: https://github.com/cjkay
 .. _nmenon: https://github.com/nmenon
-.. _manojkumar-arm: https://github.com/manojkumar-arm
+.. _anukou: https://github.com/anukou
 .. _chandnich: https://github.com/chandnich
 .. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
 .. _vishnu-banavath: https://github.com/vishnu-banavath
@@ -959,5 +991,6 @@
 .. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
 .. _bytefire: https://github.com/bytefire
 .. _rupsin01: https://github.com/rupsin01
-
-.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
+.. _jimmy-brisson: https://github.com/theotherjimmy
+.. _ChiaweiW: https://github.com/chiaweiw
+.. _Neal-liu: https://github.com/neal-liu
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index f99b7ff..0768e1f 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -52,7 +52,9 @@
 +-----------------+---------------------------+------------------------------+
 | v2.8            | 5th week of Nov '22       | 3rd week of Nov '22          |
 +-----------------+---------------------------+------------------------------+
-| v2.9            | 1st week of May '23       | 3rd week of Apr '23          |
+| v2.9            | 4th week of May '23       | 2nd week of May '23          |
++-----------------+---------------------------+------------------------------+
+| v3.0            | 2nd week of Nov '23       | 2nd week of Oct '23          |
 +-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
@@ -67,11 +69,26 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
+| None at this time              |             |         |                                                         |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+
+Removal of Deprecated Drivers
+-----------------------------
+
+As mentioned in the :ref:`Platform Ports Policy`, this is a live document
+cataloging all the deprecated drivers in TF-A project and the Release version
+after which it will be removed.
+
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| Driver                         | Deprecation | Removed | Comments                                                |
+|                                | Date        | after   |                                                         |
+|                                |             | Release |                                                         |
++================================+=============+=========+=========================================================+
-| plat_convert_pk() function     |   Nov'22    |   2.9   | Platform conversion to manage specific PK hash          |
+| CryptoCell-712                 |     2.9     |   3.0   | No longer maintained.                                   |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
-| io_dummy driver                |   Nov'22    |   2.9   | No more used by any upstream platform                   |
+| CryptoCell-713                 |     2.9     |   3.0   | No longer maintained.                                   |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 --------------
 
-*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/change-log.md b/docs/change-log.md
index bb05afb..b660c73 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,1024 @@
 This document contains a summary of the new features, changes, fixes and known
 issues in each release of Trusted Firmware-A.
 
+## [2.9.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.8.0..refs/tags/v2.9.0) (2023-05-16)
+
+### âš  BREAKING CHANGES
+
+- **Libraries**
+
+  - **EL3 Runtime**
+
+    - **RAS**
+
+      - The previous RAS_EXTENSION is now deprecated. The equivalent functionality can be achieved by the following 2 options:
+         - ENABLE_FEAT_RAS
+         - RAS_FFH_SUPPORT
+
+        **See:** replace RAS_EXTENSION with FEAT_RAS ([9202d51](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9202d51990c192e8bc041e6f53d5ce63ee908665))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - unify REGISTER_CRYPTO_LIB
+
+      **See:** unify REGISTER_CRYPTO_LIB ([dee99f1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dee99f10b1dcea09091f4a1d53185153802dfb64))
+
+  - **Arm**
+
+    - **Ethos-N**
+
+      - The Linux Kernel NPU driver can no longer directly configure and boot the NPU in a TZMP1 build. The API version has therefore been given a major version bump with this change.
+
+        **See:** add protected NPU firmware setup ([6dcf3e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dcf3e774457cf00b91abda715adfbefce822877))
+
+      - Building the FIP when TZMP1 support is enabled in the NPU driver now requires a parameter to specify the NPU firmware file.
+
+        **See:** load NPU firmware at BL2 ([33bcaed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33bcaed1211ab27968433b546979687bc1182630))
+
+- **Build System**
+
+  - BL2_AT_EL3 renamed to RESET_TO_BL2 across the repository.
+
+    **See:** distinguish BL2 as TF-A entry point and BL2 running at EL3 ([42d4d3b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42d4d3baacb3b11c68163ec85de1bf2e34e0c882))
+
+  - check boolean flags are not empty
+
+    **See:** check boolean flags are not empty ([1369fb8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1369fb82c8e809c1a59a0d99184dbfd2d0b81afa))
+
+  - All input and output linker section names have been prefixed with the period character, e.g. `cpu_ops` -> `.cpu_ops`.
+
+    **See:** always prefix section names with `.` ([da04341](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/da04341ed52d214139fe2d16667ef5b58c38e502))
+
+  - The `EXTRA_LINKERFILE` build system variable has been replaced with the `<IMAGE>_LINKER_SCRIPT_SOURCES` variable. See the commit message for more information.
+
+    **See:** permit multiple linker scripts ([a6ff006](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6ff0067ab57d848d3fb28a3eb2b47e6cf2a6092))
+
+  - The `LINKERFILE`, `BL_LINKERFILE` and `<IMAGE_LINKERFILE>` build system variables have been renamed. See the commit message for more information.
+
+    **See:** clarify linker script generation ([8227493](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/82274936374bf630bf5256370e93a531fdda6372))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **CPU feature / ID register handling in general**
+
+    - context-switch: move FGT availability check to callers ([de8c489](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de8c489247458c00f7b48301fb5c5273c7a628fc))
+    - make stub enable functions "static inline" ([d7f3ed3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7f3ed3655b85223583d8c2d9e719f364266ef26))
+    - resolve build errors due to compiler optimization ([e8f0dd5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8f0dd58da231b81ba0ce6f27aaf1e31b4d4c429))
+
+  - **Memory Partitioning and Monitoring (MPAM) Extension (FEAT_MPAM)**
+
+    - feat_detect: support major/minor ([1f8be7f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f8be7fc66fb59b197dde3b4ea83314b1728c6b8))
+    - remove unwanted param for "endfunc" macro ([0e0bd25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e0bd250ef08ba70b34db9eb0cab0f6ef4d08edf))
+    - run-time checks for mpam save/restore routines ([ed80440](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed804406bf2ee04bde1c17683cec6f679ea1e160))
+
+  - **Pointer Authentication Extension**
+
+    - make pauth_helpers linking generic ([90ce8b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/90ce8b8718d079b9e906d06bdd6a72da6cc5b636))
+
+  - **Performance Monitors Extension (FEAT_PMUv3)**
+
+    - switch FVP PMUv3 SPIs to PPI ([d7c455d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7c455d8cca85de4a520da33db6523c9c8a7ee38))
+    - unconditionally save PMCR_EL0 ([1d6d680](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d6d6802dd547c8b378a9a47572ee72e68cceb3b))
+
+  - **Scalable Matrix Extension (FEAT_SME, FEAT_SME2)**
+
+    - disable SME for SPD=spmd ([2fd2fce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2fd2fcedff0595a7050328fa60dc4850d6b424bf))
+
+  - **Statistical profiling Extension (FEAT_SPE)**
+
+    - drop SPE EL2 context switch code ([16e3ddb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16e3ddba1f049106387dfe21989243d2fc4cf061))
+
+- **Platforms**
+
+  - **Allwinner**
+
+    - check RSB availability in DT on H6 ([658b315](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/658b3154d5b06a467b65cb79d31da751ffc6f5a4))
+
+  - **Arm**
+
+    - arm_rotpk_header undefined reference ([95302e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95302e4b234589e0487996a5c0f1e111c21ffedc))
+
+    - **A5DS**
+
+      - add default value for ARM_DISABLE_TRUSTED_WDOG ([115ab63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/115ab63872ab36f8202f4c4aab093c4e9182d4e7))
+
+    - **CSS**
+
+      - fix invalid redistributor poweroff ([60719e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/60719e4e0965aead49d927f12bf2a37bd2629012))
+
+    - **FPGA**
+
+      - include missing header file ([b7253a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7253a14cdc633a606472ec4e5aa4123158e2013))
+
+    - **FVP**
+
+      - correct ehf priority for SPM_MM ([fb2fd55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fb2fd558d8102ad79e5970714e0afec31a6138d7))
+      - incorrect UUID name in FVP tb_fw_config ([7f2bf23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f2bf23dec6e6467704d7d71ec44bee030912987))
+      - unconditionally include lib/psa headers ([72db458](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/72db45852d84db6ade0da2a232a44df3e5228b6d))
+      - work around BL31 progbits exceeded ([138221c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/138221c2457b9d04101b84084c07d576b0eb5a51))
+      - work around DRTM_SUPPORT BL31 progbits exceeded ([7762e5d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7762e5d0ed5c28b0a77dc25cc566cf54a69af7e6))
+
+    - **Morello**
+
+      - add platform-specific power domain functions ([02a5bcb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02a5bcb0bc3c8596894b6d0ec8c979b330db387a))
+
+    - **N1SDP**
+
+      - add platform-specific power domain functions ([5bdafc4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5bdafc4099b446609965f9132e6c52a7bdeb9ac8))
+
+    - **RD**
+
+      - **RD-N1 Edge**
+
+        - change variable type to fix gcc sign conversion error ([3a3e0e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a3e0e5371e99b3764fd8e8d98a447911f3bb915))
+
+    - **TC**
+
+      - increase TC_TZC_DRAM1_SIZE ([7e3f6a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e3f6a87d74efec780c0832c0535dd64ef830cfa))
+      - change the FIP offset to 8 KiB boundary ([d07b8aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d07b8aac39abc3026233e316686f4643d076f8d6))
+      - change the properties of optee reserved memory ([2fff46c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2fff46c80fe4aa27cd55ad4bfbe43c3823095259))
+      - enable dynamic feature detection of FEAT_SVE for NormalWorld ([67265f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/67265f2f6d7604147080033a1c99150e9a020f28))
+      - enable the execution of both platform tests ([657b90e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/657b90ea1aa2831a7feed31f07fc8e92213e6465))
+      - only suspend booting after running plat tests ([9b26655](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b266556d308c0af6f932fedd1c41fbda05204aa))
+      - unify TC ROM start addresses ([f9e11c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f9e11c724bb7c919dc9bd5dd8fca1e04140374d2))
+      - update the name of mbedtls config header ([d5fc899](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5fc8992c7b63675b6fc4b2c00a1e1acfdaaeee2))
+
+  - **Broadcom**
+
+    - add braces around bodies of conditionals ([9f58bfb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9f58bfbbe90d2891c289cd27ab7d2ede8b5572d4))
+
+  - **Intel**
+
+    - add mailbox error return status for FCS_DECRYPTION ([76ed322](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/76ed32236aa396cb0e15eb049bea03710ca1992d))
+    - agilex bitstream pre-authenticate ([4b3d323](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b3d323acdd21d8853e38e135bf990b3767ca354))
+    - fix Agilex and N5X clock manager to main PLL C0 ([5f06bff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f06bffa831638fd95d2160209000ef36d2a22ce))
+    - fix fcs_client crashed when increased param size ([c42402c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c42402cdf8a3dfc6f6e62a92b2898066e8cc46f6))
+    - fix pinmux handoff bug on Agilex ([e6c0389](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6c038909193b83bc293de9b1eb65440e75f8c91))
+    - fix print out ERROR when encounter SEU_Err ([1a0bf6e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a0bf6e1d8fe899359535c0a0a68c2be5e5acaf4))
+    - fix sp_timer0 is not disabled in firewall on Agilex ([8de7167](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8de7167eb661ff730a79bd2c6db15c22fdc62c8a))
+    - fix the pointer of block memory to fill in and bytes being set ([afe9fcc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/afe9fcc3d262ca279a747c8ab6fa8bacf79c76fb))
+    - flash dcache before mmio read ([731622f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/731622fe757ab2bcc0492ad27bafecf24206ddac))
+    - mailbox store QSPI ref clk in scratch reg ([7f9e9e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f9e9e4b40152c0cb52bcc53ac3d32fd1c978416))
+    - missing NCORE CCU snoop filter fix in BL2 ([b34a48c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b34a48c1ce0dd7e44eac4ceb0537b337857b057f))
+    - remove checking on TEMP and VOLT checking for HWMON ([68ac5fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68ac5fe14c0220673d7ee88a99b3d02be1fef530))
+    - update boot scratch to indicate to Uboot is PSCI ON ([7f7a16a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f7a16a6c0a49af593fa080eb66f72a20bb07299))
+
+  - **NVIDIA**
+
+    - **Tegra**
+
+      - append major revision to the chip_id value ([33c4766](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33c476601cf48a4b02259b8cb43819acd824804f))
+      - remove dependency on CPU registers to get boot parameters ([0b9f05f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b9f05fcaea069bff6894d99ec5babc4be29ca67))
+
+      - **Tegra 210**
+
+        - support legacy SMC_ID 0xC2FEFE00 ([40a4e2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40a4e2d84c38ffae899eaa2c33c1e280312919cf))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - add ddr4 dvfs sw workaround for ERR050712 ([e00fe11](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e00fe11df3fee04c7f3137817294d464466dab22))
+        - backup mr12/14 value from lpddr4 chip ([a2655f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2655f48697416b8350ba5b3f7f44f1f0be79d4e))
+        - correct the rank info get fro mstr ([5277c09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5277c09606450daaffa43f3cf15fcc427d7ba612))
+        - fix coverity out of bound access issue ([0331b1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0331b1c6111d198195298a2885dbd93cac1ad26a))
+        - fix the current fsp init ([25c4323](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25c43233e866326326f9f82bfae03357c396a99f))
+        - fix the dfiphymaster setting after dvfs ([ad0cbbf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad0cbbf513dfabe51a401c06be504e57d6b143ca))
+        - fix the dram retention random hang on some imx8mq Rev2.0 ([4bf5019](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4bf5019228cf89e0cbc2cd03627f755d51e3e198))
+        - fix the rank to rank space issue ([3330084](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3330084979e4c1a39a92f0642000664c79a00dda))
+
+        - **i.MX 8Q**
+
+          - fix compilation with gcc >= 12.x ([e75a3b6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e75a3b6e89c4bce11d1885426f22262def9bd664))
+
+    - **Layerscape**
+
+      - fix errata a008850 ([c45791b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c45791b2f20909c9a9d2bae84dafc17f55892fc8))
+      - fix nv_storage assert checking ([5d599b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d599b71ea6e0020f4f9d0e7af303726483217bc))
+      - unlock write access SMMU_CBn_ACTLR ([0ca1d8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ca1d8fba3bee32242b123ae28ad5c83a657aa0d))
+
+      - **LX2**
+
+        - init global data before using it ([50aa0ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/50aa0ea7acd21e7e9920a91a14db14a9f8c63700))
+
+      - **LS1046A**
+
+        - 4 keys secureboot failure resolved ([c0c157a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0c157a680fcb100afed3e1ea9d342deea72ea05))
+
+  - **QEMU**
+
+    - enable dynamic feature detection of FEAT_SVE for NormalWorld ([fc259b6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc259b6c3a551efbc810c8e08e82b7b5378f57ba))
+
+    - **SBSA**
+
+      - enable FGT ([c598692](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c598692d0c6a79dd10c34d5a4a740c90261cfc65))
+      - enable SVE and SME ([9bff7ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9bff7ce37545162d417953ac36c6878216815b94))
+
+  - **QTI**
+
+    - **MSM8916**
+
+      - add timeout for crash console TX flush ([7e002c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e002c8a13172c44f55ab49062861479b6622884))
+      - drop unneeded initialization of CNTACR ([d833af3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d833af3ab50cd2cfecb8868c3d5340df1572f042))
+      - flush dcache after writing msm8916_entry_point ([01ba69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/01ba69cd9b833047653186858a6929e6c9379989))
+      - print \r before \n on UART console ([3fb7e40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3fb7e40a21b1570a8ce1cd1708134fa7a05d94fb))
+
+  - **Raspberry Pi**
+
+    - **Raspberry Pi 3**
+
+      - initialize SD card host controller ([bd96d53](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd96d533dc28c4c938aa54905787688823cbccac))
+
+  - **Renesas**
+
+    - align incompatible function pointers ([90c4b3b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/90c4b3b62d5303c22fdc5f65f0db784de0f4ac95))
+
+  - **Rockchip**
+
+    - use semicolon instead of comma ([8557d49](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8557d491b6dbd6cbf27cc2ae6425f6cb29ca2c35))
+
+  - **ST**
+
+    - add U suffix for unsigned numbers ([9c1aa12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c1aa1253c9c77487b73d46a89941e81e80864eb))
+    - explicitly check operators precedence ([56048fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56048fe215997ab6788ebd251e8cde094392dfc7))
+    - include utils.h to solve compilation error ([377846b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/377846b65e8eb946a6560f1200ca4ca0e1eb8b99))
+    - make metadata_block_spec static ([d1d8a9b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d1d8a9bad0be53792e219625b0d327cc4855378f))
+    - rework secure-status check in fdt_get_status() ([0ebaf22](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ebaf222899c1c33fe8bd0e69bd2c287ebe1154b))
+    - use Boolean type for tests ([45d2d49](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45d2d495e77c9c8f3e80774e48a80e4882c8ac0d))
+    - use indices when counting GPIOs in DT ([e7d7544](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7d75448b9e46dee22fe23b37c28a522b9ec3a6c))
+
+    - **STM32MP1**
+
+      - add const for strings in stm32mp_get_soc_name() ([d7f5bed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7f5bed90eaacee0a223bcf23438dfb76dee08e6))
+      - add missing platform.h include ([6e55f9e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e55f9e2cde0426c39ccda87b00047f85d30f97d))
+      - always define PKA algos flags ([e0e2d64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0e2d64f47654e4d86d0e400977eab0e4a01523e))
+      - remove boolean check on PLAT_TBBR_IMG_DEF ([231a0ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/231a0adb6abc35c125d4177749af37042575eca2))
+      - rework DWL buffer cache invalidation ([127ed00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/127ed0008e03abb98b5447cb80c5634dfa554e7d))
+
+  - **Texas Instruments**
+
+    - do not take system power reference in bl31_platform_setup() ([9977948](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9977948112d732935362a3fe8518e3b2e4b7f6b7))
+    - fix typo in boot authentication message name ([81f525e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81f525ecc75a3d8b344a27881098fcaab65f2d8f))
+
+  - **Xilinx**
+
+    - fix misra defects ([964e559](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/964e55928c8f966633cc57e41987aa00890f5da7))
+    - handle CRC failure in IPI ([5e92be5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e92be5121e8ecd81a0f89eaae0d1a7ac8f4bfd7))
+    - handle CRC failure in IPI callback ([6173d91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6173d914d673249ec47c080909c31a1654545913))
+    - initialize values to device enum members ([5c62d59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5c62d599274b5d9facd4996b50c1a1e153b247a4))
+    - remove asserts around arg0/arg1 ([8be2044](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8be20446706c6b2fe911804385f308817495d2d4))
+    - remove unnecessary condition ([c984123](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c984123669a7ba7b8d1dc168db8e130ee52bbb1e))
+    - remove unused mailbox macros ([15f49cb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15f49cb49d7daf2cd771c80d3dd80ff15874b40b))
+    - resolve integer handling issue ([4e46db4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4e46db40fc86ddc0556c42ba01198d13002fcf14))
+    - use lib/smccc.h macros instead of trusty spd ([0ee07d7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ee07d796cece8074eb296415c88872504dee682))
+
+    - **Versal**
+
+      - check smc_fid 23:16 bits ([4a50363](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a50363aaeaa16edafcff17486006049b30e1e2f))
+      - fix incorrect regbase for PMC IPI ([c4185d5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4185d5103080621393edb770a56aa274f9af1a7))
+      - initialize the variable with value 0 in pm code ([cd73d62](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd73d62b0e0920ca4e6c4fea7ab65bcbd63e07de))
+      - print proper atf handoff source ([0fe002c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0fe002c9be899f005316ea196ad4c6b08815d482))
+      - replace FPD_MAINCCI* macros ([245d30e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/245d30efe617af68c674b411d63c680dca1c21dd))
+      - sync location based on IPI_ID macros ([92a43bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/92a43bdf366502c6919bbd2c8e4f687c51d9738c))
+
+      - **Versal NET**
+
+        - fix irq for IPI0 ([95bbfbc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95bbfbc6e0789cba871e2518dba76ff9bf712331))
+        - clear power down bit during wakeup ([5f0f7e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f0f7e47e05f98587d424c2162d1ce20af4f588d))
+        - clear power down interrupt status before enable ([2d056db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d056db4e4981e0f8a58de0d1e44e46058b308f4))
+        - correct aff level for cpu off ([6ada9dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ada9dc325aaa29e2f4c87575093401197856639))
+        - disable wakeup interrupt during client wakeup ([e663f09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e663f09b3cc2a3c933191c110557c6ffe5db6d6c))
+        - enable wake interrupt during client suspend ([39fffe5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/39fffe552fb04028de750e6080d9a8ba46e89b8c))
+        - fix setting power down state ([1f79bdf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f79bdfd9ae105135a0192017d6f9368045228e9))
+        - populate gic v3 rdist data statically ([355dc3d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/355dc3d4deacf73a3d354682bcda454e6d13ed66))
+        - resolve misra 10.6 warnings ([8c23775](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c23775e88bfc4ffa2b0eaf815d4f79992d344e6))
+        - resolve misra rule 20.7 warnings ([21d1966](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21d1966a23b57425a400730270c8694e37b1a85c))
+        - use spin_lock instead of bakery_lock ([0b3a2cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b3a2cf0226878ad7098cc6cd1a97ade74fd9c38))
+
+    - **ZynqMP**
+
+      - add bitmask for get_op_char API ([ad4b667](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad4b667d3ba7ece4cf28106aef6f91259b5b06ee))
+      - check return status of pm_get_api_version ([c92ad36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c92ad369ca3a548ecbf30add110b1561fe416c10))
+      - check smc_fid 23:16 bits ([09b342a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09b342a9d3aa030bde6d52e39203b9b8c8e6b106))
+      - conditional reservation of memory in DTB ([c52a142](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c52a142b7ceb397b4d66cc90f2bc717acc7263cd))
+      - enable A53 workaround(errata 1530924) ([d8133d7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d8133d7785969b417cbace293db6393c55844fac))
+      - fix bl31_zynqmp_setup.c coding style ([26ef5c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/26ef5c29c62def3a21591dd216180d86063acdb4))
+      - fix DT reserved allocated size ([2c03915](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c03915322ede112030fcfb8097d4697b92fcc2f))
+      - fix xck24 silicon ID ([f156590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f156590767d5f80e942fa3f88a9b6a94c13ceb55))
+      - initialize uint32 with value 0U in pm code ([e65584a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e65584a017fadf002d5bdd1e95527c48610a6963))
+      - move EM SMC range to SIP range ([acbae39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/acbae3998bd829ae4b31ea9da59055e3624991a5))
+      - panic w/o handoff structure in !JTAG ([fbe4dbe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbe4dbeec906038795f72d8f9284a812bd6a852d))
+      - remove redundant api_version check ([d0b58c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0b58c8a9bff3cabfdb59e052ab7eaecfe64b305))
+      - remove unused PLAT_NUM_POWER_DOMAINS ([72c3124](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/72c3124f584609275424bf52a20fd707d4f1af6a))
+      - separate EM from PM SMCs ([a911396](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a9113966c35af281e9c8972b1209646963ff55d0))
+      - update MAX_XLAT_TABLES for DDR memory range ([12446ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12446ce89e351959aebb610eb2e35cdc7eb84d26))
+      - update the conflicting EEMI API IDs ([bcc1348](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc1348b6bb2fcd987c8f047fa9f526f32768258))
+      - with DEBUG=1 move bl31 to DDR range ([2537f07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2537f0725ee7d8f46bef3e5b49134419b5c3367b))
+
+- **Bootloader Images**
+
+  - **BL31**
+
+    - avoid clearing of argument registers in RESET_TO_BL31 case ([3e14df6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3e14df6f63303adb134d525b373ec7f08c1b1dc6))
+
+  - **BL32**
+
+    - **TSP**
+
+      - loop / crash if mmap of region fails ([8c353e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c353e0058e95cfa20c9a760ebd0908a9a9aa1c1))
+      - use verbose for power logs ([3354915](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3354915fff2ad5f97551c22a44a90f4ff7b7cc9b))
+
+- **Services**
+
+  - **RME**
+
+    - update sample platform attestation token ([19c1dce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19c1dcef88cb837abe175b89739e75e27539a561))
+
+    - **TRP**
+
+      - preserve RMI SMC X4 when not used as return ([b96253d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b96253db08383c3edfb417c505c8da6f7b1dbe75))
+
+    - **RMMD**
+
+      - add missing padding to RMM Boot Manifest and initialize it ([dc0ca64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dc0ca64e4b6c86090eee025293e7ae7f1fe1cf12))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - fix coverity scan warnings ([1543d17](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1543d17b9876add1cb89c1f5ffe0e6a129f5809e))
+      - improve bound check for descriptor ([def7590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/def7590b3e34ff69b297c239cb8948d0bdc9c691))
+      - report execution state in partition info get ([62cd8f3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62cd8f3147ed7fb146168c59cab3ba0e006210ad))
+
+    - **SPMD**
+
+      - fix build error with spmd ([fd51b21](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fd51b21573ec2e0d815caecb89cc323aac0fca6d))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - do not put RAS check before using esb ([9ec2ca2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ec2ca2d453176179f923d7e0fbaac05341ebdc6))
+    - use hint instruction for "tsb csync" ([7a181b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a181b7d046a710db5238fb37047816636d2bb8a))
+    - workaround for Cortex-A510 erratum 2684597 ([aea4ccf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aea4ccf8d9f3eabbc931f0e82df65ffca28c25e5))
+    - workaround for Cortex-A710 erratum 2282622 ([89d85ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89d85ad0aad4fef7f56a9e18968b49e2b843ca9d))
+    - workaround for Cortex-A710 erratum 2768515 ([b87b02c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b87b02cf1d93f2be2113192cd5f1927e33121a80))
+    - workaround for Cortex-A78 erratum 2742426 ([a63332c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a63332c517ac5699644d3e2fbf159d3e35c32549))
+    - workaround for Cortex-A78 erratum 2772019 ([b10afcc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b10afcce5ff1202e1cd922dbd3c1e5980b478429))
+    - workaround for Cortex-A78 erratum 2779479 ([7d1700c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d1700c4d475358539c9a84cb325183c86a06f33))
+    - workaround for Cortex-A78C erratum 1827430 ([672eb21](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/672eb21e26a41657b8146372d4283e794b430c5f))
+    - workaround for Cortex-A78C erratum 1827440 ([b01a59e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b01a59eb2a0456ca3ae6b8d020068ba846f813d4))
+    - workaround for Cortex-A78C erratum 2772121 ([00230e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/00230e37e3c21fed4a46eeb69dea9d808f8402b4))
+    - workaround for Cortex-A78C erratum 2779484 ([66bf3ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66bf3ba482e46137e19f368f1386436a33eaba74))
+    - workaround for Cortex-X2 erratum 2282622 ([f9c6301](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f9c6301d743405bd91b9a1fe433ce14fa60a830f))
+    - workaround for Cortex-X2 erratum 2768515 ([1cfde82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1cfde82227558a8cc1792c068bc7a7cdf8feab43))
+    - workaround for Cortex-X3 erratum 2615812 ([c7e698c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c7e698cfdedbe2b1c8212dd71477f289f7644953))
+    - workaround for Neoverse N2 erratum 2743089 ([1ee7c82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ee7c8232c153203d104f148a33e6f641d503f96))
+    - workaround for Neoverse V1 errata 2743233 ([f1c3eae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1c3eae9e091a63b42eebae8b03d4d470c9c3f75))
+    - workaround for Neoverse V1 errata 2779461 ([2757da0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2757da06149238041308060e5cb51f0870a02a15))
+    - workaround for Neoverse V1 erratum 2743093 ([31747f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31747f057b13b5934b607b7021139e58a55f7766))
+    - workaround platforms non-arm interconnect ([ab062f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab062f0510d42b2019667e3f4df82a1f57121412))
+
+  - **EL3 Runtime**
+
+    - allow SErrors when executing in EL3 ([1cbe42a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1cbe42a510812a4a4415a26ba46821cad1c04b68))
+    - do not save scr_el3 during EL3 entry ([e61713b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e61713b00715fc988a970687f9bf53418b81b0ca))
+    - restore SPSR/ELR/SCR after esb ([ff1d2ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff1d2ef387f085fdada4a122284b3b044fdde09c))
+
+    - **RAS**
+
+      - do not put RAS check before esb macro ([7d5036b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d5036b8ec911d83ede6eb73f1693b6f160d90ed))
+
+  - **FCONF**
+
+    - fix FCONF_ARM_IO_UUID_NUMBER value ([e208f32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e208f3244b311a23b3e7fa1c03b3e98a6228714a))
+    - make struct fconf_populator static ([40e740d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40e740dc14e807455d8db99dc758af355aa7fa8f))
+
+  - **OP-TEE**
+
+    - address late comments and fix bad rc ([8d7c80f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d7c80fa4c5ab17e25d6d82ff0b1e67795e903fb))
+    - return UUID for image loading service ([85ab882](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85ab88238183be1e27835e14e3588fb73e0f6aa7))
+
+  - **PSCI**
+
+    - do not panic on illegal MPIDR ([8a6d0d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a6d0d262ae03db0a0bedd047a2df6f95e8823f6))
+    - potential array overflow with cpu on ([6632741](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66327414fb1e3248d443f4eb2835f437625fb92c))
+    - remove unreachable switch/case blocks ([ad27f4b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad27f4b5d918bbd1feb9a2deed3cb0e2ae39616e))
+    - tighten psci_power_down_wfi behaviour ([695a48b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/695a48b5b4366d1005f8b9a0fc83726914668fb5))
+
+  - **GPT**
+
+    - fix compilation error for gpt_rme.c ([a0d5147](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0d5147b8282374e107461421bb229272fde924b))
+
+  - **SMCCC**
+
+    - check smc_fid [23:17] bits ([f8a3579](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f8a35797b919d8ea041480bd5eb2a334e7056e0b))
+
+  - **C Standard Library**
+
+    - properly define SCHAR_MIN ([06c01b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/06c01b085fb28fcfe26d747da2ba33415dbd52b9))
+    - remove __putchar alias ([28dc825](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28dc82580e50961f9b76933b20d576a6afc5035c))
+
+  - **Context Management**
+
+    - enable SCXTNUM access ([01cf14d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/01cf14dd41cae9c68cb5e76a815747a0d2a19a4a))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - avoid out-of-bounds read in auth_nvctr() ([abb8f93](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/abb8f936fd0ad085b1966bdc2cddf040ba3865e3))
+    - forbid junk after extensions ([fd37982](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fd37982a19a4a2911912ce321b9468993a0919ad))
+    - only accept v3 X.509 certificates ([e9e4a2a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9e4a2a6fd33d8fc21b00cfc9816a3dd3fef47fe))
+    - properly validate X.509 extensions ([f5c5185](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f5c51855d36e399e6e22cc1eb94f6b58e51b3b6d))
+    - reject invalid padding in digests ([f47547b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f47547b35462571636a76b737602e827ae43bc24))
+    - reject junk after certificates ([ca34dbc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca34dbc0cdb1c4e1ab62aa4dd195cf9389b9edb7))
+    - reject padding after BIT STRING in signatures ([a8c8c5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8c8c5ef2a8f5a27772eb708f2201429dd8d32b2))
+    - require at least one extension to be present ([72460f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/72460f50e2437a85ce5229c430931aab8f4a0d5b))
+    - require bit strings to have no unused bits ([8816dbb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8816dbb3819e626d14e1bb9702f6446cb80e26f0))
+    - use NULL instead of 0 for pointer check ([654b65b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/654b65b36d60a9c08e1d0cd88b35cd7bc2c813af))
+
+    - **mbedTLS**
+
+      - fix mbedtls coverity issues ([a9edc32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a9edc32c8964ffe047909b4847edd710b5879f35))
+
+  - **Console**
+
+    - correct scopes for console symbols ([03bd481](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03bd48102b575a9c86eed73866a5f9cd4d03e2d5))
+    - fix crash on spin_unlock with cache disabled ([5fb6946](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fb6946ad70f5c6e82502a704633bba1dd82e507))
+
+  - **I/O**
+
+    - compare function pointers with NULL ([06d223c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/06d223cb4f54543299b96d40a682e33f9147e192))
+
+  - **MMC**
+
+    - align part config type ([53cbc94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53cbc949670877d1b661782ab452f6fac2302ce3))
+    - do not modify r_data in mmc_send_cmd() ([bf78a65](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf78a6504254be9bf2cee38828a72f84773d4aa7))
+    - explicitly check operators precedence ([14cda51](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14cda5168de45bbbcce1a5152140111d4fc8fd21))
+    - remove redundant reset_to_idle call ([bc0a738](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc0a73866f3e4f7138892b228eb592be118b40d2))
+
+  - **GUID Partition Tables Support**
+
+    - add missing curly braces ([1290662](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1290662034578b4e52443c79f34dfd7c284c0435))
+    - add U suffix for unsigned numbers ([d1c6c49](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d1c6c495541b6e387179f987acbef274a12c7535))
+
+  - **SCMI**
+
+    - change function prototype to fix gcc error ([f0f2c90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0f2c90365d933ee0a160b4bf5723fc303d9ab73))
+    - fix compilation error in scmi base ([7c38934](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c3893423d6ba5088f92f4ebdb626285759a1bcd))
+
+  - **UFS**
+
+    - device present (DP) field is set to '1' ([83103d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83103d1264fe3cd7d54f3a89121d6889b4d33980))
+    - flush the entire PRDT ([83ef869](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83ef8698f9d1477c892cad15b4e48574ed634903))
+    - only allow using one slot ([56db7b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56db7b8b08d5bb350a02e1f794dc6eb02827917f))
+    - poll UCRDY for all commands ([6e57b2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e57b2f00e36e63da765e3aa1650b03772999726))
+    - set the PRDT length field properly ([20fdbcf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/20fdbcf502bd457a4b74ffa9a610d573594f1f6c))
+
+  - **Arm**
+
+    - **Ethos-N**
+
+      - add workaround for erratum 2838783 ([5a89947](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a89947ab3ef8541b7adb6058af9ef141073043d))
+
+    - **GIC**
+
+      - wrap cache enabled assert under plat_can_cmo ([78fbb0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/78fbb0ec8372a638b2b2a0276776892141ff43f8))
+
+      - **GICv3**
+
+        - fixed bug in the initialization of GICv3 SGIs/(E)PPIs interrupt priorities ([5d68e89](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d68e8913ea983b21eb4a1163e6215ff8f8e96e4))
+        - restore scr_el3 after changing it ([1d0d5e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d0d5e40206c693e24b0a4de7dbcfc4b79f3138e))
+        - workaround for NVIDIA erratum T241-FABRIC-4 ([a02a45d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a02a45dfef4b02fa363a5f843ba6a0aac52d181f))
+
+    - **RSS**
+
+      - do not consider MHU_ERR_ALREADY_INIT as error ([55a7aa9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/55a7aa9252acfc9712a914e74bcddefc3a8d6390))
+      - fix msg deserialization bugs in comms ([dda0528](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dda052851a78fad150b6565ea4bb75644bd37dce))
+      - remove null-terminator from RSS metadata ([85a14bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85a14bc0a9598668c4678f9eda2ba497acba5ced))
+
+  - **NXP**
+
+    - fix fspi coverity issue ([5199b3b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5199b3b93c6ada8dd830f625f77987d3474a6f98))
+    - fix sd secure boot failure ([236ca56](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/236ca5667e8ac82aa53d4e933a78e6ca1ebf456e))
+    - fix tzc380 memory regions config ([07d8e34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07d8e34fdd5a81b6fe5f805560be44c1063cea79))
+    - use semicolon instead of comma ([50b8ea1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/50b8ea115f117e17646d73fe7606bee14bd02630))
+
+    - **NXP Crypto**
+
+      - fix coverity issue ([e492299](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e49229911f4e08e317453883886a113f3332b776))
+      - fix secure boot assert inclusion ([334badb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/334badb50f3ad55762785a6ba0266c2eb4d93e8e))
+
+    - **DDR**
+
+      - add checking return value ([e83812f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e83812f11a2d725931de88308c5b520d88bcca86))
+      - apply Max CDD values for warm boot ([00bb8c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/00bb8c37e0fe57ae2126857ce2d2700106a76884))
+      - fix coverity issue ([2d541cb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d541cbcbe90217df107e1ac0c4adb76d647b283))
+      - fix underrun coverity issue ([87612ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/87612eaefff34548b72fed0d8c93dcf73f9b8c81))
+      - use CDDWW for write to read delay ([fa01056](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa0105693c85eacf6eda22eca63f220d304f7768))
+
+  - **ST**
+
+    - **Clock**
+
+      - avoid arithmetics on pointers ([4198fa1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4198fa1db7297d8385bb6624d4bd475870e5bf12))
+      - give the size for parent_mp13 and dividers_mp13 tables ([ee21709](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ee21709e98a9e0f60a46d79caf5b702a0b7941cc))
+      - remove useless switch ([69a2e32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/69a2e320b6798ce3cf5cb27bf70e3384cfac3ebb))
+      - use Boolean type for tests ([c3ae7da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3ae7da02dd8b358239dde47c3325e333af81056))
+
+    - **Crypto**
+
+      - move flag control into source code ([6a187a0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a187a002ee72ef865222870b2ecf99cf4d4efb8))
+      - remove platdata functions ([6b3ca0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b3ca0a81723290e2d9b33c406c0e65c1870baa8))
+      - set get_plain_pk_from_asn1() static ([70a422b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70a422ba83df3f572af1d2931e950feb78592ca3))
+
+    - **GPIO**
+
+      - define shift as uint32_t ([5d942ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d942ff1964131bf33f445f66175fe8211c77e23))
+
+    - **SDMMC2**
+
+      - check transfer size before filling register ([029f81e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/029f81e04c0232843f3e546fa080778a1008a9c5))
+
+    - **ST PMIC**
+
+      - define pmic_regs table size ([3cebeec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3cebeec2ae452d33ec0cea322f4ab18137e41631))
+      - enclose macro parameter in parentheses ([be7195d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be7195d06cb7731fe0d906c6eabe6cb6f39f29b1))
+
+    - **Regulator**
+
+      - enclose macro parameters in parentheses ([91af163](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/91af163cbbfab936e70568998e8b9dcb10203b8e))
+      - explicitly check operators precedence ([68083e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68083e7ad5ded7adbeca147546bbda6c14cab049))
+      - rework for_each_*rdev macros ([6a3ffb5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a3ffb53910f136d14ddad5042da01a03e5087c4))
+      - use Boolean type for tests ([9a00daf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a00daf9dd0a25da45a43142ca27126e6e26a622))
+
+    - **USB**
+
+      - replace redundant checks with asserts ([02af589](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02af589cfa8d8aefaffeef3390e3fb8fdf51978f))
+
+- **Style**
+
+  - correct some typos ([1b491ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b491eead580d7849a45a38f2c6a935a5d8d1160))
+
+- **Miscellaneous**
+
+  - **AArch64**
+
+    - allow build with ARM_ARCH_MINOR=4 ([78f56ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/78f56ee71c9ffe7a6ee36268f0fe1f7ca7d01738))
+
+  - **FDT Wrappers**
+
+    - use correct prototypes ([e0c56fd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0c56fd71fbd7e8ef307777db8940fb2cf3c9957))
+
+  - **FDTs**
+
+    - **STM32MP1**
+
+      - **STM32MP15**
+
+        - use /omit-if-no-ref/ for spi and i2c ([d480df2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d480df2116fc0d629d52f654bc218ee36251cb33))
+        - use interrupts-extended for i2c2 ([600c8f7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/600c8f7d953d466e0ec5fd04bd6ef2e44c9c9125))
+
+  - **PIE**
+
+    - pass `-fpie` to the preprocessor as well ([966660e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/966660ecd0c8a3d6e4d18a5352bb431e71a9a793))
+
+  - **UUID**
+
+    - add missing `#include` directives ([12562af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12562af369e897c67aa45bfeb97cd7bb5d500cf6))
+
+  - add missing click dependency ([ff12683](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff12683e87e44ead813600fac5415e05e7f95700))
+  - add parenthesis for tests in MIN, MAX and CLAMP macros ([8406db1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8406db14fbba19c25d000eaeab538a0474795da1))
+  - increase BL32 limit ([c2a7612](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c2a76122c88e9ba5de493e1aa765ad170614a31d))
+  - remove old-style declarations ([f4b8470](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4b8470feee4437fb3984baeee8c61ed91f63f51))
+  - remove useless "return" at void functions ([af4d8c6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af4d8c6d505c001ee78ea9dd9d8dd76ba039af9b))
+  - unify fallthrough annotations ([e138400](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e138400d1c19a561eaf9f23b0cadc07226684561))
+
+- **Documentation**
+
+  - add a build.tools.python entry ([4052d95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4052d9583c850feeb8add29734bda0ef0343c238))
+  - add few missed links for Security Advisories ([43f3a9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/43f3a9c4d67da76a00f9050e7cfe1333da51ff92))
+  - add plantuml as a dependency ([65982a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/65982a94ef113d5d652d8e1a521b219be75fca42))
+  - add readthedocs configuration file ([8a84776](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a84776340bf4215d235b7b6dc09cf94aed8c6b3))
+  - deprecate plat_convert_pk() in v2.9 ([e0f58c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0f58c7fb685560933e3583cb1dfab8fb2963692))
+  - make required compiler version == rather than >= ([415195c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/415195c03e6e1b3a5335ee242ab4116d2d1ac0b1))
+  - python version must be string ([3aa919e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3aa919eb278e7e0b23742ea043d79e1b1f1d75c6))
+  - specify python version to 3.10 ([a7773c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a7773c590d0319bdf3b4ddc67c7b22180020224b))
+
+- **Build System**
+
+  - add a default value for INVERTED_MEMMAP ([4d32f91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d32f9138d61719bbaab57fdd853877a7e06b1cd))
+  - allow lower address access with gcc-12 ([dea23e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dea23e245fb890c6c06eff7d1aed8fffa981fc05))
+  - allow warnings when using lld ([ebac692](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ebac6922d1f6fc16c5d3953dfb512553001dcdd3))
+  - partially fix qemu aarch32 build ([c68736d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c68736dab5631af3d9a1d33cb911e90e67e8ee34))
+
+- **Tools**
+
+  - **NXP Tools**
+
+    - fix coverity issue ([4fa0f09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fa0f097399c7d396bc14a6692476ada6981c458))
+
+  - **Secure Partition Tool**
+
+    - add dependency to SP image ([4daeaf3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4daeaf341a347a60fd481fb4a1530f18f8e4c058))
+
+  - **Certificate Creation Tool**
+
+    - change WARN to VERBOSE ([76a85cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/76a85cfa0ab5e7093ad18601b7e73a1e425d8025))
+
+- **Dependencies**
+
+  - add missing aeabi_memset.S ([bdedee5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bdedee5a0f156d05eb62c704e702bfd1c506dc5d))
+
+### New Features
+
+- **Architecture**
+
+  - **Extended Translation Control Register (FEAT_TCR2).**
+
+    - add FEAT_TCR2 to the changelog ([a366640](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a366640cf22d7d0e610564f81e189f6037ff9473))
+    - support FEAT_TCR2 ([d333160](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3331603664ca7d4ab1510df09e722e6ffb1df29))
+
+  - **CPU feature / ID register handling in general**
+
+    - enable FEAT_SME for FEAT_STATE_CHECKED ([45007ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45007acd46981b9f289f03b283eb53e7ba37bb67))
+    - enable FEAT_SVE for FEAT_STATE_CHECKED ([2b0bc4e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b0bc4e028a75d75c6d6942ddd404ef331db29be))
+    - extend check_feature() to deal with min/max ([a4cccb4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4cccb4f6cbbb35d12bd5f8779f3c6d8d762619c))
+
+  - **Guarded Control Stack (FEAT_GCS)**
+
+    - support guarded control stack ([688ab57](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/688ab57b9349adb19277d88f2469ceeadb8ba083))
+
+  - **Support for the `HCRX_EL2` register (FEAT_HCX)**
+
+    - initialize HCRX_EL2 to its default value ([ddb615b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ddb615b419074727ac0a1430cf0f88bd018ac8df))
+
+  - **Scalable Matrix Extension (FEAT_SME, FEAT_SME2)**
+
+    - enable SME2 functionality for NS world ([03d3c0d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03d3c0d729e24713d657209bedf74d255550babb))
+
+- **Platforms**
+
+  - **Allwinner**
+
+    - add extra CPU control registers ([b15e2cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b15e2cda14b3ffddebd8b40cc5c31c1c0e9cbf0d))
+    - add function to detect H616 die variant ([fbde260](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbde260b11171f0f67afbc631e22fe26366ff448))
+    - add support for Allwinner T507 SoC ([018c1d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/018c1d878fbfd696ebeda52b5188e4658b87bf75))
+
+  - **Arm**
+
+    - add ARM_ROTPK_LOCATION variant full key ([5f89928](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f899286eac994b8337959ad924a43c1a4a543c9))
+    - carveout DRAM1 area for Event Log ([6b2e961](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b2e961fb1428c3fe213c524164a00fcaee495c4))
+
+    - **FVP**
+
+      - add Event Log maximum size property in DT ([1cf3e2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1cf3e2f0a8eb0d6324ce3db68dd5c78bdb690a8a))
+      - copy the Event Log to TZC secured DRAM area ([191aa5d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/191aa5d3fc793c5c4cd8960d1ef7b95010cc9d87))
+      - define ns memory in the SPMC manifest ([7f28179](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f28179a46b40ede461326dd329eb832c0d72b0d))
+      - emulate trapped RNDR ([1ae7552](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ae75529bc2e5a213c3e458898c219c34aa99f65))
+      - enable errata management interface ([d3bed15](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3bed15851a1b35b2608f7275f1294c8d4f7aee7))
+      - enable FEAT_FGT by default ([15107da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15107daad6b83b4ee1edfebf420b6779a054318e))
+      - enable FEAT_HCX by default ([2e12418](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e1241888ee82a5a9b3b30acd83a1f4ea6732f1b))
+      - enable support for PSCI OS-initiated mode ([e75cc24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e75cc247c744d21e52f834a442bf1c26d0ab6161))
+      - increase BL1_RW and BL2 size ([dbb9c1f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dbb9c1f5b69134ca43c944d84b413331a64fba15))
+      - introduce PLATFORM_TEST_EA_FFH config ([fe38cc6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe38cc68975b23084b4ba512254926941c865a07))
+      - introduce PLATFORM_TEST_RAS_FFH config ([5602ce1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5602ce1d8db3256a7766776cb908b1f716c2d463))
+      - update device tree with load addresses of TOS_FW config ([1779762](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/177976286e347acd905d8082f31c201b9900d28e))
+
+    - **Juno**
+
+      - support ARM_IO_IN_DTB option for Juno ([2fad320](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2fad320f5623edcdd23297ab57c4b9b0b0ef872c))
+
+    - **Morello**
+
+      - add GPU DT node ([cd94c3d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd94c3d6ad5e738c2583486b7a973bd8e516089b))
+      - add support for HW_CONFIG ([be79071](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be79071ef73b4b08cca310ec7e7d915faea8f036))
+      - implement methods to retrieve soc-id information ([cc266bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc266bcd8c0a1d839151b69436fdf2c1ad07b0a1))
+
+    - **RD**
+
+      - **RD-N2**
+
+        - add platform id value for rdn2 variant 3 ([028c619](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/028c6190d9f3d892a84b5b9cbfdbbab808a73acb))
+
+    - **TC**
+
+      - enable MPAM functionality of L3 DSU cache ([b45ec8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b45ec8cea483a38e358146b99205504ff7f98001))
+      - add delegated attest and measurement tests ([25dd217](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25dd2172ae564c74b7e8b42aa96d5ee9a865ec75))
+      - allow secure watchdog timer to trigger periodically ([28b2d86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28b2d86cd28ffc54c6272defcd6f123a925012f1))
+      - use smmu 700 ([ed80eab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed80eab6a686ce1042300cfbdb90e13366aa08d4))
+
+  - **Intel**
+
+    - extending to support SMMU in FCS ([4687021](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4687021d2eedea880ad8596b32e85da72f8cba02))
+    - fix bridge disable and reset ([9ce8251](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ce82519c65f0dd93d2673ebb967d02f52b19a04))
+    - implement timer init divider via CPU frequency for N5X ([02a9d70](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02a9d70c4deaa2102386611ac6b305838003148d))
+    - setup FPGA interface for Agilex ([3905f57](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3905f57134853f47f6e859b8b6322a7dbbfc49f7))
+
+  - **MediaTek**
+
+    - add APU init flow ([5243091](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5243091633b8fe8057cec176ac31adb72fdf3506))
+    - add new features of LPM ([917abdd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/917abdd99012d01ef4fa804ecec1503bef68ed9b))
+    - add SiP service for OP-TEE ([621eaab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/621eaab5cc3c9d98783700b7515b1da118b3d21c))
+    - add SMC handler for EMI MPU ([c842cc0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c842cc0e5d1432a681cbddce62a852ff282169ae))
+    - add SPM's SSPM notifier ([c234ad1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c234ad17d7d7278e1afa0f416982bb0f60a04dcf))
+
+    - **MT8188**
+
+      - add apu power on/off control ([8e38b92](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e38b928490516d308bdceebc4ad032852bf2716))
+      - add MT8188 SPM debug logs ([f85b34b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f85b34b112eec006c14afab0eadbd45d1b0d0e7e))
+      - add MT8188 SPM support ([45d5075](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45d507599e213f8f3a26502c3ca8de6b1cfdc611))
+      - add SPM feature support ([f299efb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f299efbea685aa8075ec4d6d0f70d189cce3ee07))
+      - add the register definitions accessed by SPM ([1a64689](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a64689df5e7bf78aa8724c1d75f414ea62750eb))
+      - enable SPM and LPM ([380f64b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/380f64b2e39c60cb9a1f751b25cbce11c5e03e20))
+      - keep infra and peri on when system suspend ([e56a939](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e56a939cabb5ae0fe967c19ddacf97304c563f37))
+      - update INFRA IOMMU enable flow ([98415e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/98415e1a80ca025a000241cf3fc175272890c0e8))
+
+    - **MT8195**
+
+      - add support for SMC from OP-TEE ([ccc61e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ccc61e10029b8ddfcb5cb65201862a18ebbc953d))
+
+  - **NVIDIA**
+
+    - **Tegra**
+
+      - implement 'pwr_domain_off_early' handler ([96d07af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/96d07af402a5d191b7d1200a75c1b206f21cc395))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - add more dram pll setting ([4234b90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4234b902ae37ca05640888e31405ec97c8cde316))
+        - fix the ddr4 dvfs random hang on imx8m ([093888c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/093888caaf54cbfe38d4b68406d98fbcf5c7d81f))
+        - update the ddr4 dvfs flow to include ddr3l support ([0e39488](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e39488ff3f2edac04d7f5acb58d9a22baa3a69e))
+        - use non-fast wakeup stop mode for system suspend ([ef4e5f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef4e5f0f105f184f02ad4d1cc17cecec9b45502a))
+
+        - **i.MX 8Q**
+
+          - add anamix pll override setting for DSM mode ([387a1df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/387a1df18e0b5bf1d305c72df284b1b89f3c1cd3))
+          - add BL31 PIE support ([8cfa94b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8cfa94b7a7fc398cc0ea803891f6277065bb7575))
+          - add the dram retention support for imx8mq ([dd108c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd108c3c1fe3f958a38ae255e57b41e5453d077f))
+          - add version for B2 ([99475c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99475c5dcc14123dda51bda32d21753f0b4c357d))
+          - add workaround code for ERR11171 on imx8mq ([88a2646](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88a264657fad2f71369fec4b53478e8a595d10e9))
+          - always set up console ([36be108](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36be10861e851e7e4df06bb08aab60d8e878d2b2))
+          - correct the slot ack setting for STOP mode ([724ac3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/724ac3e2c23441d11f642f2ae91c8a8834ea179f))
+          - enable dram dvfs support on imx8mq ([8962bdd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8962bdd603508f649fd7a332e580c0e456ccc0ad))
+          - make IMX_BOOT_UART_BASE configurable via build parameter ([202737e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/202737efda85b2ea61934123b8ffa492f5dc3679))
+          - remove empty bl31_plat_runtime_setup ([7698dba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7698dbab96072881e0912322db5036529bf8553c))
+
+      - **i.MX 8**
+
+        - add support for debug uart on lpuart1 ([8406447](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8406447f13c65fe93aab7ed641b7e8fe3eb47a0b))
+
+    - **Layerscape**
+
+      - **LX2**
+
+        - enable OCRAM ECC ([e8faff3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8faff3da962ce112e32d8f1fdb8155e078eae75))
+        - support more variants ([c07f5e9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c07f5e9e50959a3667e5a96ac808d1d16bb72698))
+
+  - **QEMU**
+
+    - add "neoverse-n1" cpu support ([226f4c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/226f4c8e35c4441e80ad523b9105eab4ca630396))
+    - add A76/N1 cpu support for virt ([6b66693](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b66693685f828a51c7f78bfa402d6b192169a6d))
+    - combine TF-A artefacts into ROM file ([63bb905](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/63bb90569792893a4e7401004c23cde488fda0cc))
+    - increase max cpus per cluster to 16 ([73a7aca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/73a7aca2a53d4dbb62909c5741830eee9eac5ee8))
+    - increase size of bl2 ([db2bf3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db2bf3ac193f66f365b962b911e7bb2ffbde0a25))
+    - make coherent memory section optional ([af994ae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af994ae8a089ead6082ca82036d30074f554ed52))
+    - support el3 spmc ([302f053](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/302f05354f5aab340c315e0d04915367c65c6b27))
+    - support pointer authentication ([cffc956](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cffc956edf3a14508ed5740c1ed093326ca67e72))
+    - support s-el2 spmc ([36802e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36802e2c792f79ab630b53298dfd4f1e5a95d173))
+    - update abi between spmd and spmc ([25ae7ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25ae7ad1878244f78206cc7c91f7bdbd267331a1))
+
+  - **QTI**
+
+    - **SC7280**
+
+      - add support for PSCI_OS_INIT_MODE ([e528bbe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e528bbec74af359714203c7f8d356074733ea9cd))
+
+    - **MSM8916**
+
+      - expose more timer frames ([1781bf1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1781bf1c40594e3a3f36404da793d5c7a6bca533))
+
+  - **ST**
+
+    - mandate dtc version 1.4.7 ([38ac8bb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/38ac8bbbe450343e8545a44f370ff9da57cbed26))
+
+    - **STM32MP1**
+
+      - add mbedtls-3.3 support config ([c9498c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9498c8f56387ad23530dcc6e57940d2b118d907))
+
+  - **Texas Instruments**
+
+    - add PSCI system_off support ([0bdef26](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0bdef264c2bd356e2a89fc5ac7c438694618d272))
+    - add sub and patch version number support ([852378f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/852378fd60d8cc536799639774f1e4ffe124131d))
+    - disable L2 dataless UniqueClean evictions ([10d5cf1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10d5cf1b26f03d61a90cdcff5163965fa48e291c))
+    - do not handle EAs in EL3 ([2fcd408](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2fcd408bb3a6756767a43c073c597cef06e7f2d5))
+    - set L2 cache data ram latency on A72 cores to 4 cycles ([aee2f33](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aee2f33a675891f660fc0d06e739ce85f3472075))
+    - set L2 cache ECC and and parity on A72 cores ([81858a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81858a353f8e45f5cc57ce855188043b1745ea08))
+    - set snoop-delayed exclusive handling on A72 cores ([5668db7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5668db72b724dc256d9b300f6938a08625624a48))
+    - synchronize access to secure proxy threads ([312eec3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/312eec3ecde9837f61fc0d7b46b4197ec2257ee7))
+
+  - **Xilinx**
+
+    - add device node indexes ([407eb6f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/407eb6fda06d7be034dc7f1c537183f64126f074))
+    - sync copyright format ([2774965](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/27749653c7dbea1bd5b34a39085bc7cb12d46501))
+
+    - **Versal**
+
+      - replace irq array with switch case ([0ec6c31](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ec6c31320c6d86e89dce8775af2bbdfa7a302fa))
+      - switch to xlat_v2 ([0e9f54e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e9f54e5bb7f4b44bca9c63cce37913070fea23a))
+
+      - **Versal NET**
+
+        - add jtag dcc support ([30e8bc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30e8bc365c1007da97f93c71e5fa16b6be56b679))
+        - add support for set wakeup source ([c38d90f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c38d90f7964ddf186f4cbaad6da91dd0a44627e3))
+        - add support for uart1 console ([2f1b4c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f1b4c55502262dba0ccd147f87cdb38cf4131f2))
+
+    - **ZynqMP**
+
+      - add hooks for custom runtime setup ([88a8938](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88a8938e62989b7319b20c46c046aa8845852ce9))
+      - add hooks for mmap and early setup ([7013400](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70134000842cbc7c052031dd453bdec8f4cb73f1))
+      - add SMCCC_ARCH_SOC_ID support ([8f9ba3f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8f9ba3f344545740fc44e90fb8322c7728ae94ec))
+      - add support for custom sip service ([496d708](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/496d708154d893fb9f412390acd433337faccecc))
+      - build pm code as library ([3af2ee9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3af2ee906842378ee91f07aa4ea5565cd1a0f8c2))
+      - bump up version of query_data API ([aaf5ce7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aaf5ce77fb22f54a8ca7bc8d3be6172dacbfc0c1))
+      - make stack size configurable ([5753665](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57536653e62765f9529d045b118ad881369bc73a))
+
+- **Services**
+
+  - **RME**
+
+    - read DRAM information from FVP DTB ([8268590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/826859049859a5bd88e142695e10a559d85721c1))
+    - set DRAM information in Boot Manifest platform data ([a97bfa5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a97bfa5ff18b2682e3b9c528cbd5fb16ceec3393))
+
+    - **RMM**
+
+      - add support for the 2nd DRAM bank ([346cfe2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/346cfe2b46a83bc9e6656f43ec55a196503b154a))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - make platform logical partition optional ([555677f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/555677fe81c5e1888254ac36acb0a02b3850dc46))
+
+    - **SPMD**
+
+      - add support for FFA_EL3_INTR_HANDLE_32 ABI ([6671b3d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6671b3d8224a8c4c3fea7cbe66b56945c432393f))
+      - copy tos_fw_config in secure region ([0cea2ae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0cea2ae07db089e60322677021da4743a084f9ca))
+      - fail safe if SPM fails to initialize ([0d33649](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0d33649e3e2a21def73327522b9861b4619fc5c2))
+      - introduce FFA_PARTITION_INFO_GET_REGS ([eaaf517](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eaaf517cd1bd8c9d5e3e6d2d202a69a0cbcb45bf))
+      - introduce platform handler for Group0 interrupt ([f0b64e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0b64e507e9105813d9a5d16f70101cf0d8ca5a4))
+      - map SPMC manifest region as EL3_PAS ([8c829a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c829a9240109dd7a66a3c26f734f23477b12551))
+      - register handler for group0 interrupt from NWd ([a1e0e87](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1e0e871f10201a9dbdc1dadfd27904888246adc))
+
+  - **ERRATA_ABI**
+
+    - errata management firmware interface ([ffea384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ffea3844c00daf8dee466840a4932cac04b3eb57))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add support for blackhawk cpu ([6578343](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6578343bb2aab6ec5ae309097047a83445aa12da))
+    - add support for chaberton cpu ([516a52f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/516a52f6f5cda6acb311ffd6e8fb77f2e09c1357))
+
+  - **EL3 Runtime**
+
+    - handle traps for IMPDEF registers accesses ([0ed3be6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ed3be6fc2c8d275862959d1ee6a0354cc01ad5d))
+    - introduce system register trap handler ([ccd81f1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ccd81f1e097c3eafe38523110c8eebabbe662508))
+
+  - **FCONF**
+
+    - rename 'ns-load-address' to 'secondary-load-address' ([05e5503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/05e550302103a527b9f8d3869942c203c7b2dd65))
+
+  - **OP-TEE**
+
+    - add device tree for coreboot table ([f4bbf43](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4bbf435554e87de31c0a70039aa03b19962aaea))
+    - add loading OP-TEE image via an SMC ([05c69cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/05c69cf75edf53478e23fce157fea72372b49597))
+
+  - **PSCI**
+
+    - add support for OS-initiated mode ([606b743](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/606b7430077c15695a5b3bcfbad4975f00c9bf95))
+    - add support for PSCI_SET_SUSPEND_MODE ([b88a441](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b88a4416b5e5f2bda2240c632ba79e15a9a75c45))
+    - introduce 'pwr_domain_off_early' hook ([6cf4ae9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cf4ae979a5f8be23927b97ecfe789dabcb53dbd))
+    - update PSCI_FEATURES ([9a70e69](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a70e69e059863d7aec11883e6345b54058264e0))
+
+  - **C Standard Library**
+
+    - add %c to printf/snprintf ([44d9706](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44d9706e5428d8e3588d04565c7cd738ffc1e472))
+    - add support for fallthrough statement ([023f1be](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/023f1bed1dde23564e3b66a99c4a45b09e38992b))
+
+  - **PSA**
+
+    - add read_measurement API ([6d0525a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d0525aafe17e7affb0f71e86a5121989c150c42))
+    - interface with RSS for NV counters ([8374508](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8374508b00909cdffbe6233cf8fddcb49924faed))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - compare platform and certificate ROTPK for authentication ([f1e693a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1e693a77548950cfffcb1d5a4b67cf349e0aed9))
+
+    - **mbedTLS**
+
+      - add support for mbedtls-3.3 ([51e0615](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51e061591bbf13af2486c3bb5f37ed609578d145))
+
+  - **UFS**
+
+    - adds timeout and error handling ([2c5bce3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c5bce3833848dac4fbb2ae19be418145e68c8a1))
+
+  - **Arm**
+
+    - **Ethos-N**
+
+      - add check for NPU in SiP setup ([a2cdbb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2cdbb1df088cde410aea1d5989dfc500aaf7939))
+      - add event and aux control support ([7820777](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7820777fa3c8ca454ab40d5d8a8ba0e311bbb6f9))
+      - add multiple asset allocators ([8a921e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a921e354575cd16aaa6f2f5a2aeaaaea35ab886))
+      - add NPU firmware validation ([313b776](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/313b776f851ed184abb265df2b6269fe78f48ecd))
+      - add NPU sleeping SMC call ([2a2e3e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2a2e3e87706b56fd1b8e787d3a552cfc12725934))
+      - add NPU support in fiptool ([c91b08c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c91b08c8a44aafac4f72c64aa8d4777b8c73647e))
+      - add protected NPU firmware setup ([6dcf3e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dcf3e774457cf00b91abda715adfbefce822877))
+      - add protected NPU TZMP1 regions ([d77c11e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d77c11e896e04be93caa4a56e50646af6806843f))
+      - add reserved memory address support ([a19a024](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a19a0241a6f1573e11d4d747dabb756d15ac4801))
+      - add reset type to reset SMC calls ([fa37d30](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa37d30856fef6742bd82e4e0a3252a4d0b9e091))
+      - add separate RO and RW NSAIDs ([986c4e9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/986c4e991ace5cb40bed35145184e66863c47152))
+      - add SMC call to get FW properties ([e9812dd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9812ddca6e72c0501ef1e84753f335dcafb74cd))
+      - add stream extends and attr support ([e64abe7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e64abe7bdaeed99093ae5b4aab8956a04ff4075a))
+      - add support for NPU to cert_create ([f309607](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f309607229e049a6ff9cbc858efa4dd0c0b921b8))
+      - add support to set up NSAID ([70a296e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70a296ee8641802dc60754aec5b18d8347820a5c))
+      - load NPU firmware at BL2 ([33bcaed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33bcaed1211ab27968433b546979687bc1182630))
+
+    - **GIC**
+
+      - **GICv3**
+
+        - enlarge the range for intr_num of structure interrupt_prop_t ([d5eee8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5eee8f3fbf53fce84c979e68433a27c93e3e96b))
+
+    - **RSS**
+
+      - add TC platform UUIDs for RSS images ([6ef63af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ef63af65f55e9402e4cdc534928faceb9c6e003))
+
+    - **SBSA**
+
+      - helper api for refreshing watchdog timer ([e8166d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8166d3e5937b8db43921b5049672b16af7f58e0))
+
+- **Miscellaneous**
+
+  - **AArch64**
+
+    - make ID system register reads non-volatile ([c2fb8ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c2fb8ef66ccc8222c70ab802cdaf29f1592cbbb6))
+
+  - **FDTs**
+
+    - **STM32MP1**
+
+      - use /omit-if-no-ref/ for pins nodes ([0aae96c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0aae96cfb9ef826d207f2d18d4a9f21fa1a5dee7))
+
+      - **STM32MP15**
+
+        - add support for prtt1x board family ([3812ceb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3812ceba8fcd682faeed6e71190a848771fd2022))
+
+  - **PIE/POR**
+
+    - support permission indirection and overlay ([062b6c6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/062b6c6bf23f9656332b0aa3fed59c15f34f9361))
+
+- **Documentation**
+
+  - allow verbose build ([f771a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f771a3446356d92c6c27df5c4f3bb07a2561b36b))
+
+- **Build System**
+
+  - add support for new binutils versions ([1f49db5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f49db5f25cdd4e43825c9bcc0575070b80f628c))
+  - allow additional CFLAGS for library build ([5a65fcd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a65fcd5f9c67baa681f664e4596760ca1f2606a))
+
+  - **Git Hooks**
+
+    - add pre-commit hook ([cf9346c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf9346cb83804feb083b56a668eb0a462983e038))
+
+  - add support for poetry ([793f72c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/793f72c06ca1c2782f800c9f20980ca6b7870072))
+
+- **Tools**
+
+  - **Firmware Image Package Tool**
+
+    - handle FIP in a disk partition ([06e69f7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/06e69f7c94637c693ea5eb26038096c196d10f07))
+
+- **Dependencies**
+
+  - **Compiler runtime libraries**
+
+    - update source files ([658ce7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/658ce7ad8eceb40741cd40f1639a6d923f922fad))
+
 ## [2.8.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.7.0..refs/tags/v2.8.0) (2022-11-15)
 
 ### âš  BREAKING CHANGES
@@ -3580,7 +4598,7 @@
 - Platforms
 
   - Arm
-    - Fixed missing copyrights in arm-gic.h file
+    - Fixed missing copyrights in Arm-gic.h file
     - Fixed the order of header files in several dts files
     - Fixed error message printing in board makefile
     - Fixed bug of overriding the last node in image load helper API
@@ -6842,7 +7860,7 @@
 
 ______________________________________________________________________
 
-*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
 
 [mbed tls releases]: https://tls.mbed.org/tech-updates/releases
 [pr#1002]: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
diff --git a/docs/components/activity-monitors.rst b/docs/components/activity-monitors.rst
index dd45c43..5c1c2c2 100644
--- a/docs/components/activity-monitors.rst
+++ b/docs/components/activity-monitors.rst
@@ -6,9 +6,9 @@
 Unit (|AMU|), an optional non-invasive component for monitoring core events
 through a set of 64-bit counters.
 
-When the ``ENABLE_AMU=1`` build option is provided, Trusted Firmware-A sets up
-the |AMU| prior to its exit from EL3, and will save and restore architected
-|AMU| counters as necessary upon suspend and resume.
+When the ``ENABLE_FEAT_AMU=1`` build option is provided, Trusted Firmware-A
+sets up the |AMU| prior to its exit from EL3, and will save and restore
+architected |AMU| counters as necessary upon suspend and resume.
 
 .. _Activity Monitor Auxiliary Counters:
 
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/components/measured_boot/event_log.rst b/docs/components/measured_boot/event_log.rst
index 0881248..c102bea 100644
--- a/docs/components/measured_boot/event_log.rst
+++ b/docs/components/measured_boot/event_log.rst
@@ -33,3 +33,11 @@
 - tpm_event_log_size [mandatory]
     - value type: <u32>
     - Event Log size.
+
+- tpm_event_log_max_size [mandatory]
+    - value type: <u32>
+    - Event Log maximum size.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index 871be2d..8d00345 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -1,45 +1,89 @@
 Reliability, Availability, and Serviceability (RAS) Extensions
-==============================================================
+**************************************************************
 
 This document describes |TF-A| support for Arm Reliability, Availability, and
 Serviceability (RAS) extensions. RAS is a mandatory extension for Armv8.2 and
 later CPUs, and also an optional extension to the base Armv8.0 architecture.
 
-In conjunction with the |EHF|, support for RAS extension enables firmware-first
-paradigm for handling platform errors: exceptions resulting from errors in
-Non-secure world are routed to and handled in EL3.
-Said errors are Synchronous External Abort (SEA), Asynchronous External Abort
-(signalled as SErrors), Fault Handling and Error Recovery interrupts.
-The |EHF| document mentions various :ref:`error handling
-use-cases <delegation-use-cases>` .
-
 For the description of Arm RAS extensions, Standard Error Records, and the
 precise definition of RAS terminology, please refer to the Arm Architecture
-Reference Manual. The rest of this document assumes familiarity with
-architecture and terminology.
+Reference Manual and `RAS Supplement`_. The rest of this document assumes
+familiarity with architecture and terminology.
+
+There are two philosophies for handling RAS errors from Non-secure world point
+of view.
+
+- :ref:`Firmware First Handling (FFH)`
+- :ref:`Kernel First Handling (KFH)`
+
+.. _Firmware First Handling (FFH):
+
+Firmware First Handling (FFH)
+=============================
+
+Introduction
+------------
+
+EA’s and Error interrupts corresponding to NS nodes are handled first in firmware
+
+-  Errors signaled back to NS world via suitable mechanism
+-  Kernel is prohibited from accessing the RAS error records directly
+-  Firmware creates CPER records for kernel to navigate and process
+-  Firmware signals error back to Kernel via SDEI
 
 Overview
 --------
 
+FFH works in conjunction with `Exception Handling Framework`. Exceptions resulting from
+errors in Non-secure world are routed to and handled in EL3. Said errors are Synchronous
+External Abort (SEA), Asynchronous External Abort (signalled as SErrors), Fault Handling
+and Error Recovery interrupts.
+RAS Framework in TF-A allows the platform to define an external abort handler and to
+register RAS nodes and interrupts. It also provides `helpers`__ for accessing Standard
+Error Records as introduced by the RAS extensions
+
-As mentioned above, the RAS support in |TF-A| enables routing to and handling of
-exceptions resulting from platform errors in EL3. It allows the platform to
-define an External Abort handler, and to register RAS nodes and interrupts. RAS
-framework also provides `helpers`__ for accessing Standard Error Records as
-introduced by the RAS extensions.
 
 .. __: `Standard Error Record helpers`_
 
+.. _Kernel First Handling (KFH):
+
+Kernel First Handling (KFH)
+===========================
+
+Introduction
+------------
+
-The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
-time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST_NS`` must also
-be set ``1``. ``RAS_TRAP_NS_ERR_REC_ACCESS`` controls the access to the RAS
-error record registers from Non-secure.
+EA's originating/attributed to NS world are handled first in NS and Kernel navigates
+the std error records directly.
+
+**KFH can be supported in a platform without TF-A being aware of it but there are few
+corner cases where TF-A needs to have special handling, which is currently missing and
+will be added in future**
+
+TF-A build options
+==================
+
+- **ENABLE_FEAT_RAS**: Manage FEAT_RAS extension when switching the world.
+- **RAS_FFH_SUPPORT**: Pull in necessary framework and platform hooks for Firmware first
+  handling(FFH) of RAS errors.
+- **RAS_TRAP_NS_ERR_REC_ACCESS**: Trap Non-secure access of RAS error record registers.
+- **RAS_EXTENSION**: Deprecated macro, equivalent to ENABLE_FEAT_RAS and RAS_FFH_SUPPORT
+  put together.
+
+RAS feature has dependency on some other TF-A build flags
+
+- **EL3_EXCEPTION_HANDLING**: Required for FFH
+- **HANDLE_EA_EL3_FIRST_NS**: Required for FFH
+- **FAULT_INJECTION_SUPPORT**: Required for testing RAS feature on fvp platform
+
+RAS Framework
+=============
+
 
 .. _ras-figure:
 
 .. image:: ../resources/diagrams/draw.io/ras.svg
 
-See more on `Engaging the RAS framework`_.
-
 Platform APIs
 -------------
 
@@ -191,19 +235,10 @@
 Engaging the RAS framework
 --------------------------
 
-Enabling RAS support is a platform choice constructed from three distinct, but
-related, build options:
-
--  ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware;
-
--  ``EL3_EXCEPTION_HANDLING=1`` enables handling of exceptions at EL3. See
-   `Interaction with Exception Handling Framework`_;
-
--  ``HANDLE_EA_EL3_FIRST_NS=1`` enables routing of External Aborts and SErrors,
-   resulting from errors in NS world, to EL3.
+Enabling RAS support is a platform choice
 
 The RAS support in |TF-A| introduces a default implementation of
-``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_EXTENSION``
+``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_FFH_SUPPORT``
 is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the
 top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating
 to through platform-supplied error records, probe them, and when an error is
@@ -239,4 +274,6 @@
 
 --------------
 
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
+
+.. _RAS Supplement: https://developer.arm.com/documentation/ddi0587/latest
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 6b57c0e..009ac28 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -52,7 +52,7 @@
   - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
     consistency with the versioning schemes used in other parts of RMM.
 
-This document specifies the 0.1 version of Boot Interface ABI and RMM-EL3
+This document specifies the 0.2 version of Boot Interface ABI and RMM-EL3
 services specification and the 0.2 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
@@ -503,6 +503,10 @@
 and it is the responsibility of RMM to preserve this or use this as a return argument.
 EL3 will always copy x0-x4 from Realm context to NS Context.
 
+EL3 must save and restore the following as part of world switch:
+   #. EL2 system registers with the exception of ``zcr_el2`` register.
+   #. PAuth key registers (APIA, APIB, APDA, APDB, APGA).
+
 EL3 will not save some registers as mentioned in the below list. It is the
 responsibility of RMM to ensure that these are appropriately saved if the
 Realm World makes use of them:
@@ -510,10 +514,11 @@
    #. FP/SIMD registers
    #. SVE registers
    #. SME registers
-   #. EL1/0 registers
+   #. EL1/0 registers with the exception of PAuth key registers as mentioned above.
+   #. zcr_el2 register.
 
-It is the responsibility of EL3 that any other registers other than the ones mentioned above
-will not be leaked to the NS Host and to maintain the confidentiality of the Realm World.
+It is essential that EL3 honors this contract to maintain the Confidentiality and integrity
+of the Realm world.
 
 SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
 case, RMM could choose to not save the incoming SVE context but must ensure
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index f0caf89..d4f0b00 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -203,6 +203,7 @@
 
 Sample TF-A build command line when FEAT_SEL2 architecture extension is
 implemented and the SPMC is located at S-EL2:
+
 .. code:: shell
 
     make \
@@ -220,6 +221,7 @@
 
 Sample TF-A build command line when FEAT_SEL2 architecture extension is
 implemented, the SPMC is located at S-EL2, and enabling secure boot:
+
 .. code:: shell
 
     make \
@@ -461,8 +463,15 @@
 - *cpus* node provide the platform topology and allows MPIDR to VMPIDR mapping.
   Note the primary core is declared first, then secondary cores are declared
   in reverse order.
-- The *memory* node provides platform information on the ranges of memory
-  available to the SPMC.
+- The *memory* nodes provide platform information on the ranges of memory
+  available for use by SPs at runtime. These ranges relate to either
+  secure or non-secure memory, depending on the *device_type* field.
+  If the field specifies "memory" the range is secure, else if it specifies
+  "ns-memory" the memory is non-secure. The system integrator must exclude
+  the memory used by other components that are not SPs, such as the monitor,
+  or the SPMC itself, the OS Kernel/Hypervisor, or other NWd VMs. The SPMC
+  limits the SP's address space such that they do not access memory outside
+  of those ranges.
 
 SPMC boot
 ~~~~~~~~~
@@ -562,7 +571,12 @@
 - Memory regions are mapped in the SP EL1&0 Stage-2 translation regime at
   load time (or EL1&0 Stage-1 for an S-EL1 SPMC). A memory region node can
   specify RX/TX buffer regions in which case it is not necessary for an SP
-  to explicitly invoke the ``FFA_RXTX_MAP`` interface.
+  to explicitly invoke the ``FFA_RXTX_MAP`` interface. The memory referred
+  shall be contained within the memory ranges defined in SPMC manifest. The
+  NS bit in the attributes field should be consistent with the security
+  state of the range that it relates to. I.e. non-secure memory shall be
+  part of a non-secure memory range, and secure memory shall be contained
+  in a secure memory range of a given platform.
 - Device regions are mapped in the SP EL1&0 Stage-2 translation regime (or
   EL1&0 Stage-1 for an S-EL1 SPMC) as peripherals and possibly allocate
   additional resources (e.g. interrupts).
@@ -1029,6 +1043,68 @@
 
 This is used in particular to convey power management messages.
 
+Memory Sharing
+--------------
+
+Hafnium implements the following memory sharing interfaces:
+
+ - ``FFA_MEM_SHARE`` - for shared access between lender and borrower.
+ - ``FFA_MEM_LEND`` - borrower to obtain exclusive access, though lender
+   retains ownership of the memory.
+ - ``FFA_MEM_DONATE`` - lender permanently relinquishes ownership of memory
+   to the borrower.
+
+The ``FFA_MEM_RETRIEVE_REQ`` interface is for the borrower to request the
+memory to be mapped into its address space: for S-EL1 partitions the SPM updates
+their stage 2 translation regime; for S-EL0 partitions the SPM updates their
+stage 1 translation regime. On a successful call, the SPMC responds back with
+``FFA_MEM_RETRIEVE_RESP``.
+
+The ``FFA_MEM_RELINQUISH`` interface is for when the borrower is done with using
+a memory region.
+
+The ``FFA_MEM_RECLAIM`` interface is for the owner of the memory to reestablish
+its ownership and exclusive access to the memory shared.
+
+The memory transaction descriptors are transmitted via RX/TX buffers. In
+situations where the size of the memory transaction descriptor exceeds the
+size of the RX/TX buffers, Hafnium provides support for fragmented transmission
+of the full transaction descriptor. The ``FFA_MEM_FRAG_RX`` and ``FFA_MEM_FRAG_TX``
+interfaces are for receiving and transmitting the next fragment, respectively.
+
+If lender and borrower(s) are SPs, all memory sharing operations are supported.
+
+Hafnium also supports memory sharing operations between the normal world and the
+secure world. If there is an SP involved, the SPMC allocates data to track the
+state of the operation.
+
+The SPMC is also the designated allocator for the memory handle. The hypervisor
+or OS kernel has the possibility to rely on the SPMC to maintain the state
+of the operation, thus saving memory.
+A lender SP can only donate NS memory to a borrower from the normal world.
+
+The SPMC supports the hypervisor retrieve request, as defined by the FF-A
+v1.1 EAC0 specification, in section 16.4.3. The intent is to aid with operations
+that the hypervisor must do for a VM retriever. For example, when handling
+an FFA_MEM_RECLAIM, if the hypervisor relies on SPMC to keep the state
+of the operation, the hypervisor retrieve request can be used to obtain
+that state information, do the necessary validations, and update stage 2
+memory translation.
+
+Hafnium also supports memory lend and share targetting multiple borrowers.
+This is the case for a lender SP to multiple SPs, and for a lender VM to
+multiple endpoints (from both secure world and normal world). If there is
+at least one borrower VM, the hypervisor is in charge of managing its
+stage 2 translation on a successful memory retrieve.
+The semantics of ``FFA_MEM_DONATE`` implies ownership transmission,
+which should target only one partition.
+
+The memory share interfaces are backwards compatible with memory transaction
+descriptors from FF-A v1.0. These get translated to FF-A v1.1 descriptors for
+Hafnium's internal processing of the operation. If the FF-A version of a
+borrower is v1.0, Hafnium provides FF-A v1.0 compliant memory transaction
+descriptors on memory retrieve response.
+
 PE MMU configuration
 --------------------
 
@@ -1318,6 +1394,25 @@
        direct request to SP2 by invoking FFA_RUN.
   - 9) SPMC resumes the pre-empted vCPU of SP2.
 
+EL3 interrupt handling
+~~~~~~~~~~~~~~~~~~~~~~
+
+In GICv3 based systems, EL3 interrupts are configured as Group0 secure
+interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an
+SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to
+request EL3 platform firmware to handle a pending Group0 interrupt.
+Similarly, SPMD registers a handler with interrupt management framework to
+delegate handling of Group0 interrupt to the platform if the interrupt triggers
+in normal world.
+
+ - Platform hook
+
+   - plat_spmd_handle_group0_interrupt
+
+     SPMD provides platform hook to handle Group0 secure interrupts. In the
+     current design, SPMD expects the platform not to delegate handling to the
+     NWd (such as through SDEI) while processing Group0 interrupts.
+
 Power management
 ----------------
 
@@ -1557,4 +1652,4 @@
 
 --------------
 
-*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
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/auth-framework.rst b/docs/design/auth-framework.rst
index 6913e66..597f955 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -236,18 +236,56 @@
                             void *sig_ptr, unsigned int sig_len,
                             void *sig_alg, unsigned int sig_alg_len,
                             void *pk_ptr, unsigned int pk_len);
+    int (*calc_hash)(enum crypto_md_algo alg, void *data_ptr,
+                     unsigned int data_len,
+                     unsigned char output[CRYPTO_MD_MAX_SIZE])
     int (*verify_hash)(void *data_ptr, unsigned int data_len,
                        void *digest_info_ptr, unsigned int digest_info_len);
+    int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
+                        size_t len, const void *key, unsigned int key_len,
+                        unsigned int key_flags, const void *iv,
+                        unsigned int iv_len, const void *tag,
+                        unsigned int tag_len);
 
 These functions are registered in the CM using the macro:
 
 .. code:: c
 
-    REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash);
+    REGISTER_CRYPTO_LIB(_name,
+                        _init,
+                        _verify_signature,
+                        _calc_hash,
+                        _verify_hash,
+                        _auth_decrypt,
+                        _convert_pk);
 
 ``_name`` must be a string containing the name of the CL. This name is used for
 debugging purposes.
 
+Crypto module provides a function ``_calc_hash`` to calculate and
+return the hash of the given data using the provided hash algorithm.
+This function is mainly used in the ``MEASURED_BOOT`` and ``DRTM_SUPPORT``
+features to calculate the hashes of various images/data.
+
+Optionally, a platform function can be provided to convert public key
+(_convert_pk). It is only used if the platform saves a hash of the ROTPK.
+Most platforms save the hash of the ROTPK, but some may save slightly different
+information - e.g the hash of the ROTPK plus some related information.
+Defining this function allows to transform the ROTPK used to verify
+the signature to the buffer (a platform specific public key) which
+hash is saved in OTP.
+
+.. code:: c
+
+    int (*convert_pk)(void *full_pk_ptr, unsigned int full_pk_len,
+                      void **hashed_pk_ptr, unsigned int *hashed_pk_len);
+
+
+-  ``full_pk_ptr``: Pointer to Distinguished Encoding Rules (DER) ROTPK.
+-  ``full_pk_len``: DER ROTPK size.
+-  ``hashed_pk_ptr``: to return a pointer to a buffer, which hash should be the one saved in OTP.
+-  ``hashed_pk_len``: previous buffer size
+
 Image Parser Module (IPM)
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -936,7 +974,7 @@
 based on mbed TLS, which can be found in
 ``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
 authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
-four functions:
+below functions:
 
 .. code:: c
 
@@ -945,6 +983,9 @@
                          void *sig_ptr, unsigned int sig_len,
                          void *sig_alg, unsigned int sig_alg_len,
                          void *pk_ptr, unsigned int pk_len);
+    int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
+                             unsigned int data_len,
+                             unsigned char output[CRYPTO_MD_MAX_SIZE])
     int verify_hash(void *data_ptr, unsigned int data_len,
                     void *digest_info_ptr, unsigned int digest_info_len);
     int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
@@ -975,6 +1016,6 @@
 
 --------------
 
-*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 8a20186..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
@@ -317,6 +317,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
 
+- ``ERRATA_A78_2712571``: This applies erratum 2712571 workaround to Cortex-A78
+   CPU, this erratum affects system configurations that do not use an ARM
+   interconnect IP. This needs to be enabled for revisions r0p0, r1p0, r1p1
+   and r1p2 and it is still open.
+
 -  ``ERRATA_A78_2742426``: This applies erratum 2742426 workaround to Cortex-A78
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 and
    it is still open.
@@ -347,8 +352,21 @@
   Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
   erratum is still open.
 
+- ``ERRATA_A78_AE_2712574`` : This applies erratum 2712574 workaround to
+  Cortex-A78 AE CPU. This erratum affects system configurations that do not use
+  an ARM interconnect IP. This needs to be enabled for revisions r0p0, r0p1 and
+  r0p2. This erratum is still open.
+
 For Cortex-A78C, the following errata build flags are defined :
 
+- ``ERRATA_A78C_1827430`` : This applies errata 1827430 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revision r0p0. The erratum is
+  fixed in r0p1.
+
+- ``ERRATA_A78C_1827440`` : This applies errata 1827440 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revision r0p0. The erratum is
+  fixed in r0p1.
+
 - ``ERRATA_A78C_2132064`` : This applies errata 2132064 workaround to
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
   it is still open.
@@ -365,6 +383,11 @@
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
   erratum is still open.
 
+- ``ERRATA_A78C_2712575`` : This applies erratum 2712575 workaround to
+  Cortex-A78C CPU, this erratum affects system configurations that do not use
+  an ARM interconnect IP. This needs to be enabled for revisions r0p1 and r0p2
+  and is still open.
+
 - ``ERRATA_A78C_2772121`` : This applies errata 2772121 workaround to
   Cortex-A78C CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
   This erratum is still open.
@@ -480,6 +503,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
    It is still open.
 
+- ``ERRATA_V1_2701953``: This applies erratum 2701953 workaround to Neoverse-V1
+   CPU, this erratum affects system configurations that do not use an ARM
+   interconnect IP. This needs to be enabled for revisions r0p0, r1p0 and r1p1.
+   It has been fixed in r1p2.
+
 -  ``ERRATA_V1_2743093``: This applies errata 2743093 workaround to Neoverse-V1
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
    CPU. It is still open.
@@ -492,6 +520,13 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, r1p2 of the
    CPU. It is still open.
 
+For Neoverse V2, the following errata build flags are defined :
+
+-  ``ERRATA_V2_2719103``: This applies errata 2719103 workaround to Neoverse-V2
+   CPU, this affects system configurations that do not use and ARM interconnect
+   IP. This needs to be enabled for revisions r0p0 and r0p1. It has been fixed
+   in r0p2.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -550,6 +585,11 @@
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+-  ``ERRATA_A710_2701952``: This applies erratum 2701952 workaround to Cortex-A710
+   CPU, and applies to system configurations that do not use and ARM
+   interconnect IP. This needs to be enabled for r0p0, r1p0, r2p0 and r2p1 and
+   is still open.
+
 -  ``ERRATA_A710_2768515``: This applies errata 2768515 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
    r2p1 of the CPU and is still open.
@@ -602,6 +642,11 @@
    CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
    in r0p3.
 
+- ``ERRATA_N2_2728475``: This applies erratum 2728475 workaround to Neoverse-N2
+   CPU, this erratum affects system configurations that do not use and ARM
+   interconnect IP. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
+   It is fixed in r0p3.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -639,6 +684,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0 of the CPU
    and is fixed in r2p1.
 
+- ``ERRATA_X2_2701952``: This applies erratum 2701952 workaround to Cortex-X2
+   CPU and affects system configurations that do not use an ARM interconnect IP.
+   This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 and is
+   still open.
+
 -  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to Cortex-X2
    CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
    CPU and is still open.
@@ -701,6 +751,13 @@
    Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
 
+For Cortex-A715, the following errata build flags are defined :
+
+-  ``ERRATA_A715_2701951``: This applies erratum 2701951 workaround to Cortex-A715
+   CPU and affects system configurations that do not use an ARM interconnect
+   IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
+   in r1p2.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 97f3550..3d648c4 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
@@ -25,12 +25,12 @@
 :ref:`Translation (XLAT) Tables Library`.
 
 TF-A can be built to support either AArch64 or AArch32 execution state.
-.. note::
 
- The descriptions in this chapter are for the Arm TrustZone architecture.
- For changes to the firmware design for the
- `Arm Confidential Compute Architecture (Arm CCA)`_ please refer to the
- chapter :ref:`Realm Management Extension (RME)`.
+.. note::
+    The descriptions in this chapter are for the Arm TrustZone architecture.
+    For changes to the firmware design for the `Arm Confidential Compute
+    Architecture (Arm CCA)`_ please refer to the chapter :ref:`Realm Management
+    Extension (RME)`.
 
 Cold boot
 ---------
@@ -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``
 
-To report the status of each errata workaround, the function shall use the
-assembler macro ``report_errata``, passing it:
+   It should obtain the cpu revision (with ``cpu_get_rev_var``), call its
+   revision checker, and perform the mitigation, should the erratum apply.
 
--  The build option that enables the errata;
+   It may only clobber x0 to x8. The rest should be treated as callee-saved.
 
--  The name of the CPU: this must be the same identifier that CPU driver
-   registered itself with, using ``declare_cpu_ops``;
+#. Register itself to the framework
 
--  And the errata identifier: the identifier must match what's used in the
-   errata's check function described above.
+   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.
 
-The errata status reporting function will be called once per CPU type/errata
-combination during the software's active life time.
+See the next section on how to do this easily.
+
+.. note::
 
-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.
+ 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::
+
+ 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.
+
+ For CVEs the ``erratum_id`` also becomes ``cve_<year>_<number>``.
+
+Errata framework helpers
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+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 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::
+
+    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
@@ -1759,6 +1762,10 @@
 
                    DRAM
     0xffffffff +----------+
+               | EL3 TZC  |
+    0xffe00000 |----------| (secure)
+               | AP TZC   |
+    0xff000000 +----------+
                :          :
     0x82100000 |----------|
                |HW_CONFIG |
@@ -1800,6 +1807,10 @@
 
                      DRAM
     0xffffffff +--------------+
+               |   EL3 TZC    |
+    0xffe00000 |--------------|  (secure)
+               |   AP TZC     |
+    0xff000000 +--------------+
                :              :
     0x82100000 |--------------|
                |  HW_CONFIG   |
@@ -1840,7 +1851,10 @@
 
                    DRAM
     0xffffffff +----------+
-               |  BL32    |  (secure)
+               |  EL3 TZC |
+    0xffe00000 |----------|  (secure)
+               |  AP TZC  |
+               |  (BL32)  |
     0xff000000 +----------+
                |          |
     0x82100000 |----------|
@@ -1880,6 +1894,20 @@
 
 ::
 
+                  DRAM
+    0xFFFFFFFF +----------+
+               |  SCP TZC |
+    0xFFE00000 |----------|
+               |  EL3 TZC |
+    0xFFC00000 |----------|  (secure)
+               |  AP TZC  |
+    0xFF000000 +----------+
+               |          |
+               :          :  (non-secure)
+               |          |
+    0x80000000 +----------+
+
+
                   Flash0
     0x0C000000 +----------+
                :          :
@@ -1909,9 +1937,14 @@
 ::
 
                    DRAM
-    0xFFE00000 +----------+
-               |  BL32    |  (secure)
-    0xFF000000 |----------|
+    0xFFFFFFFF +----------+
+               |  SCP TZC |
+    0xFFE00000 |----------|
+               |  EL3 TZC |
+    0xFFC00000 |----------|  (secure)
+               |  AP TZC  |
+               |  (BL32)  |
+    0xFF000000 +----------+
                |          |
                :          :  (non-secure)
                |          |
@@ -2592,16 +2625,29 @@
 section lists the usage of Architecture Extensions, and build flags
 controlling them.
 
+Build options
+~~~~~~~~~~~~~
+
+``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR``
+
-In general, and unless individually mentioned, the build options
-``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` select the Architecture Extension to
-target when building TF-A. Subsequent Arm Architecture Extensions are backward
-compatible with previous versions.
+These build options serve dual purpose
 
-The build system only requires that ``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` have a
-valid numeric value. These build options only control whether or not
-Architecture Extension-specific code is included in the build. Otherwise, TF-A
-targets the base Armv8.0-A architecture; i.e. as if ``ARM_ARCH_MAJOR`` == 8
-and ``ARM_ARCH_MINOR`` == 0, which are also their respective default values.
+- Determine the architecture extension support in TF-A build: All the mandatory
+  architectural features up to ``ARM_ARCH_MAJOR.ARM_ARCH_MINOR`` are included
+  and unconditionally enabled by TF-A build system.
+
+- Passed to compiler via "-march" option to generate binary target : Tell the
+  compiler to emit instructions upto ``ARM_ARCH_MAJOR.ARM_ARCH_MINOR``
+
+The build system requires that the platform provides a valid numeric value based on
+CPU architecture extension, otherwise it defaults to base Armv8.0-A architecture.
+Subsequent Arm Architecture versions also support extensions which were introduced
+in previous versions.
+
+**TO-DO** : Its planned to decouple the two functionalities and introduce a new macro
+for compiler usage. The requirement for this decoupling arises becasue TF-A code
+always provides support for the latest and greatest architecture features but this
+is not the case for the target compiler.
 
 .. seealso:: :ref:`Build Options`
 
@@ -2687,12 +2733,12 @@
 the toolchain  target architecture directive.
 
 Platform may choose to not define straight the toolchain target architecture
-directive by defining ``MARCH32_DIRECTIVE``.
+directive by defining ``MARCH_DIRECTIVE``.
 I.e:
 
 .. code:: make
 
-   MARCH32_DIRECTIVE := -mach=armv7-a
+   MARCH_DIRECTIVE := -mach=armv7-a
 
 Code Structure
 --------------
@@ -2743,7 +2789,7 @@
 
 -  `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D)`_
 
--  `Power State Coordination Interface PDD`_
+-  `PSCI`_
 
 -  `SMC Calling Convention`_
 
@@ -2753,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/reset-design.rst b/docs/design/reset-design.rst
index 666ee4f..f8c5a43 100644
--- a/docs/design/reset-design.rst
+++ b/docs/design/reset-design.rst
@@ -141,26 +141,27 @@
 Platform initialization
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-In this configuration, when the CPU resets to BL31 there should be no parameters
-that can be passed in registers by previous boot stages. Instead, the platform
-code in BL31 needs to know, or be able to determine, the location of the BL32
-(if required) and BL33 images and provide this information in response to the
-``bl31_plat_get_next_image_ep_info()`` function.
-
-.. note::
-   Some platforms that configure ``RESET_TO_BL31`` might still be able to
-   receive parameters in registers depending on their actual boot sequence. On
-   those occasions, and in addition to ``RESET_TO_BL31``, these platforms should
-   set ``RESET_TO_BL31_WITH_PARAMS`` to avoid the input registers from being
-   zeroed before entering BL31.
+In this configuration, since the CPU resets to BL31, no parameters are expected
+to be passed to BL31 (see notes below for clarification).
+Instead, the platform code in BL31 needs to know, or be able to determine, the
+location of the BL32 (if required) and BL33 images and provide this information
+in response to the ``bl31_plat_get_next_image_ep_info()`` function.
 
 Additionally, platform software is responsible for carrying out any security
 initialisation, for example programming a TrustZone address space controller.
 This might be done by the Trusted Boot Firmware or by platform code in BL31.
 
+.. note::
+   Even though RESET_TO_BL31 is designed such that BL31 is the reset BL image,
+   some platforms may wish to pass some arguments to BL31 as per the defined
+   contract between BL31 and previous bootloaders. Previous bootloaders can
+   pass arguments through registers x0 through x3. BL31 will preserve them and
+   propagate them to platform code, which will handle these arguments in an
+   IMPDEF manner.
+
 --------------
 
-*Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. |Default reset code flow| image:: ../resources/diagrams/default_reset_code.png
 .. |Reset code flow with programmable reset address| image:: ../resources/diagrams/reset_code_no_boot_type_check.png
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 3d82e69..ecc68b2 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -10,6 +10,8 @@
    measured_boot_poc
    drtm_poc
    rss
+   psci_osi_mode
+   measured_boot
 
 --------------
 
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
new file mode 100644
index 0000000..8130d7d
--- /dev/null
+++ b/docs/design_documents/measured_boot.rst
@@ -0,0 +1,212 @@
+Measured Boot Design
+====================
+
+This document briefly explains the Measured-Boot design implementation
+in |TF-A|.
+
+Introduction
+------------
+
+Measured Boot is the process of computing and securely recording hashes of code
+and critical data at each stage in the boot chain before the code/data is used.
+
+These measurements can be leveraged by other components in the system to
+implement a complete attestation system. For example, they could be used to
+enforce local attestation policies (such as releasing certain platform keys or
+not), or they could be securely sent to a remote challenger a.k.a. `verifier`
+after boot to attest to the state of the code and critical-data.
+
+Measured Boot does not authenticate the code or critical-data, but simply
+records what code/critical-data was present on the system during boot.
+
+It is assumed that BL1 is implicitly trusted (by virtue of immutability) and
+acts as the root of trust for measurement hence it is not measured.
+
+The Measured Boot implementation in TF-A supports multiple backends to securely
+store measurements mentioned below in the :ref:`Measured Boot Backends` section.
+
+Critical data
+-------------
+
+All firmware images - i.e. BLx images and their corresponding configuration
+files, if any - must be measured. In addition to that, there might be specific
+pieces of data which needs to be measured as well. These are typically different
+on each platform. They are referred to as *critical data*.
+
+Critical data for the platform can be determined using the following criteria:
+
+#. Data that influence boot flow behaviour such as -
+
+   - Configuration parameters that alter the boot flow path.
+   - Parameters that determine which firmware to load from NV-Storage to
+     SRAM/DRAM to pass the boot process successfully.
+
+#. Hardware configurations settings, debug settings and security policies
+   that need to be in a valid state for a device to maintain its security
+   posture during boot and runtime.
+#. Security-sensitive data that is being updated by hardware.
+
+Examples of Critical data:
+
+#. The list of errata workarounds being applied at reset.
+#. State of fuses such as whether an SoC is in secure mode.
+#. NV counters that determine whether firmware is up-to-date and secure.
+
+Measurement slot
+----------------
+
+The measurement slot resides in a Trusted Module and can be either a secure
+register or memory.
+The measurement slot is used to provide a method to cryptographically record
+(measure) images and critical data on a platform.
+The measurement slot update calculation, called an **extend** operation, is
+a one-way hash of all the previous measurements and the new measurement. It
+is the only way to change the slot value, thus no measurements can ever be
+removed or overwritten.
+
+.. _Measured Boot Backends:
+
+Measured Boot Backends
+----------------------
+
+The Measured Boot implementation in TF-A supports:
+
+#. Event Log
+
+   The TCG Event Log holds a record of measurements made into the Measurement
+   Slot aka PCR (Platform Configuration Register).
+
+   The `TCG EFI Protocol Specification`_ provides details on how to measure
+   components. The Arm document
+   `Arm® Server Base Security Guide`_ provides specific guidance for
+   measurements on an SBSA/SBBR server system. By considering these
+   specifications it is decided that -
+
+   #. Use PCR0 for images measurements.
+   #. Use PCR1 for Critical data measurements.
+
+   TCG has specified the architecture for the structure of this log in the
+   `TCG EFI Protocol Specification`_. The specification describes two event
+   log event records—the legacy, fixed size SHA1 structure called TCG_PCR_EVENT
+   and the variable length crypto agile structure called TCG_PCR_EVENT2. Event
+   Log driver implemented in TF-A covers later part.
+
+#. RSS
+
+   It is one of physical backend to extend the measurements. Please refer this
+   document :ref:`Runtime Security Subsystem (RSS)` for more details.
+
+Platform Interface
+------------------
+
+Every image which gets successfully loaded in memory (and authenticated, if
+trusted boot is enabled) then gets measured. In addition to that, platforms
+can measure any relevant piece of critical data at any point during the boot.
+The following diagram outlines the call sequence for Measured Boot platform
+interfaces invoked from generic code:
+
+.. image:: ../resources/diagrams/measured_boot_design.png
+
+These platform interfaces are used by BL1 and BL2 only, and are declared in
+``include/plat/common/platform.h``.
+BL31 does not load and thus does not measure any image.
+
+Responsibilities of these platform interfaces are -
+
+#. **Function : blx_plat_mboot_init()**
+
+   .. code-block:: c
+
+      void bl1_plat_mboot_init(void);
+      void bl2_plat_mboot_init(void);
+
+   Initialise all Measured Boot backends supported by the platform
+   (e.g. Event Log buffer, RSS). As these functions do not return any value,
+   the platform should deal with error management, such as logging the error
+   somewhere, or panicking the system if this is considered a fatal error.
+
+   - On the Arm FVP port -
+
+     - In BL1, this function is used to initialize the Event Log backend
+       driver, and also to write header information in the Event Log
+       buffer.
+     - In BL2, this function is used to initialize the Event Log buffer with
+       the information received from the BL1. It results in panic on
+       error.
+
+#. **Function : plat_mboot_measure_image()**
+
+   .. code-block:: c
+
+      int plat_mboot_measure_image(unsigned int image_id,
+                                   image_info_t *image_data);
+
+   - Measure the image using a hash function of the crypto module.
+
+   - Record the measurement in the corresponding backend -
+
+     - If it is Event Log backend, then record the measurement in TCG Event Log
+       format.
+     - If it is a secure crypto-processor (like RSS), then extend the designated
+       PCR (or slot) with the given measurement.
+   - This function must return 0 on success, a signed integer error code
+     otherwise.
+   - On the Arm FVP port, this function measures the given image and then
+     records that measurement in the Event Log buffer.
+     The passed id is used to retrieve information about on how to measure
+     the image (e.g. PCR number).
+
+#. **Function : blx_plat_mboot_finish()**
+
+   .. code-block:: c
+
+      void bl1_plat_mboot_finish(void);
+      void bl2_plat_mboot_finish(void);
+
+   - Do all teardown operations with respect to initialised Measured Boot backends.
+     This could be -
+
+     - Pass the Event Log details (start address and size) to Normal world or to
+       Secure World using any platform implementation way.
+     - Measure all critical data if any.
+     - As these functions do not return any value, the platform should deal with
+       error management, such as logging the error somewhere, or panicking the
+       system if this is considered a fatal error.
+
+   - On the Arm FVP port -
+
+     - In BL1, this function is used to pass the base address of
+       the Event Log buffer and its size to BL2 via tb_fw_config to extend the
+       Event Log buffer with the measurement of various images loaded by BL2.
+       It results in panic on error.
+     - In BL2, this function is used to pass the Event Log buffer information
+       (base address and size) to non-secure(BL33) and trusted OS(BL32) via
+       nt_fw and tos_fw config respectively.
+       See :ref:`DTB binding for Event Log properties` for a description of the
+       bindings used for Event Log properties.
+
+#. **Function : plat_mboot_measure_critical_data()**
+
+   .. code-block:: c
+
+      int plat_mboot_measure_critical_data(unsigned int critical_data_id,
+                                           const void *base,
+                                           size_t size);
+
+   This interface is not invoked by the generic code and it is up to the
+   platform layer to call it where appropriate.
+
+   This function measures the given critical data structure and records its
+   measurement using the Measured Boot backend driver.
+   This function must return 0 on success, a signed integer error code
+   otherwise.
+
+   In FVP, Non volatile counters get measured and recorded as Critical data
+   using the backend via this interface.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
+
+.. _Arm® Server Base Security Guide: https://developer.arm.com/documentation/den0086/latest
+.. _TCG EFI Protocol Specification: https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 2e25057..86cf4d1 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -5,10 +5,12 @@
 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.
+
+See details of :ref:`Measured Boot Design`.
 
 The driver also provides mechanisms to pass the Event Log to normal world if
 needed.
@@ -135,11 +137,11 @@
 
 (4) Now, you should be able to continue with step 5 in "`Get and build the solution`_"
     instructions. In order to enable support for Measured Boot, you need to
-    set the ``MEASURED_BOOT`` build option:
+    set the following build options:
 
     .. code:: shell
 
-       $ MEASURED_BOOT=y make -j `nproc`
+       $ MEASURED_BOOT=y MEASURED_BOOT_FTPM=y make -j `nproc`
 
     .. note::
        The build process will likely take a long time. It is strongly recommended to
diff --git a/docs/design_documents/psci_osi_mode.rst b/docs/design_documents/psci_osi_mode.rst
new file mode 100644
index 0000000..a6e1bdf
--- /dev/null
+++ b/docs/design_documents/psci_osi_mode.rst
@@ -0,0 +1,718 @@
+PSCI OS-initiated mode
+======================
+
+: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: Accepted
+
+.. contents:: Table of Contents
+
+Introduction
+------------
+
+Power state coordination
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+A power domain topology is a logical hierarchy of power domains in a system that
+arises from the physical dependencies between power domains.
+
+Local power states describe power states for an individual node, and composite
+power states describe the combined power states for an individual node and its
+parent node(s).
+
+Entry into low-power states for a topology node above the core level requires
+coordinating its children nodes. For example, in a system with a power domain
+that encompasses a shared cache, and a separate power domain for each core that
+uses the shared cache, the core power domains must be powered down before the
+shared cache power domain can be powered down.
+
+PSCI supports two modes of power state coordination: platform-coordinated and
+OS-initiated.
+
+Platform-coordinated
+~~~~~~~~~~~~~~~~~~~~
+
+Platform-coordinated mode is the default mode of power state coordination, and
+is currently the only supported mode in TF-A.
+
+In platform-coordinated mode, the platform is responsible for coordinating power
+states, and chooses the deepest power state for a topology node that can be
+tolerated by its children.
+
+OS-initiated
+~~~~~~~~~~~~
+
+OS-initiated mode is optional.
+
+In OS-initiated mode, the calling OS is responsible for coordinating power
+states, and may request for a topology node to enter a low-power state when
+its last child enters the low-power state.
+
+Motivation
+----------
+
+There are two reasons why OS-initiated mode might be a more suitable option than
+platform-coordinated mode for a platform.
+
+Scalability
+^^^^^^^^^^^
+
+In platform-coordinated mode, each core independently selects their own local
+power states, and doesn't account for composite power states that are shared
+between cores.
+
+In OS-initiated mode, the OS has knowledge of the next wakeup event for each
+core, and can have more precise control over the entry, exit, and wakeup
+latencies when deciding if a composite power state (e.g. for a cluster) is
+appropriate. This is especially important for multi-cluster SMP systems and
+heterogeneous systems like big.LITTLE, where different processor types can have
+different power efficiencies.
+
+Simplicity
+^^^^^^^^^^
+
+In platform-coordinated mode, the OS doesn't have visibility when the last core
+at a power level enters a low-power state. If the OS wants to perform last man
+activity (e.g. powering off a shared resource when it is no longer needed), it
+would have to communicate with an API side channel to know when it can do so.
+This could result in a design smell where the platform is using
+platform-coordinated mode when it should be using OS-initiated mode instead.
+
+In OS-initiated mode, the OS can perform last man activity if it selects a
+composite power state when the last core enters a low-power state. This
+eliminates the need for a side channel, and uses the well documented API between
+the OS and the platform.
+
+Current vendor implementations and workarounds
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* STMicroelectronics
+
+  * For their ARM32 platforms, they're using OS-initiated mode implemented in
+    OP-TEE.
+  * For their future ARM64 platforms, they are interested in using OS-initiated
+    mode in TF-A.
+
+* Qualcomm
+
+  * For their mobile platforms, they're using OS-initiated mode implemented in
+    their own custom secure monitor firmware.
+  * For their Chrome OS platforms, they're using platform-coordinated mode in
+    TF-A with custom driver logic to perform last man activity.
+
+* Google
+
+  * They're using platform-coordinated mode in TF-A with custom driver logic to
+    perform last man activity.
+
+Both Qualcomm and Google would like to be able to use OS-initiated mode in TF-A
+in order to simplify custom driver logic.
+
+Requirements
+------------
+
+PSCI_FEATURES
+^^^^^^^^^^^^^
+
+PSCI_FEATURES is for checking whether or not a PSCI function is implemented and
+what its properties are.
+
+.. c:macro:: PSCI_FEATURES
+
+   :param func_id: 0x8400_000A.
+   :param psci_func_id: the function ID of a PSCI function.
+   :retval NOT_SUPPORTED: if the function is not implemented.
+   :retval feature flags associated with the function: if the function is
+       implemented.
+
+CPU_SUSPEND feature flags
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Reserved, bits[31:2]
+* Power state parameter format, bit[1]
+
+  * A value of 0 indicates the original format is used.
+  * A value of 1 indicates the extended format is used.
+
+* OS-initiated mode, bit[0]
+
+  * A value of 0 indicates OS-initiated mode is not supported.
+  * A value of 1 indicates OS-initiated mode is supported.
+
+See sections 5.1.14 and 5.15 of the PSCI spec (DEN0022D.b) for more details.
+
+PSCI_SET_SUSPEND_MODE
+^^^^^^^^^^^^^^^^^^^^^
+
+PSCI_SET_SUSPEND_MODE is for switching between the two different modes of power
+state coordination.
+
+.. c:macro:: PSCI_SET_SUSPEND_MODE
+
+   :param func_id: 0x8400_000F.
+   :param mode: 0 indicates platform-coordinated mode, 1 indicates OS-initiated
+       mode.
+   :retval SUCCESS: if the request is successful.
+   :retval NOT_SUPPORTED: if OS-initiated mode is not supported.
+   :retval INVALID_PARAMETERS: if the requested mode is not a valid value (0 or
+       1).
+   :retval DENIED: if the cores are not in the correct state.
+
+Switching from platform-coordinated to OS-initiated is only allowed if the
+following conditions are met:
+
+* All cores are in one of the following states:
+
+  * Running.
+  * Off, through a call to CPU_OFF or not yet booted.
+  * Suspended, through a call to CPU_DEFAULT_SUSPEND.
+
+* None of the cores has called CPU_SUSPEND since the last change of mode or
+  boot.
+
+Switching from OS-initiated to platform-coordinated is only allowed if all cores
+other than the calling core are off, either through a call to CPU_OFF or not yet
+booted.
+
+If these conditions are not met, the PSCI implementation must return DENIED.
+
+See sections 5.1.19 and 5.20 of the PSCI spec (DEN0022D.b) for more details.
+
+CPU_SUSPEND
+^^^^^^^^^^^
+
+CPU_SUSPEND is for moving a topology node into a low-power state.
+
+.. c:macro:: CPU_SUSPEND
+
+   :param func_id: 0xC400_0001.
+   :param power_state: the requested low-power state to enter.
+   :param entry_point_address: the address at which the core must resume
+       execution following wakeup from a powerdown state.
+   :param context_id: this field specifies a pointer to the saved context that
+       must be restored on a core following wakeup from a powerdown state.
+   :retval SUCCESS: if the request is successful.
+   :retval INVALID_PARAMETERS: in OS-initiated mode, this error is returned when
+       a low-power state is requested for a topology node above the core level,
+       and at least one of the node's children is in a local low-power state
+       that is incompatible with the request.
+   :retval INVALID_ADDRESS: if the entry_point_address argument is invalid.
+   :retval DENIED: only in OS-initiated mode; this error is returned when a
+       low-power state is requested for a topology node above the core level,
+       and at least one of the node's children is running, i.e. not in a
+       low-power state.
+
+In platform-coordinated mode, the PSCI implementation coordinates requests from
+all cores to determine the deepest power state to enter.
+
+In OS-initiated mode, the calling OS is making an explicit request for a
+specific power state, as opposed to expressing a vote. The PSCI implementation
+must comply with the request, unless the request is not consistent with the
+implementation's view of the system's state, in which case, the implementation
+must return INVALID_PARAMETERS or DENIED.
+
+See sections 5.1.2 and 5.4 of the PSCI spec (DEN0022D.b) for more details.
+
+Power state formats
+~~~~~~~~~~~~~~~~~~~
+
+Original format
+
+* Power Level, bits[25:24]
+
+  * The requested level in the power domain topology to enter a low-power
+    state.
+
+* State Type, bit[16]
+
+  * A value of 0 indicates a standby or retention state.
+  * A value of 1 indicates a powerdown state.
+
+* State ID, bits[15:0]
+
+  * Field to specify the requested composite power state.
+  * The state ID encodings must uniquely describe every possible composite
+    power state.
+  * In OS-initiated mode, the state ID encoding must allow expressing the
+    power level at which the calling core is the last to enter a powerdown
+    state.
+
+Extended format
+
+* State Type, bit[30]
+* State ID, bits[27:0]
+
+Races in OS-initiated mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In OS-initiated mode, there are race windows where the OS's view and
+implementation's view of the system's state differ. It is possible for the OS to
+make requests that are invalid given the implementation's view of the system's
+state. For example, the OS might request a powerdown state for a node from one
+core, while at the same time, the implementation observes that another core in
+that node is powering up.
+
+To address potential race conditions in power state requests:
+
+* The calling OS must specify in each CPU_SUSPEND request the deepest power
+  level for which it sees the calling core as the last running core (last man).
+  This is required even if the OS doesn't want the node at that power level to
+  enter a low-power state.
+* The implementation must validate that the requested power states in the
+  CPU_SUSPEND request are consistent with the system's state, and that the
+  calling core is the last core running at the requested power level, or deny
+  the request otherwise.
+
+See sections 4.2.3.2, 6.2, and 6.3 of the PSCI spec (DEN0022D.b) for more
+details.
+
+Caveats
+-------
+
+CPU_OFF
+^^^^^^^
+
+CPU_OFF is always platform-coordinated, regardless of whether the power state
+coordination mode for suspend is platform-coordinated or OS-initiated. If all
+cores in a topology node call CPU_OFF, the last core will power down the node.
+
+In OS-initiated mode, if a subset of the cores in a topology node has called
+CPU_OFF, the last running core may call CPU_SUSPEND to request a powerdown state
+at or above that node's power level.
+
+See section 5.5.2 of the PSCI spec (DEN0022D.b) for more details.
+
+Implementation
+--------------
+
+Current implementation of platform-coordinated mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Platform-coordinated is currently the only supported power state coordination
+mode in TF-A.
+
+The functions of interest in the ``psci_cpu_suspend`` call stack are as follows:
+
+* ``psci_validate_power_state``
+
+  * This function calls a platform specific ``validate_power_state`` handler,
+    which takes the ``power_state`` parameter, and updates the ``state_info``
+    object with the requested states for each power level.
+
+* ``psci_find_target_suspend_lvl``
+
+  * This function takes the ``state_info`` object containing the requested power
+    states for each power level, and returns the deepest power level that was
+    requested to enter a low power state, i.e. the target power level.
+
+* ``psci_do_state_coordination``
+
+  * This function takes the target power level and the ``state_info`` object
+    containing the requested power states for each power level, and updates the
+    ``state_info`` object with the coordinated target power state for each
+    level.
+
+* ``pwr_domain_suspend``
+
+  * This is a platform specific handler that takes the ``state_info`` object
+    containing the target power states for each power level, and transitions
+    each power level to the specified power state.
+
+Proposed implementation of OS-initiated mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To add support for OS-initiated mode, the following changes are proposed:
+
+* Add a boolean build option ``PSCI_OS_INIT_MODE`` for a platform to enable
+  optional support for PSCI OS-initiated mode. This build option defaults to 0.
+
+.. note::
+
+   If ``PSCI_OS_INIT_MODE=0``, the following changes will not be compiled into
+   the build.
+
+* Update ``psci_features`` to return 1 in bit[0] to indicate support for
+  OS-initiated mode for CPU_SUSPEND.
+* Define a ``suspend_mode`` enum: ``PLAT_COORD`` and ``OS_INIT``.
+* Define a ``psci_suspend_mode`` global variable with a default value of
+  ``PLAT_COORD``.
+* Implement a new function handler ``psci_set_suspend_mode`` for
+  PSCI_SET_SUSPEND_MODE.
+* Since ``psci_validate_power_state`` calls a platform specific
+  ``validate_power_state`` handler, the platform implementation should populate
+  the ``state_info`` object based on the state ID from the given ``power_state``
+  parameter.
+* ``psci_find_target_suspend_lvl`` remains unchanged.
+* Implement a new function ``psci_validate_state_coordination`` that ensures the
+  request satisfies the following conditions, and denies any requests
+  that don't:
+
+  * The requested power states for each power level are consistent with the
+    system's state
+  * The calling core is the last core running at the requested power level
+
+  This function differs from ``psci_do_state_coordination`` in that:
+
+  * The ``psci_req_local_pwr_states`` map is not modified if the request were to
+    be denied
+  * The ``state_info`` argument is never modified since it contains the power
+    states requested by the calling OS
+
+* Update ``psci_cpu_suspend_start`` to do the following:
+
+  * If ``PSCI_SUSPEND_MODE`` is ``PLAT_COORD``, call
+    ``psci_do_state_coordination``.
+  * If ``PSCI_SUSPEND_MODE`` is ``OS_INIT``, call
+    ``psci_validate_state_coordination``. If validation fails, propagate the
+    error up the call stack.
+
+* 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
+
+Testing
+-------
+
+The proposed patches can be found at
+https://review.trustedfirmware.org/q/topic:psci-osi.
+
+Testing on FVP and Google platforms
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The proposed patches add a new CPU Suspend in OSI mode test suite to TF-A Tests.
+This has been enabled and verified on the FVP_Base_RevC-2xAEMvA platform and
+Google platforms, and excluded from all other platforms via the build option
+``PLAT_TESTS_SKIP_LIST``.
+
+Testing on STM32MP15
+^^^^^^^^^^^^^^^^^^^^
+
+The proposed patches have been tested and verified on the STM32MP15 platform,
+which has a single cluster with 2 CPUs, by Gabriel Fernandez
+<gabriel.fernandez@st.com> from STMicroelectronics with this device tree
+configuration:
+
+.. code-block:: devicetree
+
+   cpus {
+           #address-cells = <1>;
+           #size-cells = <0>;
+
+           cpu0: cpu@0 {
+                   device_type = "cpu";
+                   compatible = "arm,cortex-a7";
+                   reg = <0>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD0>;
+                   power-domain-names = "psci";
+           };
+           cpu1: cpu@1 {
+                   device_type = "cpu";
+                   compatible = "arm,cortex-a7";
+                   reg = <1>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD1>;
+                   power-domain-names = "psci";
+           };
+
+           idle-states {
+                   cpu_retention: cpu-retention {
+                           compatible = "arm,idle-state";
+                           arm,psci-suspend-param = <0x00000001>;
+                           entry-latency-us = <130>;
+                           exit-latency-us = <620>;
+                           min-residency-us = <700>;
+                           local-timer-stop;
+                   };
+           };
+
+           domain-idle-states {
+                   CLUSTER_STOP: core-power-domain {
+                           compatible = "domain-idle-state";
+                           arm,psci-suspend-param = <0x01000001>;
+                           entry-latency-us = <230>;
+                           exit-latency-us = <720>;
+                           min-residency-us = <2000>;
+                           local-timer-stop;
+                   };
+           };
+   };
+
+   psci {
+           compatible = "arm,psci-1.0";
+           method = "smc";
+
+           CPU_PD0: power-domain-cpu0 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&pd_core>;
+                   domain-idle-states = <&cpu_retention>;
+           };
+
+           CPU_PD1: power-domain-cpu1 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&pd_core>;
+                   domain-idle-states = <&cpu_retention>;
+           };
+
+           pd_core: power-domain-cluster {
+                   #power-domain-cells = <0>;
+                   domain-idle-states = <&CLUSTER_STOP>;
+           };
+   };
+
+Testing on Qualcomm SC7280
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The proposed patches have been tested and verified on the SC7280 platform by
+Maulik Shah <quic_mkshah@quicinc.com> from Qualcomm with this device tree
+configuration:
+
+.. code-block:: devicetree
+
+   cpus {
+           #address-cells = <2>;
+           #size-cells = <0>;
+
+           CPU0: cpu@0 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x0>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD0>;
+                   power-domain-names = "psci";
+           };
+
+           CPU1: cpu@100 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x100>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD1>;
+                   power-domain-names = "psci";
+           };
+
+           CPU2: cpu@200 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x200>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD2>;
+                   power-domain-names = "psci";
+           };
+
+           CPU3: cpu@300 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x300>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD3>;
+                   power-domain-names = "psci";
+           }
+
+           CPU4: cpu@400 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x400>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD4>;
+                   power-domain-names = "psci";
+           };
+
+           CPU5: cpu@500 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x500>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD5>;
+                   power-domain-names = "psci";
+           };
+
+           CPU6: cpu@600 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x600>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD6>;
+                   power-domain-names = "psci";
+           };
+
+           CPU7: cpu@700 {
+                   device_type = "cpu";
+                   compatible = "arm,kryo";
+                   reg = <0x0 0x700>;
+                   enable-method = "psci";
+                   power-domains = <&CPU_PD7>;
+                   power-domain-names = "psci";
+           };
+
+           idle-states {
+                   entry-method = "psci";
+
+                   LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
+                           compatible = "arm,idle-state";
+                           idle-state-name = "little-power-down";
+                           arm,psci-suspend-param = <0x40000003>;
+                           entry-latency-us = <549>;
+                           exit-latency-us = <901>;
+                           min-residency-us = <1774>;
+                           local-timer-stop;
+                   };
+
+                   LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 {
+                           compatible = "arm,idle-state";
+                           idle-state-name = "little-rail-power-down";
+                           arm,psci-suspend-param = <0x40000004>;
+                           entry-latency-us = <702>;
+                           exit-latency-us = <915>;
+                           min-residency-us = <4001>;
+                           local-timer-stop;
+                   };
+
+                   BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
+                           compatible = "arm,idle-state";
+                           idle-state-name = "big-power-down";
+                           arm,psci-suspend-param = <0x40000003>;
+                           entry-latency-us = <523>;
+                           exit-latency-us = <1244>;
+                           min-residency-us = <2207>;
+                           local-timer-stop;
+                   };
+
+                   BIG_CPU_SLEEP_1: cpu-sleep-1-1 {
+                           compatible = "arm,idle-state";
+                           idle-state-name = "big-rail-power-down";
+                           arm,psci-suspend-param = <0x40000004>;
+                           entry-latency-us = <526>;
+                           exit-latency-us = <1854>;
+                           min-residency-us = <5555>;
+                           local-timer-stop;
+                   };
+           };
+
+           domain-idle-states {
+                   CLUSTER_SLEEP_0: cluster-sleep-0 {
+                           compatible = "arm,idle-state";
+                           idle-state-name = "cluster-power-down";
+                           arm,psci-suspend-param = <0x40003444>;
+                           entry-latency-us = <3263>;
+                           exit-latency-us = <6562>;
+                           min-residency-us = <9926>;
+                           local-timer-stop;
+                   };
+           };
+   };
+
+   psci {
+           compatible = "arm,psci-1.0";
+           method = "smc";
+
+           CPU_PD0: cpu0 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+           };
+
+           CPU_PD1: cpu1 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+           };
+
+           CPU_PD2: cpu2 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+           };
+
+           CPU_PD3: cpu3 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+           };
+
+           CPU_PD4: cpu4 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+           };
+
+           CPU_PD5: cpu5 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+           };
+
+           CPU_PD6: cpu6 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+           };
+
+           CPU_PD7: cpu7 {
+                   #power-domain-cells = <0>;
+                   power-domains = <&CLUSTER_PD>;
+                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+           };
+
+           CLUSTER_PD: cpu-cluster0 {
+                   #power-domain-cells = <0>;
+                   domain-idle-states = <&CLUSTER_SLEEP_0>;
+           };
+   };
+
+Comparisons on Qualcomm SC7280
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+CPUIdle states
+~~~~~~~~~~~~~~
+
+* 8 CPUs, 1 L3 cache
+* Platform-coordinated mode
+
+  * CPUIdle states
+
+    * State0 - WFI
+    * State1 - Core collapse
+    * State2 - Rail collapse
+    * State3 - L3 cache off and system resources voted off
+
+* OS-initiated mode
+
+  * CPUIdle states
+
+    * State0 - WFI
+    * State1 - Core collapse
+    * State2 - Rail collapse
+
+  * Cluster domain idle state
+
+    * State3 - L3 cache off and system resources voted off
+
+.. image:: ../resources/diagrams/psci-flattened-vs-hierarchical-idle-states.png
+
+Results
+~~~~~~~
+
+* The following stats have been captured with fixed CPU frequencies from the use
+  case of 10 seconds of device idle with the display turned on and Wi-Fi and
+  modem turned off.
+* Count refers to the number of times a CPU or cluster entered power collapse.
+* Residency refers to the time in seconds a CPU or cluster stayed in power
+  collapse.
+* The results are an average of 3 iterations of actual counts and residencies.
+
+.. image:: ../resources/diagrams/psci-pc-mode-vs-osi-mode.png
+
+OS-initiated mode was able to scale better than platform-coordinated mode for
+multiple CPUs. The count and residency results for state3 (i.e. a cluster domain
+idle state) in OS-initiated mode for multiple CPUs were much closer to the
+results for a single CPU than in platform-coordinated mode.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index abfc8ec..a5633e9 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -207,10 +207,10 @@
    of the binary image. If set to 1, then only the ELF image is built.
    0 is the default.
 
--  ``DISABLE_MTPMU``: Boolean option to disable FEAT_MTPMU if implemented
-   (Armv8.6 onwards). Its default value is 0 to keep consistency with platforms
-   that do not implement FEAT_MTPMU. For more information on FEAT_MTPMU,
-   check the latest Arm ARM.
+-  ``DISABLE_MTPMU``: Numeric option to disable ``FEAT_MTPMU`` (Multi Threaded
+   PMU). ``FEAT_MTPMU`` is an optional feature available on Armv8.6 onwards.
+   This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+   mechanism. Default is ``0``.
 
 -  ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
    Board Boot authentication at runtime. This option is meant to be enabled only
@@ -230,11 +230,6 @@
    payload. Please refer to the "Booting an EL3 payload" section for more
    details.
 
--  ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions.
-   This is an optional architectural feature available on v8.4 onwards. Some
-   v8.2 implementations also implement an AMU and this option can be used to
-   enable this feature on those systems as well. Default is 0.
-
 -  ``ENABLE_AMU_AUXILIARY_COUNTERS``: Enables support for AMU auxiliary counters
    (also known as group 1 counters). These are implementation-defined counters,
    and as such require additional platform configuration. Default is 0.
@@ -261,13 +256,12 @@
    builds, but this behaviour can be overridden in each platform's Makefile or
    in the build command line.
 
--  ``ENABLE_FEAT_AMUv1``: Numeric value to enable access to the HAFGRTR_EL2
-   (Hypervisor Activity Monitors Fine-Grained Read Trap Register) during EL2
-   to EL3 context save/restore operations. This flag can take the values 0 to 2,
-   to align with the ``FEATURE_DETECTION`` mechanism. It is an optional feature
-   available on v8.4 and onwards and must be set to either 1 or 2 alongside
-   ``ENABLE_FEAT_FGT``, to access the HAFGRTR_EL2 register.
-   Default value is ``0``.
+-  ``ENABLE_FEAT_AMU``: Numeric value to enable Activity Monitor Unit
+   extensions. This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. This is an optional architectural feature
+   available on v8.4 onwards. Some v8.2 implementations also implement an AMU
+   and this option can be used to enable this feature on those systems as well.
+   This flag can take the values 0 to 2, the default is 0.
 
 -  ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1``
    extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6
@@ -327,12 +321,11 @@
    Default value is ``0``. ``FEAT_RNG_TRAP`` is an optional feature from
    Armv8.5 onwards.
 
--  ``ENABLE_FEAT_SB``: Numeric value to enable the ``FEAT_SB`` (Speculation
-   Barrier) extension allowing access to ``sb`` instruction. ``FEAT_SB`` is an
-   optional feature and defaults to ``0`` for pre-Armv8.5 CPUs but are mandatory
-   for Armv8.5 or later CPUs. This flag can take values 0 to 2, to align with
-   ``FEATURE_DETECTION`` mechanism. It is enabled from v8.5 and upwards and if
-   needed could be overidden from platforms explicitly. Default value is ``0``.
+-  ``ENABLE_FEAT_SB``: Boolean option to let the TF-A code use the ``FEAT_SB``
+   (Speculation Barrier) instruction ``FEAT_SB`` is an optional feature and
+   defaults to ``0`` for pre-Armv8.5 CPUs, but is mandatory for Armv8.5 or
+   later CPUs. It is enabled from v8.5 and upwards and if needed can be
+   overidden from platforms explicitly.
 
 -  ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2)
    extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4.
@@ -361,6 +354,32 @@
    flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_GCS``: Numeric value to set the bit SCR_EL3.GCSEn in EL3 to
+   allow use of Guarded Control Stack from EL2 as well as adding the GCS
+   registers to the EL2 context save/restore operations. This flag can take
+   the values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
@@ -413,27 +432,36 @@
    instrumented. Enabling this option enables the ``ENABLE_PMF`` build option
    as well. Default is 0.
 
--  ``ENABLE_SME_FOR_NS``: Boolean option to enable Scalable Matrix Extension
+-  ``ENABLE_SME_FOR_NS``: Numeric value to enable Scalable Matrix Extension
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
    registers so are enabled together. Using this option without
    ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure
-   world to trap to EL3. SME is an optional architectural feature for AArch64
+   world to trap to EL3. Requires ``ENABLE_SVE_FOR_NS`` to be set as SME is a
+   superset of SVE. SME is an optional architectural feature for AArch64
    and TF-A support is experimental. At this time, this build option cannot be
    used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to
-   build with these options will fail. Default is 0.
+   build with these options will fail. This flag can take the values 0 to 2, to
+   align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
+
+-  ``ENABLE_SME2_FOR_NS``: Numeric value to enable Scalable Matrix Extension
+   version 2 (SME2) for the non-secure world only. SME2 is an optional
+   architectural feature for AArch64 and TF-A support is experimental.
+   This should be set along with ENABLE_SME_FOR_NS=1, if not, the default SME
+   accesses will still be trapped. This flag can take the values 0 to 2, to
+   align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
 
 -  ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix
-   Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS
-   must also be set to use this. If enabling this, the secure world MUST
-   handle context switching for SME, SVE, and FPU/SIMD registers to ensure that
-   no data is leaked to non-secure world. This is experimental. Default is 0.
+   Extension for secure world. Used along with SVE and FPU/SIMD.
+   ENABLE_SME_FOR_NS and ENABLE_SVE_FOR_SWD must also be set to use this.
+   This is experimental. Default is 0.
 
--  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
+-  ``ENABLE_SPE_FOR_NS`` : Numeric value to enable Statistical Profiling
    extensions. This is an optional architectural feature for AArch64.
-   The default is 1 but is automatically disabled when the target architecture
-   is AArch32.
+   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   mechanism. The default is 2 but is automatically disabled when the target
+   architecture is AArch32.
 
--  ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
+-  ``ENABLE_SVE_FOR_NS``: Numeric value to enable Scalable Vector Extension
    (SVE) for the Non-secure world only. SVE is an optional architectural feature
    for AArch64. Note that when SVE is enabled for the Non-secure world, access
    to SIMD and floating-point functionality from the Secure world is disabled by
@@ -441,15 +469,15 @@
    This is to avoid corruption of the Non-secure world data in the Z-registers
    which are aliased by the SIMD and FP registers. The build option is not
    compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
-   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to
-   1. The default is 1 but is automatically disabled when ENABLE_SME_FOR_NS=1
-   since SME encompasses SVE. At this time, this build option cannot be used on
-   systems that have SPM_MM enabled.
+   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS``
+   enabled.  This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. At this time, this build option cannot be
+   used on systems that have SPM_MM enabled. The default is 1.
 
 -  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
    SVE is an optional architectural feature for AArch64. Note that this option
-   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it
-   is automatically disabled when the target architecture is AArch32.
+   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is
+   automatically disabled when the target architecture is AArch32.
 
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong", "default" and "none". The
@@ -503,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
@@ -610,17 +639,15 @@
    translation library (xlat tables v2) must be used; version 1 of translation
    library is not supported.
 
+-  ``IMPDEF_SYSREG_TRAP``: Numeric value to enable the handling traps for
+   implementation defined system register accesses from lower ELs. Default
+   value is ``0``.
+
 -  ``INVERTED_MEMMAP``: memmap tool print by default lower addresses at the
    bottom, higher addresses at the top. This build flag can be set to '1' to
    invert this behavior. Lower addresses will be printed at the top and higher
    addresses at the bottom.
 
--  ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
-   runtime software in AArch32 mode, which is required to run AArch32 on Juno.
-   By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
-   AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
-   images.
-
 -  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
    used for generating the PKCS keys and subsequent signing of the certificate.
    It accepts 5 values: ``rsa``, ``rsa_1_5``, ``ecdsa``, ``ecdsa-brainpool-regular``
@@ -740,26 +767,23 @@
    enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
    set to 1 as well.
 
+-  ``PSCI_OS_INIT_MODE``: Boolean flag to enable support for optional PSCI
+   OS-initiated mode. This option defaults to 0.
+
--  ``RAS_EXTENSION``: Numeric value to enable Armv8.2 RAS features. RAS features
+-  ``ENABLE_FEAT_RAS``: Numeric value to enable Armv8.2 RAS features. RAS features
    are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
    or later CPUs. This flag can take the values 0 to 2, to align with the
    ``FEATURE_DETECTION`` mechanism.
 
-   When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST_NS`` must also be
-   set to ``1``.
-
-   This option is disabled by default.
+-  ``RAS_FFH_SUPPORT``: Support to enable Firmware first handling of RAS errors
+   originating from NS world. When ``RAS_FFH_SUPPORT`` is set to ``1``,
+   ``HANDLE_EA_EL3_FIRST_NS`` and ``ENABLE_FEAT_RAS`` must also be set to ``1``.
 
 -  ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
    of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
    entrypoint) or 1 (CPU reset to BL31 entrypoint).
    The default value is 0.
 
--  ``RESET_TO_BL31_WITH_PARAMS``: If ``RESET_TO_BL31`` has been enabled, setting
-   this additional option guarantees that the input registers are not cleared
-   therefore allowing parameters to be passed to the BL31 entrypoint.
-   The default value is 0.
-
 -  ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
    in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
    instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
@@ -1078,10 +1102,11 @@
   ``FEATURE_DETECTION`` mechanism. The default is 0 and it is automatically
   disabled when the target architecture is AArch32.
 
-- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Boolean option to enable trace system
+- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Numeric value to enable trace system
   registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented
   but unused). This feature is available if trace unit such as ETMv4.x, and
-  ETE(extending ETM feature) is implemented. This flag is disabled by default.
+  ETE(extending ETM feature) is implemented. This flag can take the values
+  0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0.
 
 - ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers
   access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
@@ -1099,6 +1124,13 @@
   means platform hook won't be checked and CMOs will always be performed when
   related functions are called.
 
+- ``ERRATA_ABI_SUPPORT``: Boolean option to enable support for Errata management
+  firmware interface for the BL31 image. By default its disabled (``0``).
+
+- ``ERRATA_NON_ARM_INTERCONNECT``: Boolean option to enable support for the
+  errata mitigation for platforms with a non-arm interconnect using the errata
+  ABI. By default its disabled (``0``).
+
 GICv3 driver options
 --------------------
 
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index 4a48059..aa8c2bb 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -19,62 +19,79 @@
 
 For building a local copy of the |TF-A| documentation you will need:
 
-- Python 3 (3.5 or later)
+- Python 3 (3.8 or later)
 - PlantUML (1.2017.15 or later)
-- Python modules specified in ``docs/requirements.txt``
-
-   You can install these with ``pip3`` (the Python Package Installer) by
-   passing it the requirements file above (with ``-r``). An optional ``--user``
-   argument will install them locally, but you have to add their location to
-   $PATH (pip will emit a warning). Alternatively, they can be installed
-   globally (but will probably require root privileges).
-
-   .. note::
-      Although not necessary, it is recommended you use a virtual environment.
-      More advanced usage instructions for *pip* are beyond the scope of this
-      document but you can refer to the `pip homepage`_ for detailed guides.
-
+- `Poetry`_ (Python dependency manager)
 - Optionally, the `Dia`_ application can be installed if you need to edit
   existing ``.dia`` diagram files, or create new ones.
 
-An example set of installation commands for Ubuntu follows, assuming that the
-working directory is ``docs``:
+
+Below is an example set of instructions to get a working environment (tested on
+Ubuntu):
 
 .. code:: shell
 
     sudo apt install python3 python3-pip plantuml [dia]
-    pip3 install [--user] -r requirements.txt
-
-.. note::
-   Several other modules will be installed as dependencies. Please review
-   the list to ensure that there will be no conflicts with other modules already
-   installed in your environment.
+    curl -sSL https://install.python-poetry.org | python3 -
 
 Building rendered documentation
 -------------------------------
 
-Documents can be built into HTML-formatted pages from project root directory by
-running the following command.
+To install Python dependencies using Poetry:
 
 .. code:: shell
 
+    poetry install
+
+Poetry will create a new virtual environment and install all dependencies listed
+in ``pyproject.toml``. You can get information about this environment, such as
+its location and the Python version, with the command:
+
+.. code:: shell
+
+    poetry env info
+
+If you have already sourced a virtual environment, Poetry will respect this and
+install dependencies there.
+
-   make doc
+Once all dependencies are installed, the documentation can be compiled into
+HTML-formatted pages from the project root directory by running:
 
-Output from the build process will be placed in:
+.. code:: shell
+
+   poetry run make doc
 
-::
+Output from the build process will be placed in: ``docs/build/html``.
 
-   docs/build/html
+Other Output Formats
+~~~~~~~~~~~~~~~~~~~~
 
 We also support building documentation in other formats. From the ``docs``
 directory of the project, run the following command to see the supported
-formats. It is important to note that you will not get the correct result if
-the command is run from the project root directory, as that would invoke the
-top-level Makefile for |TF-A| itself.
+formats.
 
 .. code:: shell
 
+   poetry run make -C docs help
+
-   make help
+Building rendered documentation from Poetry's virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The command ``poetry run`` used in the steps above executes the input command
+from inside the project's virtual environment. The easiest way to activate this
+virtual environment is with the ``poetry shell`` command.
+
+Running ``poetry shell`` from the directory containing this project, activates
+the same virtual environment. This creates a sub-shell through which you can
+build the documentation directly with ``make``.
+
+.. code:: shell
+
+    poetry shell
+    make doc
+
+Type ``exit`` to deactivate the virtual environment and exit this new shell. For
+other use cases, please see the official `Poetry`_ documentation.
 
 Building rendered documentation from a container
 ------------------------------------------------
@@ -88,24 +105,23 @@
 
 .. code:: shell
 
-   docker run --rm -v $PWD:/TF sphinxdoc/sphinx \
-          bash -c 'cd /TF && \
-          pip3 install plantuml -r ./docs/requirements.txt && make doc'
+   docker run --rm -v $PWD:/tf-a sphinxdoc/sphinx \
+        bash -c 'cd /tf-a &&
+            apt-get update && apt-get install -y curl plantuml &&
+            curl -sSL https://install.python-poetry.org | python3 - &&
+            ~/.local/bin/poetry install && ~/.local/bin/poetry run make doc'
 
 The above command fetches the ``sphinxdoc/sphinx`` container from `docker
 hub`_, launches the container, installs documentation requirements and finally
 creates the documentation. Once done, exit the container and output from the
-build process will be placed in:
-
-::
-
-   docs/build/html
+build process will be placed in: ``docs/build/html``.
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
 
 .. _Sphinx: http://www.sphinx-doc.org/en/master/
+.. _Poetry: https://python-poetry.org/docs/
 .. _pip homepage: https://pip.pypa.io/en/stable/
 .. _Dia: https://wiki.gnome.org/Apps/Dia
 .. _docker: https://www.docker.com/
diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst
index 5ebabea..8180a3f 100644
--- a/docs/getting_started/index.rst
+++ b/docs/getting_started/index.rst
@@ -12,10 +12,9 @@
    build-options
    build-internals
    image-terminology
-   porting-guide
    psci-lib-integration-guide
    rt-svc-writers-guide
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 5b49d2e..f4c3c28 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -14,7 +14,7 @@
 |TF-A| can be built using either a Linux or a Windows machine as the build host.
 
 A relatively recent Linux distribution is recommended for building |TF-A|. We
-have performed tests using Ubuntu 20.04 LTS (64-bit) but other distributions
+have performed tests using Ubuntu 22.04 LTS (64-bit) but other distributions
 should also work fine as a base, provided that the necessary tools and libraries
 can be installed.
 
@@ -26,7 +26,7 @@
 |TF-A| can be built with any of the following *cross-compiler* toolchains that
 target the Armv7-A or Armv8-A architectures:
 
-- GCC >= 11.3.Rel1 (from the `Arm Developer website`_)
+- GCC >= 12.2.Rel1 (from the `Arm Developer website`_)
 
    You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
    AArch32 and AArch64 builds respectively.
@@ -77,11 +77,11 @@
 The following libraries are required for Trusted Board Boot and Measured Boot
 support:
 
-- mbed TLS == 2.28.1 (tag: ``mbedtls-2.28.1``)
+- mbed TLS == 3.4.0 (tag: ``mbedtls-3.4.0``)
 
 These tools are optional:
 
-- Device Tree Compiler (DTC) >= 1.4.6
+- Device Tree Compiler (DTC) >= 1.4.7
 
    Needed if you want to rebuild the provided Flattened Device Tree (FDT)
    source files (``.dts`` files). DTC is available for Linux through the package
@@ -98,6 +98,13 @@
    Git hooks and helper tools. Without these tools you will need to rely on the
    CI for feedback on commit message conformance.
 
+- Poetry >= 1.3.2
+
+   Required for managing Python dependencies, this will allow you to reliably
+   reproduce a Python environment to build documentation and run analysis tools.
+   Most importantly, it ensures your system environment will not be affected by
+   dependencies in the Python scripts.
+
 Package Installation (Linux)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -177,7 +184,7 @@
 
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
 .. _Gerrit Code Review: https://www.gerritcodereview.com/
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/global_substitutions.txt b/docs/global_substitutions.txt
index 0cf2946..80012e7 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -50,15 +50,18 @@
 .. |SP| replace:: :term:`SP`
 .. |SPD| replace:: :term:`SPD`
 .. |SPM| replace:: :term:`SPM`
+.. |SRTM| replace:: :term:`SRTM`
 .. |SSBS| replace:: :term:`SSBS`
 .. |SVE| replace:: :term:`SVE`
 .. |TBB| replace:: :term:`TBB`
 .. |TBBR| replace:: :term:`TBBR`
+.. |TCG| replace:: :term:`TCG`
 .. |TEE| replace:: :term:`TEE`
 .. |TF-A| replace:: :term:`TF-A`
 .. |TF-M| replace:: :term:`TF-M`
 .. |TLB| replace:: :term:`TLB`
 .. |TLK| replace:: :term:`TLK`
+.. |TPM| replace:: :term:`TPM`
 .. |TRNG| replace:: :term:`TRNG`
 .. |TSP| replace:: :term:`TSP`
 .. |TZC| replace:: :term:`TZC`
@@ -66,3 +69,4 @@
 .. |UEFI| replace:: :term:`UEFI`
 .. |WDOG| replace:: :term:`WDOG`
 .. |XLAT| replace:: :term:`XLAT`
+.. |ERRATA_ABI| replace:: :term:`ERRATA_ABI`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index e6b0239..58b7d99 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -70,6 +70,9 @@
    EHF
       Exception Handling Framework
 
+   ERRATA_ABI
+      Errata management firmware interface
+
    FCONF
       Firmware Configuration Framework
 
@@ -187,6 +190,9 @@
    SPM
       Secure Partition Manager
 
+   SRTM
+      Static Root of Trust for Measurement
+
    SSBS
       Speculative Store Bypass Safe. Introduced in Armv8.5, this configuration
       bit can be set by software to allow or prevent the hardware from
@@ -204,6 +210,9 @@
    TCB
       Trusted Compute Base
 
+   TCG
+      Trusted Computing Group
+
    TEE
       Trusted Execution Environment
 
@@ -219,8 +228,11 @@
    TLK
       Trusted Little Kernel. A Trusted OS from NVIDIA.
 
+   TPM
+      Trusted Platform Module
+
    TRNG
-      True Randon Number Generator (hardware based)
+      True Random Number Generator (hardware based)
 
    TSP
       Test Secure Payload
diff --git a/docs/index.rst b/docs/index.rst
index 3860199..a7a5993 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -11,11 +11,13 @@
    process/index
    components/index
    design/index
+   porting-guide
    plat/index
    perf/index
    security_advisories/index
    design_documents/index
    threat_model/index
+   tools/index
    change-log
    glossary
    license
@@ -84,11 +86,11 @@
 
 --------------
 
-*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _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/perf/index.rst b/docs/perf/index.rst
index bccad00..0938a17 100644
--- a/docs/perf/index.rst
+++ b/docs/perf/index.rst
@@ -5,10 +5,13 @@
    :maxdepth: 1
    :caption: Contents
 
+   psci-performance-instr
    psci-performance-juno
+   psci-performance-n1sdp
+   psci-performance-methodology
    tsp
    performance-monitoring-unit
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/perf/psci-performance-instr.rst b/docs/perf/psci-performance-instr.rst
new file mode 100644
index 0000000..16f386f
--- /dev/null
+++ b/docs/perf/psci-performance-instr.rst
@@ -0,0 +1,117 @@
+PSCI Performance Measurement
+============================
+
+TF-A provides two instrumentation tools for performing analysis of the PSCI
+implementation:
+
+* PSCI STAT
+* Runtime Instrumentation
+
+This page explains how they may be enabled and used to perform all varieties of
+analysis.
+
+Performance Measurement Framework
+---------------------------------
+
+The Performance Measurement Framework `PMF`_ is a framework that provides
+mechanisms for collecting and retrieving timestamps at runtime from the
+Performance Measurement Unit (`PMU`_). The PMU is a generalized abstraction for
+accessing CPU hardware registers used to measure hardware events. This means,
+for instance, that the PMU might be used to place instrumentation points at
+logical locations in code for tracing purposes.
+
+TF-A utilises the PMF as a backend for the two instrumentation services it
+provides--PSCI Statistics and Runtime Instrumentation. The PMF is used by
+these services to facilitate collection and retrieval of timestamps.  For
+instance, the PSCI Statistics service registers the PMF service
+``psci_svc`` to track its residency statistics.
+
+This is reserved a unique ID, name, and space in memory by the PMF. The
+framework provides a convenient interface for PSCI Statistics to retrieve
+values from ``psci_svc`` at runtime.  Alternatively, the service may be
+configured such that the PMF dumps those values to the console. A platform may
+choose to expose SMCs that allow retrieval of these timestamps from the
+service.
+
+This feature is enabled with the Boolean flag ``ENABLE_PMF``.
+
+PSCI Statistics
+---------------
+
+PSCI Statistics is a runtime service that provides residency statistics for
+power states used by the platform. The service tracks residency time and
+entry count. Residency time is the total time spent in a particular power
+state by a PE. The entry count is the number of times the PE has entered
+the power state. PSCI Statistics implements the optional functions
+``PSCI_STAT_RESIDENCY`` and ``PSCI_STAT_COUNT`` from the `PSCI`_
+specification.
+
+
+.. c:macro:: PSCI_STAT_RESIDENCY
+
+    :param target_cpu: Contains copy of affinity fields in the MPIDR register
+      for identifying the target core (See section 5.1.4 of `PSCI`_
+      specifications for more details).
+    :param power_state: identifier for a specific local
+      state. Generally, this parameter takes the same form as the power_state
+      parameter described for CPU_SUSPEND in section 5.4.2.
+
+    :returns: Time spent in ``power_state``, in microseconds, by ``target_cpu``
+      and the highest level expressed in ``power_state``.
+
+
+.. c:macro:: PSCI_STAT_COUNT
+
+    :param target_cpu: follows the same format as ``PSCI_STAT_RESIDENCY``.
+    :param power_state: follows the same format as ``PSCI_STAT_RESIDENCY``.
+
+    :returns: Number of times the state expressed in ``power_state`` has been
+      used by ``target_cpu`` and the highest level expressed in
+      ``power_state``.
+
+The implementation provides residency statistics only for low power states,
+and does this regardless of the entry mechanism into those states. The
+statistics it collects are set to 0 during shutdown or reset.
+
+PSCI Statistics is enabled with the Boolean build flag
+``ENABLE_PSCI_STAT``.  All Arm platforms utilise the PMF unless another
+collection backend is provided (``ENABLE_PMF`` is implicitly enabled).
+
+Runtime Instrumentation
+-----------------------
+
+The Runtime Instrumentation Service is an instrumentation tool that wraps
+around the PMF to provide timestamp data. Although the service is not
+restricted to PSCI, it is used primarily in TF-A to quantify the total time
+spent in the PSCI implementation. The tool can be used to instrument other
+components in TF-A as well. It is enabled with the Boolean flag
+``ENABLE_RUNTIME_INSTRUMENTATION``, and as with PSCI STAT, requires PMF to
+be enabled.
+
+In PSCI, this service provides instrumentation points in the
+following code paths:
+
+* Entry into the PSCI SMC handler
+* Exit from the PSCI SMC handler
+* Entry to low power state
+* Exit from low power state
+* Entry into cache maintenance operations in PSCI
+* Exit from cache maintenance operations in PSCI
+
+The service captures the cycle count, which allows for the time spent in the
+implementation to be calculated, given the frequency counter.
+
+PSCI SMC Handler Instrumentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The timestamp during entry into the handler is captured as early as possible
+during the runtime exception, prior to entry into the handler itself. All
+timestamps are stored in memory for later retrieval. The exit timestamp is
+captured after normal return from the PSCI SMC handler, or, if a low power state
+was requested, it is captured in the warm boot path.
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
+
+.. _PMF: ../design/firmware-design.html#performance-measurement-framework
+.. _PMU: performance-monitoring-unit.html
+.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index 7418669..7a484b8 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -25,62 +25,189 @@
 Juno supports CPU, cluster and system power down states, corresponding to power
 levels 0, 1 and 2 respectively. It does not support any retention states.
 
-We used the upstream `TF master as of 31/01/2017`_, building the platform using
-the ``ENABLE_RUNTIME_INSTRUMENTATION`` option:
+Given that runtime instrumentation using PMF is invasive, there is a small
+(unquantified) overhead on the results. PMF uses the generic counter for
+timestamps, which runs at 50MHz on Juno.
 
-.. code:: shell
+The following source trees and binaries were used:
 
-    make PLAT=juno ENABLE_RUNTIME_INSTRUMENTATION=1 \
-        SCP_BL2=<path/to/scp-fw.bin>                \
-        BL33=<path/to/test-fw.bin>                  \
-        all fip
+- TF-A [`v2.9-rc0`_]
+- TFTF [`v2.9-rc0`_]
 
-When using the debug build of TF, there was no noticeable difference in the
-results.
+Please see the Runtime Instrumentation `Testing Methodology`_ page for more
+details.
 
-The tests are based on an ARM-internal test framework. The release build of this
-framework was used because the results in the debug build became skewed; the
-console output prevented some of the tests from executing in parallel.
+Procedure
+---------
 
-The tests consist of both parallel and sequential tests, which are broadly
-described as follows:
+#. Build TFTF with runtime instrumentation enabled:
 
-- **Parallel Tests** This type of test powers on all the non-lead CPUs and
-  brings them and the lead CPU to a common synchronization point.  The lead CPU
-  then initiates the test on all CPUs in parallel.
+    .. code:: shell
 
-- **Sequential Tests** This type of test powers on each non-lead CPU in
-  sequence. The lead CPU initiates the test on a non-lead CPU then waits for the
-  test to complete before proceeding to the next non-lead CPU. The lead CPU then
-  executes the test on itself.
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=juno \
+            TESTS=runtime-instrumentation all
 
-In the results below, CPUs 0-3 refer to CPUs in the little cluster (A53) and
-CPUs 4-5 refer to CPUs in the big cluster (A57). In all cases CPU 4 is the lead
-CPU.
+#. Fetch Juno's SCP binary from TF-A's archive:
 
-``PSCI_ENTRY`` refers to the time taken from entering the TF PSCI implementation
-to the point the hardware enters the low power state (WFI). Referring to the TF
-runtime instrumentation points, this corresponds to:
-``(RT_INSTR_ENTER_HW_LOW_PWR - RT_INSTR_ENTER_PSCI)``.
+    .. code:: shell
 
-``PSCI_EXIT`` refers to the time taken from the point the hardware exits the low
-power state to exiting the TF PSCI implementation. This corresponds to:
-``(RT_INSTR_EXIT_PSCI - RT_INSTR_EXIT_HW_LOW_PWR)``.
+        curl --fail --connect-timeout 5 --retry 5 -sLS -o scp_bl2.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/juno/release/juno-bl2.bin
 
-``CFLUSH_OVERHEAD`` refers to the part of ``PSCI_ENTRY`` taken to flush the
-caches. This corresponds to: ``(RT_INSTR_EXIT_CFLUSH - RT_INSTR_ENTER_CFLUSH)``.
+#. Build TF-A with the following build options:
 
-Note there is very little variance observed in the values given (~1us), although
-the values for each CPU are sometimes interchanged, depending on the order in
-which locks are acquired. Also, there is very little variance observed between
-executing the tests sequentially in a single boot or rebooting between tests.
+    .. code:: shell
 
-Given that runtime instrumentation using PMF is invasive, there is a small
-(unquantified) overhead on the results. PMF uses the generic counter for
-timestamps, which runs at 50MHz on Juno.
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=juno \
+            BL33="/path/to/tftf.bin" SCP_BL2="scp_bl2.bin" \
+            ENABLE_RUNTIME_INSTRUMENTATION=1 fiptool all fip
+
+#. Load the following images onto the development board: ``fip.bin``,
+   ``scp_bl2.bin``.
+
+Results
+-------
+
+``CPU_SUSPEND`` to deepest power level
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   243.76  |  239.92 |     6.32    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   663.5   |  30.32  |    167.82   |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   105.12  |  22.84  |     5.88    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   384.16  |  19.06  |     4.7     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   523.98  |  270.46 |     4.74    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   950.54  |  220.9  |     89.2    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   266.96  |  31.74  |    167.92   |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   266.9   |  31.52  |    167.82   |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   279.86  |  23.42  |    87.52    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   101.38  |   18.8  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   101.18  |  19.28  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   101.32  |  19.02  |     4.62    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_SUSPEND`` to power level 0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Results and Commentary
-----------------------
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    +---------+------+-----------+---------+-------------+
+    |    0    |  0   |   661.94  |  22.88  |     9.66    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   801.64  |  23.38  |     9.62    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   105.56  |  16.02  |     8.12    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   245.42  |  16.26  |     7.78    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   384.42  |   16.1  |     7.84    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   523.74  |   15.4  |     8.02    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   102.16  |  23.64  |     6.7     |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   101.66  |  23.78  |     6.6     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   277.74  |  15.96  |     4.66    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    98.0   |  15.88  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   97.66   |  15.88  |     4.62    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   97.76   |  15.38  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_OFF`` on all non-lead CPUs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
+core to the deepest power level.
+
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   265.38  |  34.12  |    167.36   |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   265.72  |  33.98  |    167.48   |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   185.3   |  23.18  |    87.42    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   101.58  |  23.46  |     4.48    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   101.66  |  22.02  |     4.72    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   101.48  |  22.22  |     4.52    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_VERSION`` in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +=============+========+==============+
+    |      0      |   0    |     1.22     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     1.2      |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.6      |
+    +-------------+--------+--------------+
+    |      1      |   1    |     1.08     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     1.04     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     1.04     |
+    +-------------+--------+--------------+
+
+Annotated Historic Results
+--------------------------
+
+The following results are based on the upstream `TF master as of 31/01/2017`_.
+TF-A was built using the same build instructions as detailed in the procedure
+above.
+
+In the results below, CPUs 0-3 refer to CPUs in the little cluster (A53) and
+CPUs 4-5 refer to CPUs in the big cluster (A57). In all cases CPU 4 is the lead
+CPU.
+
+``PSCI_ENTRY`` corresponds to the powerdown latency, ``PSCI_EXIT`` the wakeup latency, and
+``CFLUSH_OVERHEAD`` the latency of the cache flush operation.
 
 ``CPU_SUSPEND`` to deepest power level on all CPUs in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -290,3 +417,5 @@
 
 .. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
+.. _v2.9-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.9-rc0
+.. _Testing Methodology: ../perf/psci-performance-methodology.html
diff --git a/docs/perf/psci-performance-methodology.rst b/docs/perf/psci-performance-methodology.rst
new file mode 100644
index 0000000..a9f379d
--- /dev/null
+++ b/docs/perf/psci-performance-methodology.rst
@@ -0,0 +1,55 @@
+Runtime Instrumentation Methodology
+===================================
+
+This document outlines steps for undertaking performance measurements of key
+operations in the Trusted Firmware-A Power State Coordination Interface (PSCI)
+implementation, using the in-built Performance Measurement Framework (PMF) and
+runtime instrumentation timestamps.
+
+Framework
+~~~~~~~~~
+
+The tests are based on the ``runtime-instrumentation`` test suite provided by
+the Trusted Firmware Test Framework (TFTF). The release build of this framework
+was used because the results in the debug build became skewed; the console
+output prevented some of the tests from executing in parallel.
+
+The tests consist of both parallel and sequential tests, which are broadly
+described as follows:
+
+- **Parallel Tests** This type of test powers on all the non-lead CPUs and
+  brings them and the lead CPU to a common synchronization point.  The lead CPU
+  then initiates the test on all CPUs in parallel.
+
+- **Sequential Tests** This type of test powers on each non-lead CPU in
+  sequence. The lead CPU initiates the test on a non-lead CPU then waits for the
+  test to complete before proceeding to the next non-lead CPU. The lead CPU then
+  executes the test on itself.
+
+Note there is very little variance observed in the values given (~1us), although
+the values for each CPU are sometimes interchanged, depending on the order in
+which locks are acquired. Also, there is very little variance observed between
+executing the tests sequentially in a single boot or rebooting between tests.
+
+Given that runtime instrumentation using PMF is invasive, there is a small
+(unquantified) overhead on the results. PMF uses the generic counter for
+timestamps, which runs at 50MHz on Juno.
+
+Metrics
+~~~~~~~
+
+.. glossary::
+
+   Powerdown Latency
+        Time taken from entering the TF PSCI implementation to the point the hardware
+        enters the low power state (WFI). Referring to the TF runtime instrumentation points, this
+        corresponds to: ``(RT_INSTR_ENTER_HW_LOW_PWR - RT_INSTR_ENTER_PSCI)``.
+
+   Wakeup Latency
+        Time taken from the point the hardware exits the low power state to exiting
+        the TF PSCI implementation. This corresponds to: ``(RT_INSTR_EXIT_PSCI -
+        RT_INSTR_EXIT_HW_LOW_PWR)``.
+
+   Cache Flush Latency
+        Time taken to flush the caches during powerdown. This corresponds to:
+        ``(RT_INSTR_EXIT_CFLUSH - RT_INSTR_ENTER_CFLUSH)``.
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
new file mode 100644
index 0000000..70a1436
--- /dev/null
+++ b/docs/perf/psci-performance-n1sdp.rst
@@ -0,0 +1,203 @@
+Runtime Instrumentation Testing - N1SDP
+=======================================
+
+For this test we used the N1 System Development Platform (`N1SDP`_), which
+contains an SoC consisting of two dual-core Arm N1 clusters.
+
+The following source trees and binaries were used:
+
+- TF-A [`v2.9-rc0-16-g666aec401`_]
+- TFTF [`v2.9-rc0`_]
+- SCP/MCP `Prebuilt Images`_
+
+Please see the Runtime Instrumentation `Testing Methodology`_ page for more
+details.
+
+Procedure
+---------
+
+#. Build TFTF with runtime instrumentation enabled:
+
+    .. code:: shell
+
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=n1sdp \
+            TESTS=runtime-instrumentation all
+
+#. Build TF-A with the following build options:
+
+    .. code:: shell
+
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=n1sdp \
+            ENABLE_RUNTIME_INSTRUMENTATION=1 fiptool all
+
+#. Fetch the SCP firmware images:
+
+    .. code:: shell
+
+        curl --fail --connect-timeout 5 --retry 5 \
+            -sLS -o build/n1sdp/release/scp_rom.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-bl1.bin
+        curl --fail --connect-timeout 5 \
+            --retry 5 -sLS -o build/n1sdp/release/scp_ram.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-bl2.bin
+
+#. Fetch the MCP firmware images:
+
+    .. code:: shell
+
+        curl --fail --connect-timeout 5 --retry 5 \
+            -sLS -o build/n1sdp/release/mcp_rom.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-mcp-bl1.bin
+        curl --fail --connect-timeout 5 --retry 5 \
+            -sLS -o build/n1sdp/release/mcp_ram.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-mcp-bl2.bin
+
+#. Using the fiptool, create a new FIP package and append the SCP ram image onto
+   it.
+
+    .. code:: shell
+
+        ./tools/fiptool/fiptool create --blob \
+                uuid=cfacc2c4-15e8-4668-82be-430a38fad705,file=build/n1sdp/release/bl1.bin \
+                --scp-fw build/n1sdp/release/scp_ram.bin build/n1sdp/release/scp_fw.bin
+
+#. Append the MCP image to the FIP.
+
+    .. code:: shell
+
+        ./tools/fiptool/fiptool create \
+            --blob uuid=54464222-a4cf-4bf8-b1b6-cee7dade539e,file=build/n1sdp/release/mcp_ram.bin \
+            build/n1sdp/release/mcp_fw.bin
+
+#. Then, add TFTF as the Non-Secure workload in the FIP image:
+
+    .. code:: shell
+
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=n1sdp \
+            ENABLE_RUNTIME_INSTRUMENTATION=1 SCP_BL2=/dev/null \
+            BL33=<path/to/tftf.bin>  fip
+
+#. Load the following images onto the development board: ``fip.bin``,
+   ``scp_rom.bin``, ``scp_ram.bin``, ``mcp_rom.bin``, and ``mcp_ram.bin``.
+
+.. note::
+
+    These instructions presume you have a complete firmware stack. The N1SDP
+    `user guide`_ provides a detailed explanation on how to get setup from
+    scratch.
+
+Results
+-------
+
+``CPU_SUSPEND`` to deepest power level
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    3.44   |  10.04  |     0.4     |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    4.98   |  12.72  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    3.58   |  15.42  |     0.2     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    5.24   |  17.78  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.82   |   9.98  |     0.32    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    1.96   |   9.96  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    2.0    |   10.5  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    2.22   |  10.56  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_SUSPEND`` to power level 0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.52   |  11.84  |     0.34    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    1.1    |  13.66  |     0.14    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    2.18   |   9.48  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    2.06   |   14.4  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.54   |   9.34  |     0.3     |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    1.88   |   9.5   |     0.16    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    1.86   |   9.86  |     0.2     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    2.02   |   9.64  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_OFF`` on all non-lead CPUs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
+core to the deepest power level.
+
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.86   |   9.88  |     0.32    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    21.1   |  12.44  |     0.42    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   21.22   |   13.2  |     0.32    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   21.56   |  13.18  |     0.54    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_VERSION`` in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +=============+========+==============+
+    |      0      |   0    |     0.08     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     0.22     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.28     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.26     |
+    +-------------+--------+--------------+
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
+
+.. _v2.9-rc0-16-g666aec401: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/v2.9-rc0-16-g666aec401
+.. _v2.9-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.9-rc0
+.. _user guide: https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-docs/-/blob/master/docs/n1sdp/user-guide.rst
+.. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.11.0/n1sdp/release/
+.. _N1SDP: https://developer.arm.com/documentation/101489/latest
+.. _Testing Methodology: ../perf/psci-performance-methodology.html
\ No newline at end of file
diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst
index 3e9ce51..8e967dc 100644
--- a/docs/plat/allwinner.rst
+++ b/docs/plat/allwinner.rst
@@ -23,6 +23,8 @@
 +------+-------------------+
 | H313 | sun50i_h616       |
 +------+-------------------+
+| T507 | sun50i_h616       |
++------+-------------------+
 | R329 | sun50i_r329       |
 +------+-------------------+
 
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 68eb3ec..e0b9242 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -101,6 +101,14 @@
    the Arm Juno platform has this included in its ``HW_CONFIG`` and the platform
    only loads the ``HW_CONFIG`` in AArch64 builds. Default is 0.
 
+-  ``ARM_ETHOSN_NPU_TZMP1``: boolean option to enable TZMP1 support for the
+   Arm® Ethos™-N NPU. Requires ``ARM_ETHOSN_NPU_DRIVER`` and
+   ``TRUSTED_BOARD_BOOT`` to be enabled.
+
+-  ``ARM_ETHOSN_NPU_FW``: location of the NPU firmware binary
+   (```ethosn.bin```). This firmware image will be included in the FIP and
+   loaded at runtime.
+
 -  ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the
    SPMC Core manifest. Valid when ``SPD=spmd`` is selected.
 
@@ -161,8 +169,23 @@
    require all the CPUs to execute the CPU specific power down sequence to
    complete a warm reboot sequence in which only the CPUs are power cycled.
 
+Arm FVP Build Options
+---------------------
+
+- ``FVP_TRUSTED_SRAM_SIZE``: Size (in kilobytes) of the Trusted SRAM region to
+  utilize when building for the FVP platform. This option defaults to 256.
+
+Arm Juno Build Options
+----------------------
+
+-  ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
+   runtime software in AArch32 mode, which is required to run AArch32 on Juno.
+   By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
+   AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
+   images.
+
 --------------
 
 .. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 42c0eda..fcfa04a 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -51,7 +51,6 @@
 -  ``FVP_Morello``            (Version 0.11/33)
 -  ``FVP_RD_E1_edge``         (Version 11.17/29)
 -  ``FVP_RD_V1``              (Version 11.17/29)
--  ``FVP_TC0`` (Version 11.17/18)
 -  ``FVP_TC1`` (Version 11.17/33)
 -  ``FVP_TC2`` (Version 11.18/28)
 
@@ -631,7 +630,7 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
 
 .. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
 .. _Arm's website: `FVP models`_
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index d741d58..5320a3b 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -56,7 +56,7 @@
 
 #. Obtain SCP binaries (Juno)
 
-   This version of TF-A is tested with SCP version 2.8.0 on Juno. You can
+   This version of TF-A is tested with SCP version 2.12.0 on Juno. You can
    download pre-built SCP binaries (``scp_bl1.bin`` and ``scp_bl2.bin``)
    from `TF-A downloads page`_. Alternatively, you can `build
    the binaries from source`_.
@@ -245,8 +245,8 @@
 
 .. _Linaro release software stack: http://releases.linaro.org/members/arm/platforms/
 .. _Juno platform software user guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/juno/user-guide.rst
-.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.8.0/juno/
+.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/juno/
 .. _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/arm/tc/index.rst b/docs/plat/arm/tc/index.rst
index df1847d..c5058f5 100644
--- a/docs/plat/arm/tc/index.rst
+++ b/docs/plat/arm/tc/index.rst
@@ -17,10 +17,9 @@
 (TARGET_PLATFORM=1), TC2 (TARGET_PLATFORM=2) platforms w.r.t to TF-A
 is the CPUs supported as below:
 
--  TC0 has support for Cortex A510, Cortex A710 and Cortex X2.
--  TC1 has support for Cortex A510, Cortex Makalu and Cortex X3.
--  TC2 has support for Hayes and Hunter Arm CPUs.
-
+-  TC0 has support for Cortex A510, Cortex A710 and Cortex X2. (Note TC0 is now deprecated)
+-  TC1 has support for Cortex A510, Cortex A715 and Cortex X3.
+-  TC2 has support for Cortex A520, Cortex A720 and Cortex x4.
 
 Boot Sequence
 -------------
@@ -58,6 +57,6 @@
 
 --------------
 
-*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
 
 .. _Arm Toolchain: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
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/imx9.rst b/docs/plat/imx9.rst
new file mode 100644
index 0000000..4adaae3
--- /dev/null
+++ b/docs/plat/imx9.rst
@@ -0,0 +1,60 @@
+NXP i.MX 9 Series
+==================
+
+Building on the market-proven i.MX 6 and i.MX 8 series, i.MX 9 series applications
+processors bring together higher performance applications cores, an independent
+MCU-like real-time domain, Energy Flex architecture, state-of-the-art security
+with EdgeLock® secure enclave and dedicated multi-sensory data processing engines
+(graphics, image, display, audio and voice). The i.MX 9 series, part of the EdgeVerse™
+edge computing platform, integrates hardware neural processing units across many
+members of the series for acceleration of machine learning applications at the edge
+`i.MX9 Applications Processors`_.
+
+Boot Sequence
+-------------
+
+BootROM --> SPL --> BL31 --> BL33(u-boot) --> Linux kernel
+
+How to build
+------------
+
+Build Procedure
+~~~~~~~~~~~~~~~
+
+-  Prepare AARCH64 toolchain.
+
+- Get the ELE FW image from NXP linux SDK package
+
+-  Build SPL and u-boot firstly, and get binary images: u-boot-spl.bin,
+   u-boot.bin and dtb
+
+-  Build TF-A
+
+   Build bl31:
+
+   .. code:: shell
+
+       CROSS_COMPILE=aarch64-linux-gnu- make PLAT=<Target_SoC> bl31
+
+   Target_SoC should be "imx93" for i.MX93 SoC.
+
+Deploy TF-A Images
+~~~~~~~~~~~~~~~~~~
+
+TF-A binary(bl31.bin), u-boot-spl.bin u-boot.bin, ELE FW image are combined
+together to generate a binary file called flash.bin, the imx-mkimage tool is
+used to generate flash.bin, and flash.bin needs to be flashed into SD card
+with certain offset for BOOT ROM.
+
+Reference Documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Details on how to prepare, generate & deploy the boot image be found in following documents:
+
+- i.MX Linux User's Guide
+  `link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
+- i.MX Linux Reference Manual
+  `link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
+
+.. _i.MX9 Applications Processors: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-9-processors:IMX9-PROCESSORS
+
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index a4e2067..fe2cc44 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
@@ -26,6 +27,7 @@
    warp7
    imx8
    imx8m
+   imx9
    nxp/index
    poplar
    qemu
@@ -76,7 +78,9 @@
 +----------------+----------------+--------------------+--------------------+
 |    tc0         |      Arm       |        2.8         |       3.0          |
 +----------------+----------------+--------------------+--------------------+
+|    rde1edge    |      Arm       |        2.9         |       3.1          |
++----------------+----------------+--------------------+--------------------+
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/plat/qti-msm8916.rst b/docs/plat/qti-msm8916.rst
index 09a79b7..d7c3642 100644
--- a/docs/plat/qti-msm8916.rst
+++ b/docs/plat/qti-msm8916.rst
@@ -7,7 +7,7 @@
 is the `DragonBoard 410c`_ single-board computer, but the SoC is also used in
 various mid-range smartphones/tablets.
 
-The TF-A/BL31 port for MSM8916 provides a minimal, community-maintained
+The TF-A port for MSM8916 provides a minimal, community-maintained
 EL3 firmware. It is primarily based on information from the public
 `Snapdragon 410E Technical Reference Manual`_ combined with a lot of
 trial and error to actually make it work.
@@ -20,8 +20,7 @@
 
 Functionality
 -------------
-
-The BL31 port is much more minimal compared to the original firmware and
+The TF-A port is much more minimal compared to the original firmware and
 therefore expects the non-secure world (e.g. Linux) to manage more hardware,
 such as the SMMUs and all remote processors (RPM, WCNSS, Venus, Modem).
 Everything except modem is currently functional with a slightly modified version
@@ -41,28 +40,74 @@
 
 Boot Flow
 ---------
-BL31 replaces the original ``tz`` firmware in the boot flow::
+BL31 (AArch64) or BL32/SP_MIN (AArch32) replaces the original ``tz`` firmware
+in the boot flow::
 
 	Boot ROM (PBL) -> SBL -> BL31 (EL3) -> U-Boot (EL2) -> Linux (EL2)
 
-By default, BL31 enters the non-secure world in EL2 AArch64 state at address
-``0x8f600000``. The original hypervisor firmware (``hyp``) is not used, you can
-use KVM or another hypervisor. The entry address is fixed in the BL31 binary
-but can be changed using the ``PRELOADED_BL33_BASE`` make file parameter.
+After initialization the normal world starts at a fixed entry address in EL2/HYP
+mode, configured using ``PRELOADED_BL33_BASE``. At runtime, it is expected that
+the normal world bootloader was already loaded into RAM by a previous firmware
+component (usually SBL) and that it is capable of running in EL2/HYP mode.
 
-Using an AArch64 bootloader (such as `U-Boot for DragonBoard 410c`_) is
-recommended. AArch32 bootloaders (such as the original Little Kernel bootloader
-from Qualcomm) are not directly supported, although it is possible to use an EL2
-shim loader to temporarily switch to AArch32 state.
+`U-Boot for DragonBoard 410c`_ is recommended if possible. The original Little
+Kernel-based bootloader from Qualcomm does not support EL2/HYP, but can be
+booted using an additional shim loader such as `tfalkstub`_.
 
-Installation
-------------
-First, setup the cross compiler for AArch64 and build TF-A for ``msm8916``::
+Build
+-----
+It is possible to build for either AArch64 or AArch32. AArch64 is the preferred
+build option.
 
-	$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=msm8916
+AArch64 (BL31)
+^^^^^^^^^^^^^^
+Setup the cross compiler for AArch64 and build BL31 for ``msm8916``::
+
+	$ make CROSS_COMPILE=aarch64-none-elf- PLAT=msm8916
 
 The BL31 ELF image is generated in ``build/msm8916/release/bl31/bl31.elf``.
-This image must be "signed" before flashing it, even if the board has secure
+
+AArch32 (BL32/SP_MIN)
+^^^^^^^^^^^^^^^^^^^^^
+Setup the cross compiler for AArch32 and build BL32 with SP_MIN for ``msm8916``::
+
+	$ make CROSS_COMPILE=arm-none-eabi- PLAT=msm8916 ARCH=aarch32 AARCH32_SP=sp_min
+
+The BL32 ELF image is generated in ``build/msm8916/release/bl32/bl32.elf``.
+
+Build Options
+-------------
+Some options can be changed at build time by adding them to the make command line:
+
+ * ``QTI_UART_NUM``: Number of UART controller to use for debug output and crash
+   reports. This must be the same UART as used by earlier boot firmware since
+   the UART controller does not get fully initialized at the moment. Defaults to
+   the usual debug UART used for the platform (see ``platform.mk``).
+ * ``QTI_RUNTIME_UART``: By default (``0``) the UART is only used for the boot
+   process and critical crashes. If set to ``1`` it is also used for runtime
+   messages. Note that this option can only be used if the UART is reserved in
+   the normal world and the necessary clocks remain enabled.
+
+The memory region used for the different firmware components is not fixed and
+can be changed on the make command line. The default values match the addresses
+used by the original firmware (see ``platform.mk``):
+
+ * ``PRELOADED_BL33_BASE``: The entry address for the normal world. Usually
+   refers to the first bootloader (e.g. U-Boot).
+ * ``BL31_BASE``: Base address for the BL31 firmware component. Must point to
+   a 64K-aligned memory region with at least 128 KiB space that is permanently
+   reserved in the normal world.
+ * ``BL32_BASE``: Base address for the BL32 firmware component.
+
+   * **AArch32:** BL32 is used in place of BL31, so the option is equivalent to
+     ``BL31_BASE``.
+   * **AArch64:** Secure-EL1 Payload. Defaults to using 128 KiB of space
+     directly after BL31. For testing only, the port is primarily intended as
+     a minimal PSCI implementation without a separate secure world.
+
+Installation
+------------
+The ELF image must be "signed" before flashing it, even if the board has secure
 boot disabled. In this case the signature does not provide any security,
 but it provides the firmware with required metadata.
 
@@ -75,6 +120,10 @@
 Then install the resulting ``build/msm8916/release/bl31/bl31-test-signed.mbn``
 to the ``tz`` partition on the device. BL31 should be running after a reboot.
 
+.. note::
+	On AArch32 the ELF image is called ``bl32.elf``.
+	The installation procedure is identical.
+
 .. warning::
 	Do not flash incorrectly signed firmware on devices that have secure
 	boot enabled! Make sure that you have a way to recover the board in case
@@ -82,8 +131,11 @@
 
 Boot Trace
 ----------
-BL31 prints some lines on the debug console UART2, which will usually look like
-this (with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown)::
+
+AArch64 (BL31)
+^^^^^^^^^^^^^^
+BL31 prints some lines on the debug console, which will usually look like this
+(with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown)::
 
 	...
 	S - DDR Frequency, 400 MHz
@@ -109,8 +161,34 @@
 	Qualcomm-DragonBoard 410C
 	...
 
+AArch32 (BL32/SP_MIN)
+^^^^^^^^^^^^^^^^^^^^^
+BL32/SP_MIN prints some lines on the debug console, which will usually look like
+this (with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown)::
+
+	...
+	S - DDR Frequency, 400 MHz
+	NOTICE:  SP_MIN: v2.8(debug):v2.8
+	NOTICE:  SP_MIN: Built : 23:03:31, Mar 31 2023
+	INFO:    SP_MIN: Platform setup start
+	INFO:    ARM GICv2 driver initialized
+	INFO:    SP_MIN: Platform setup done
+	INFO:    SP_MIN: Initializing runtime services
+	INFO:    BL32: cortex_a53: CPU workaround for 819472 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for 824069 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for 826319 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for 827319 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for disable_non_temporal_hint was applied
+	INFO:    SP_MIN: Preparing exit to normal world
+	INFO:    Entry point address = 0x86400000
+	INFO:    SPSR = 0x1da
+	Android Bootloader - UART_DM Initialized!!!
+	[0] welcome to lk
+	...
+
 .. _Qualcomm Snapdragon 410: https://www.qualcomm.com/products/snapdragon-processors-410
 .. _DragonBoard 410c: https://www.96boards.org/product/dragonboard410c/
 .. _Snapdragon 410E Technical Reference Manual: https://developer.qualcomm.com/download/sd410/snapdragon-410e-technical-reference-manual.pdf
 .. _U-Boot for DragonBoard 410c: https://u-boot.readthedocs.io/en/latest/board/qualcomm/dragonboard410c.html
 .. _qtestsign: https://github.com/msm8916-mainline/qtestsign
+.. _tfalkstub: https://github.com/msm8916-mainline/tfalkstub
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 81f4fbe..4fe0d2f 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -89,6 +89,16 @@
 make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 DEBUG=1 \
 	ZYNQMP_ATF_MEM_BASE=0x40000 ZYNQMP_ATF_MEM_SIZE=<size>
 
+Configurable Stack Size
+-----------------------
+
+The stack size in TF-A for ZynqMP platform is configurable.
+The custom package can define the desired stack size as per the requirement in
+the make file as follows,
+
+PLATFORM_STACK_SIZE := <value>
+$(eval $(call add_define,PLATFORM_STACK_SIZE))
+
 FSBL->TF-A Parameter Passing
 ----------------------------
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/porting-guide.rst
similarity index 94%
rename from docs/getting_started/porting-guide.rst
rename to docs/porting-guide.rst
index 6735cb1..f074021 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -26,6 +26,13 @@
       defined. We intend to convert existing weak functions over time. Until
       then, you will find references to *weak* functions in this document.
 
+Please review the :ref:`Threat Model` documents as part of the porting
+effort. Some platform interfaces play a key role in mitigating against some of
+the threats. Failing to fulfill these expectations could undermine the security
+guarantees offered by TF-A. These platform responsibilities are highlighted in
+the threat assessment section, under the "`Mitigations implemented?`" box for
+each threat.
+
 Some modifications are common to all Boot Loader (BL) stages. Section 2
 discusses these in detail. The subsequent sections discuss the remaining
 modifications for each BL stage in detail.
@@ -38,7 +45,7 @@
 source files in ``plat/arm/common/``. This is done so that there are no
 dependencies between platforms maintained by different people/companies. If you
 want to use any of the functionality present in ``plat/arm`` files, please
-create a pull request that moves the code to ``plat/common`` so that it can be
+propose a patch that moves the code to ``plat/common`` so that it can be
 discussed.
 
 Common modifications
@@ -54,7 +61,7 @@
 A platform port must enable the Memory Management Unit (MMU) as well as the
 instruction and data caches for each BL stage. Setting up the translation
 tables is the responsibility of the platform port because memory maps differ
-across platforms. A memory translation library (see ``lib/xlat_tables/``) is
+across platforms. A memory translation library (see ``lib/xlat_tables_v2/``) is
 provided to help in this setup.
 
 Note that although this library supports non-identity mappings, this is intended
@@ -538,6 +545,15 @@
 
    Defines the maximum address that the TSP's progbits sections can occupy.
 
+If the platform supports OS-initiated mode, i.e. the build option
+``PSCI_OS_INIT_MODE`` is enabled, and if the platform's maximum power domain
+level for PSCI_CPU_SUSPEND differs from ``PLAT_MAX_PWR_LVL``, the following
+constant must be defined.
+
+-  **#define : PLAT_MAX_CPU_SUSPEND_PWR_LVL**
+
+   Defines the maximum power domain level that PSCI_CPU_SUSPEND should apply to.
+
 If the platform port uses the PL061 GPIO driver, the following constant may
 optionally be defined:
 
@@ -565,6 +581,68 @@
    PLAT_PARTITION_BLOCK_SIZE := 4096
    $(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE))
 
+If the platform port uses the Arm® Ethos™-N NPU driver, the following
+configuration must be performed:
+
+- The NPU SiP service handler must be hooked up. This consists of both the
+  initial setup (``ethosn_smc_setup``) and the handler itself
+  (``ethosn_smc_handler``)
+
+If the platform port uses the Arm® Ethos™-N NPU driver with TZMP1 support
+enabled, the following constants and configuration must also be defined:
+
+- **ARM_ETHOSN_NPU_PROT_FW_NSAID**
+
+  Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to
+  access the protected memory that contains the NPU's firmware.
+
+- **ARM_ETHOSN_NPU_PROT_DATA_RW_NSAID**
+
+  Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
+  read/write access to the protected memory that contains inference data.
+
+- **ARM_ETHOSN_NPU_PROT_DATA_RO_NSAID**
+
+  Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
+  read-only access to the protected memory that contains inference data.
+
+- **ARM_ETHOSN_NPU_NS_RW_DATA_NSAID**
+
+  Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
+  read/write access to the non-protected memory.
+
+- **ARM_ETHOSN_NPU_NS_RO_DATA_NSAID**
+
+  Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
+  read-only access to the non-protected memory.
+
+- **ARM_ETHOSN_NPU_FW_IMAGE_BASE** and **ARM_ETHOSN_NPU_FW_IMAGE_LIMIT**
+
+  Defines the physical address range that the NPU's firmware will be loaded
+  into and executed from.
+
+- Configure the platforms TrustZone Controller (TZC) with appropriate regions
+  of protected memory. At minimum this must include a region for the NPU's
+  firmware code and a region for protected inference data, and these must be
+  accessible using the NSAIDs defined above.
+
+- Include the NPU firmware and certificates in the FIP.
+
+- Provide FCONF entries to configure the image source for the NPU firmware
+  and certificates.
+
+- Add MMU mappings such that:
+
+ - BL2 can write the NPU firmware into the region defined by
+   ``ARM_ETHOSN_NPU_FW_IMAGE_BASE`` and ``ARM_ETHOSN_NPU_FW_IMAGE_LIMIT``
+ - BL31 (SiP service) can read the NPU firmware from the same region
+
+- Add the firmware image ID ``ARM_ETHOSN_NPU_FW_IMAGE_ID`` to the list of images
+  loaded by BL2.
+
+Please see the reference implementation code for the Juno platform as an example.
+
+
 The following constant is optional. It should be defined to override the default
 behaviour of the ``assert()`` function (for example, to save memory).
 
@@ -816,34 +894,6 @@
 either could not be updated or the authentication image descriptor indicates
 that it is not allowed to be updated.
 
-Function: plat_convert_pk()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void *, unsigned int, void **, unsigned int *
-    Return   : int
-
-This function is optional when Trusted Board Boot is enabled, and only
-used if the platform saves a hash of the ROTPK.
-First argument is the Distinguished Encoding Rules (DER) ROTPK.
-Second argument is its size.
-Third argument is used to return a pointer to a buffer, which hash should
-be the one saved in OTP.
-Fourth argument is a pointer to return its size.
-
-Most platforms save the hash of the ROTPK, but some may save slightly different
-information - e.g the hash of the ROTPK plus some related information.
-Defining this function allows to transform the ROTPK used to verify
-the signature to the buffer (a platform specific public key) which
-hash is saved in OTP.
-
-The default implementation copies the input key and length to the output without
-modification.
-
-The function returns 0 on success. Any other value means the expected
-public key buffer cannot be extracted.
-
 Dynamic Root of Trust for Measurement support (in BL31)
 -------------------------------------------------------
 
@@ -1459,43 +1509,6 @@
 the SMCCC function specified in the argument; otherwise returns
 SMC_ARCH_CALL_NOT_SUPPORTED.
 
-Function : plat_mboot_measure_image()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : unsigned int, image_info_t *
-    Return   : int
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function measures the given image and records its measurement using
-   the measured boot backend driver.
--  On the Arm FVP port, this function measures the given image using its
-   passed id and information and then records that measurement in the
-   Event Log buffer.
--  This function must return 0 on success, a signed integer error code
-   otherwise.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : plat_mboot_measure_critical_data()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : unsigned int, const void *, size_t
-    Return   : int
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function measures the given critical data structure and records its
-   measurement using the measured boot backend driver.
--  This function must return 0 on success, a signed integer error code
-   otherwise.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
 Function : plat_can_cmo()
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1763,42 +1776,6 @@
 The default implementation of this function asserts therefore platforms must
 override it when using the FWU feature.
 
-Function : bl1_plat_mboot_init() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to initialize the backend driver(s) of measured boot.
--  On the Arm FVP port, this function is used to initialize the Event Log
-   backend driver, and also to write header information in the Event Log buffer.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : bl1_plat_mboot_finish() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to finalize the measured boot backend driver(s),
-   and also, set the information for the next bootloader component to
-   extend the measurement if needed.
--  On the Arm FVP port, this function is used to pass the base address of
-   the Event Log buffer and its size to BL2 via tb_fw_config to extend the
-   Event Log buffer with the measurement of various images loaded by BL2.
-   It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
 Boot Loader Stage 2 (BL2)
 -------------------------
 
@@ -1930,42 +1907,6 @@
 must return 0, otherwise it must return 1. The default implementation
 of this always returns 0.
 
-Function : bl2_plat_mboot_init() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to initialize the backend driver(s) of measured boot.
--  On the Arm FVP port, this function is used to initialize the Event Log
-   backend driver with the Event Log buffer information (base address and
-   size) received from BL1. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : bl2_plat_mboot_finish() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to finalize the measured boot backend driver(s),
-   and also, set the information for the next bootloader component to extend
-   the measurement if needed.
--  On the Arm FVP port, this function is used to pass the Event Log buffer
-   information (base address and size) to non-secure(BL33) and trusted OS(BL32)
-   via nt_fw and tos_fw config respectively. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
 Boot Loader Stage 2 (BL2) at EL3
 --------------------------------
 
@@ -2735,6 +2676,22 @@
 by the ``MPIDR`` (first argument). The generic code expects the platform to
 return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure.
 
+plat_psci_ops.pwr_domain_off_early() [optional]
+...............................................
+
+This optional function performs the platform specific actions to check if
+powering off the calling CPU and its higher parent power domain levels as
+indicated by the ``target_state`` (first argument) is possible or allowed.
+
+The ``target_state`` encodes the platform coordinated target local power states
+for the CPU power domain and its parent power domain levels.
+
+For this handler, the local power state for the CPU power domain will be a
+power down state where as it could be either power down, retention or run state
+for the higher power domain levels depending on the result of state
+coordination. The generic code expects PSCI_E_DENIED return code if the
+platform thinks that CPU_OFF should not proceed on the calling CPU.
+
 plat_psci_ops.pwr_domain_off()
 ..............................
 
@@ -2752,6 +2709,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]
 ...........................................................
 
@@ -3348,11 +3316,11 @@
 (``uint64_t flags``) indicates the preempted security state. These parameters
 are received from the top-level exception handler.
 
-If ``RAS_EXTENSION`` is set to ``1``, the default implementation of this
+If ``RAS_FFH_SUPPORT`` is set to ``1``, the default implementation of this
 function iterates through RAS handlers registered by the platform. If any of the
 RAS handlers resolve the External Abort, no further action is taken.
 
-If ``RAS_EXTENSION`` is set to ``0``, or if none of the platform RAS handlers
+If ``RAS_FFH_SUPPORT`` is set to ``0``, or if none of the platform RAS handlers
 could resolve the External Abort, the default implementation prints an error
 message, and panics.
 
@@ -3448,6 +3416,38 @@
 
 This function needs to be implemented by a platform if it enables FEAT_RNG_TRAP.
 
+Function : plat_handle_impdef_trap
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uint64_t
+    Argument : cpu_context_t *
+    Return   : int
+
+This function is invoked by BL31's exception handler when there is a synchronous
+system register trap caused by access to the implementation defined registers.
+It allows platforms enabling ``IMPDEF_SYSREG_TRAP`` to emulate those system
+registers choosing to program bits of their choice.
+
+The first parameter (``uint64_t esr_el3``) contains the content of the ESR_EL3
+syndrome register, which encodes the instruction that was trapped.
+
+The second parameter (``cpu_context_t *ctx``) represents the CPU state in the
+lower exception level, at the time when the execution of the ``mrs`` instruction
+was trapped.
+
+The return value indicates how to proceed:
+
+-  When returning ``TRAP_RET_UNHANDLED`` (-1), the machine will panic.
+-  When returning ``TRAP_RET_REPEAT`` (0), the exception handler will return
+   to the same instruction, so its execution will be repeated.
+-  When returning ``TRAP_RET_CONTINUE`` (1), the exception handler will return
+   to the next instruction.
+
+This function needs to be implemented by a platform if it enables
+IMPDEF_SYSREG_TRAP.
+
 Build flags
 -----------
 
@@ -3503,7 +3503,7 @@
 storage access is only required by BL1 and BL2 phases and performed inside the
 ``load_image()`` function in ``bl_common.c``.
 
-.. uml:: ../resources/diagrams/plantuml/io_framework_usage_overview.puml
+.. uml:: resources/diagrams/plantuml/io_framework_usage_overview.puml
 
 It is mandatory to implement at least one storage driver. For the Arm
 development platforms the Firmware Image Package (FIP) driver is provided as
@@ -3513,7 +3513,7 @@
 in ``drivers/io/io_storage.c`` and the driver files are located in
 ``drivers/io/``.
 
-.. uml:: ../resources/diagrams/plantuml/io_arm_class_diagram.puml
+.. uml:: resources/diagrams/plantuml/io_arm_class_diagram.puml
 
 Each IO driver must provide ``io_dev_*`` structures, as described in
 ``drivers/io/io_driver.h``. These are returned via a mandatory registration
@@ -3524,12 +3524,12 @@
 abstraction layer. These drivers then need to be initialized by bootloader
 phases as required in their respective ``blx_platform_setup()`` functions.
 
-.. uml:: ../resources/diagrams/plantuml/io_dev_registration.puml
+.. uml:: resources/diagrams/plantuml/io_dev_registration.puml
 
 The storage abstraction layer provides mechanisms (``io_dev_init()``) to
 initialize storage devices before IO operations are called.
 
-.. uml:: ../resources/diagrams/plantuml/io_dev_init_and_check.puml
+.. uml:: resources/diagrams/plantuml/io_dev_init_and_check.puml
 
 The basic operations supported by the layer
 include ``open()``, ``close()``, ``read()``, ``write()``, ``size()`` and ``seek()``.
@@ -3555,11 +3555,17 @@
 dynamically allocating memory. This may also have the affect of limiting the
 amount of open resources per driver.
 
+Measured Boot Platform Interface
+--------------------------------
+
+Enabling the MEASURED_BOOT flag adds extra platform requirements. Please refer
+to :ref:`Measured Boot Design` for more details.
+
 --------------
 
 *Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _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/code-review-guidelines.rst b/docs/process/code-review-guidelines.rst
index 67a211f..bd42811 100644
--- a/docs/process/code-review-guidelines.rst
+++ b/docs/process/code-review-guidelines.rst
@@ -1,11 +1,6 @@
 Code Review Guidelines
 ======================
 
-This document provides TF-A specific details about the project's code review
-process. It should be read in conjunction with the `Project Maintenance
-Process`_, which it supplements.
-
-
 Why do we do code reviews?
 --------------------------
 
@@ -23,8 +18,34 @@
 unfairly criticizing or belittling the work of any contributor.
 
 
-Good practices
---------------
+Overview of the code review process
+-----------------------------------
+
+All contributions to Trusted Firmware-A project are reviewed by the community to
+ensure they meet the project's expectations before they get merged, according to
+the `Project Maintenance Process`_ defined for all `Trusted Firmware` projects.
+
+Technical ownership of most parts of the codebase falls on the :ref:`code
+owners`. All patches are ultimately merged by the :ref:`maintainers`.
+
+Approval of a patch is tracked using Gerrit `labels`. For a patch to be merged,
+it must get all of the following votes:
+
+- At least one ``Code-Owner-Review+1`` up-vote, and no ``Code-Owner-Review-1``
+  down-vote.
+
+- At least one ``Maintainer-Review+1`` up-vote, and no ``Maintainer-Review-1``
+  down-vote.
+
+- ``Verified+1`` vote applied by the automated Continuous Integration (CI)
+  system.
+
+Note that, in some instances, the maintainers might give a waiver for some of
+the CI failures and manually override the ``Verified+1`` score.
+
+
+Good practices for all reviewers
+--------------------------------
 
 To ensure the code review gives the greatest possible benefit, participants in
 the project should:
@@ -73,6 +94,14 @@
    directory to have the freedom to change it in any way. This way, your changes
    benefit everyone and will be maintained over time.
 
+-  It is the patch-author's responsibility to respond to review comments within
+   21 days. In the event that the patch-author does not respond within this
+   timeframe, the maintainer is entitled to abandon the patch(es).
+   Patch author(s) may be busy with other priorities, causing a delay in
+   responding to active review comments after posting patch(es). In such a
+   situation, if the author's patch(es) is/are abandoned, they can restore
+   their work for review by resolving comments, merge-conflicts, and revising
+   their original submissions.
 
 Guidelines for all reviewers
 ----------------------------
@@ -211,6 +240,6 @@
 
 --------------
 
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
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/process/index.rst b/docs/process/index.rst
index 7914a4e..9b669c0 100644
--- a/docs/process/index.rst
+++ b/docs/process/index.rst
@@ -13,4 +13,5 @@
    contributing
    code-review-guidelines
    faq
+   maintenance
    security-hardening
diff --git a/docs/process/maintenance.rst b/docs/process/maintenance.rst
new file mode 100644
index 0000000..45aada2
--- /dev/null
+++ b/docs/process/maintenance.rst
@@ -0,0 +1,55 @@
+Project Maintenance Processes
+=============================
+
+Trusted Firmware-A (TF-A) project follows the generic `trustedfirmware.org
+Project Maintenance Process`_. The present document complements it by defining
+TF-A project-specific decisions.
+
+How to become a maintainer?
+---------------------------
+
+Qualifying Criteria
+~~~~~~~~~~~~~~~~~~~
+
+To be elligible to become a maintainer for TF-A project, all criteria outlined
+`here`_ must be fullfilled. These are:
+
+- Being an active member of the project for at least a couple of years.
+
+- Having contributed a substantial number of non-trivial and high-quality
+  patches.
+
+- Having reviewed a substantial number of non-trivial patches, preferably in the
+  generic layer, with high-quality constructive feedback.
+
+- Behaving in a professional and polite way, with the best interests of the
+  project at heart.
+
+- Showing a strong will to improve the project and to do the right thing, rather
+  than going for the quick and easy path.
+
+- Participating in design discussions on the development mailing list and during
+  TF-A tech forums calls.
+
+- Having appropriate bandwidth (minimum 2 hours per week) to deal with the workload.
+
+Election Process
+~~~~~~~~~~~~~~~~
+
+To put an individual's name up for election,
+
+#. Send an email to all existing TF-A maintainers, asking whether they have any
+   objections to this individual becoming a TF-A maintainer.
+
+#. Give existing maintainers one calendar week to participate in the discussion.
+
+#. If there are objections, the existing maintainers should try to resolve them
+   amongst themselves. If they cannot, this should be escalated to the
+   trustedfirmware.org Technical Steering Commitee (TSC).
+
+#. If there are no (more) objections, announce the news on the TF-A mailing list
+   and update the list of maintainers on the :ref:`Project
+   Maintenance<maintainers>` page.
+
+.. _trustedfirmware.org Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
+.. _here: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/#how-to-become-a-maintainer
diff --git a/docs/process/platform-ports-policy.rst b/docs/process/platform-ports-policy.rst
index 7983749..02eb6bd 100644
--- a/docs/process/platform-ports-policy.rst
+++ b/docs/process/platform-ports-policy.rst
@@ -10,12 +10,18 @@
 Platform compatibility is mainly affected by changes to Platform APIs (as
 documented in the :ref:`Porting Guide`), driver APIs (like the GICv3 drivers) or
 library interfaces (like xlat_table library). The project will try to maintain
-compatibility for upstream platforms. Due to evolving requirements and
-enhancements, there might be changes affecting platform compatibility which
-means the previous interface needs to be deprecated and a new interface
-introduced to replace it. In case the migration to the new interface is trivial,
-the contributor of the change is expected to make good effort to migrate the
-upstream platforms to the new interface.
+compatibility for upstream platforms.
+
+Due to evolving requirements and enhancements, there might be changes affecting
+platform compatibility, which means the previous interface needs to be deprecated
+and a new interface introduced to replace it. In case the migration to the new
+interface is trivial, the contributor of the change is expected to make good
+effort to migrate the upstream platforms to the new interface.
+
+The project will generally not take into account downstream platforms. If those
+are affected by a deprecation / removal decision, we encourage their maintainers
+to upstream their platform code or copy the latest version of the code being
+deprecated into their downstream tree.
 
 The deprecated interfaces are listed inside :ref:`Release Processes` as well as
 the release after which each one will be removed. When an interface is
@@ -26,26 +32,25 @@
 deprecated interfaces. Platforms are expected to migrate before the removal of
 the deprecated interface.
 
-Platform deprecation policy
----------------------------
+Deprecation policy
+------------------
 
-If a platform is no longer maintained, it is best to deprecate it to keep the
-projects' source tree clean and healthy. Deprecation can be a 1-stage or 2-stage
-process (up to the platform maintainers).
+If a platform, driver or library interface is no longer maintained, it is best
+to deprecate it to keep the projects' source tree clean and healthy. Deprecation
+can be a 1-stage or 2-stage process (up to the maintainers).
 
- - *2-stage*: The platform's source code can be kept in the repository for a
-   cooling off period before deleting it (typically 2 release cycles). In this
-   case, we keep track ot the *Deprecated* version separately from the *Deleted*
-   version.
+ - *2-stage*: The source code can be kept in the repository for a cooling off
+   period before deleting it (typically 2 release cycles). In this case, we keep
+   track of the *Deprecated* version separately from the *Deleted* version.
 
- - *1-stage*: The platform's source code can be deleted straight away. In this
-   case, both versions are the same.
+ - *1-stage*: The source code can be deleted straight away. In this case, both
+   versions are the same.
 
 The :ref:`Platform Ports` page provides a list of all deprecated/deleted
 platform ports (or soon to be) to this day.
 
 --------------
 
-*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
diff --git a/docs/requirements.in b/docs/requirements.in
deleted file mode 100644
index ae20b7d..0000000
--- a/docs/requirements.in
+++ /dev/null
@@ -1,5 +0,0 @@
-myst-parser==0.18.1
-pip-tools==6.4.0
-sphinx==5.3.0
-sphinx-rtd-theme==1.1.1
-sphinxcontrib-plantuml==0.24.1
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index 1ed78d0..0000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# This file is autogenerated by pip-compile with Python 3.8
-# by the following command:
-#
-#    pip-compile docs/requirements.in
-#
-alabaster==0.7.12
-    # via sphinx
-babel==2.11.0
-    # via sphinx
-certifi==2022.12.7
-    # via requests
-charset-normalizer==2.1.1
-    # via requests
-click==8.1.3
-    # via pip-tools
-docutils==0.17.1
-    # via
-    #   myst-parser
-    #   sphinx
-    #   sphinx-rtd-theme
-idna==3.4
-    # via requests
-imagesize==1.4.1
-    # via sphinx
-importlib-metadata==6.0.0
-    # via sphinx
-jinja2==3.1.2
-    # via
-    #   myst-parser
-    #   sphinx
-markdown-it-py==2.1.0
-    # via
-    #   mdit-py-plugins
-    #   myst-parser
-markupsafe==2.1.1
-    # via jinja2
-mdit-py-plugins==0.3.3
-    # via myst-parser
-mdurl==0.1.2
-    # via markdown-it-py
-myst-parser==0.18.1
-    # via -r docs/requirements.in
-packaging==23.0
-    # via sphinx
-pep517==0.13.0
-    # via pip-tools
-pip-tools==6.4.0
-    # via -r docs/requirements.in
-pygments==2.14.0
-    # via sphinx
-pytz==2022.7
-    # via babel
-pyyaml==6.0
-    # via myst-parser
-requests==2.28.1
-    # via sphinx
-snowballstemmer==2.2.0
-    # via sphinx
-sphinx==5.3.0
-    # via
-    #   -r docs/requirements.in
-    #   myst-parser
-    #   sphinx-rtd-theme
-    #   sphinxcontrib-plantuml
-sphinx-rtd-theme==1.1.1
-    # via -r docs/requirements.in
-sphinxcontrib-applehelp==1.0.3
-    # via sphinx
-sphinxcontrib-devhelp==1.0.2
-    # via sphinx
-sphinxcontrib-htmlhelp==2.0.0
-    # via sphinx
-sphinxcontrib-jsmath==1.0.1
-    # via sphinx
-sphinxcontrib-plantuml==0.24.1
-    # via -r docs/requirements.in
-sphinxcontrib-qthelp==1.0.3
-    # via sphinx
-sphinxcontrib-serializinghtml==1.1.5
-    # via sphinx
-tomli==2.0.1
-    # via pep517
-typing-extensions==4.4.0
-    # via myst-parser
-urllib3==1.26.13
-    # via requests
-wheel==0.38.4
-    # via pip-tools
-zipp==3.11.0
-    # via importlib-metadata
-
-# The following packages are considered to be unsafe in a requirements file:
-# pip
-# setuptools
diff --git a/docs/resources/diagrams/Makefile b/docs/resources/diagrams/Makefile
index c951754..faf9634 100644
--- a/docs/resources/diagrams/Makefile
+++ b/docs/resources/diagrams/Makefile
@@ -79,7 +79,13 @@
 FWU-update_struct_layers		= "background"
 FWU-update_struct_opts			=
 
-all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG) $(PSA_FWU_PNG)
+MB_DESIGN_DIA				= measured_boot_design.dia
+MB_DESIGN_PNG				= measured_boot_design.png
+
+measured_boot_design_layers		= "background"
+measured_boot_design_opts		=
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG) $(PSA_FWU_PNG) $(MB_DESIGN_PNG)
 
 $(RESET_PNGS):$(RESET_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
@@ -99,3 +105,6 @@
 
 $(PSA_FWU_PNG):$(PSA_FWU_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(MB_DESIGN_PNG):$(MB_DESIGN_DIA)
+	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
diff --git a/docs/resources/diagrams/measured_boot_design.dia b/docs/resources/diagrams/measured_boot_design.dia
new file mode 100644
index 0000000..fdae464
--- /dev/null
+++ b/docs/resources/diagrams/measured_boot_design.dia
Binary files differ
diff --git a/docs/resources/diagrams/measured_boot_design.png b/docs/resources/diagrams/measured_boot_design.png
new file mode 100644
index 0000000..42469be
--- /dev/null
+++ b/docs/resources/diagrams/measured_boot_design.png
Binary files differ
diff --git a/docs/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-flattened-vs-hierarchical-idle-states.png b/docs/resources/diagrams/psci-flattened-vs-hierarchical-idle-states.png
new file mode 100644
index 0000000..7c41f75
--- /dev/null
+++ b/docs/resources/diagrams/psci-flattened-vs-hierarchical-idle-states.png
Binary files differ
diff --git a/docs/resources/diagrams/psci-osi-mode.png b/docs/resources/diagrams/psci-osi-mode.png
new file mode 100644
index 0000000..09175e5
--- /dev/null
+++ b/docs/resources/diagrams/psci-osi-mode.png
Binary files differ
diff --git a/docs/resources/diagrams/psci-pc-mode-vs-osi-mode.png b/docs/resources/diagrams/psci-pc-mode-vs-osi-mode.png
new file mode 100644
index 0000000..7270a3d
--- /dev/null
+++ b/docs/resources/diagrams/psci-pc-mode-vs-osi-mode.png
Binary files differ
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index d73e74b..762801d 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -77,7 +77,7 @@
 +----------------------+
 | Cortex-A715          |
 +----------------------+
-| Cortex-Hunter        |
+| Cortex-A720          |
 +----------------------+
 | Neoverse-N1          |
 +----------------------+
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index 9fd55a9..b22fb18 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -4,9 +4,27 @@
 Threat modeling is an important part of Secure Development Lifecycle (SDL)
 that helps us identify potential threats and mitigations affecting a system.
 
-In the next sections, we first give a description of the target of evaluation
-using a data flow diagram. Then we provide a list of threats we have identified
-based on the data flow diagram and potential threat mitigations.
+As the TF-A codebase is highly configurable to allow tailoring it best for each
+platform's needs, providing a holistic threat model covering all of its features
+is not necessarily the best approach. Instead, we provide a collection of
+documents which, together, form the project's threat model. These are
+articulated around a core document, called the :ref:`Generic Threat Model`,
+which focuses on the most common configuration we expect to see. The other
+documents typically focus on specific features not covered in the core document.
+
+As the TF-A codebase evolves and new features get added, these threat model
+documents will be updated and extended in parallel to reflect at best the
+current status of the code from a security standpoint.
+
+   .. note::
+
+      Although our aim is eventually to provide threat model material for all
+      features within the project, we have not reached that point yet. We expect
+      to gradually fill these gaps over time.
+
+Each of these documents give a description of the target of evaluation using a
+data flow diagram, as well as a list of threats we have identified using the
+`STRIDE threat modeling technique`_ and corresponding mitigations.
 
 .. toctree::
    :maxdepth: 1
@@ -20,4 +38,6 @@
 
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.*
+
+.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 940cad5..71ec9b1 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -36,12 +36,34 @@
 - There is no Secure-EL2. We don't consider threats that may come with
   Secure-EL2 software.
 
-- Measured boot is disabled. We do not consider the threats nor the mitigations
-  that may come with it.
-
 - No experimental features are enabled. We do not consider threats that may come
   from them.
 
+.. note::
+
+ In the current Measured Boot design, BL1, BL2, and BL31, as well as the
+ secure world components, form the |SRTM|. Measurement data is currently
+ considered an asset to be protected against attack, and this is achieved
+ by storing them in the Secure Memory.
+ Beyond the measurements stored inside the TCG-compliant Event Log buffer,
+ there are no other assets to protect or threats to defend against that
+ could compromise |TF-A| execution environment's security.
+
+ There are general security assets and threats associated with remote/delegated
+ attestation. However, these are outside the |TF-A| security boundary and
+ should be dealt with by the appropriate agent in the platform/system.
+ Since current Measured Boot design does not use local attestation, there would
+ be no further assets to protect(like unsealed keys).
+
+ A limitation of the current Measured Boot design is that it is dependent upon
+ Secure Boot as implementation of Measured Boot does not extend measurements
+ into a discrete |TPM|, where they would be securely stored and protected
+ against tampering. This implies that if Secure-Boot is compromised, Measured
+ Boot may also be compromised.
+
+ Platforms must carefully evaluate the security of the default implementation
+ since the |SRTM| includes all secure world components.
+
 Data Flow Diagram
 =================
 
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
index 98dbf76..9458a9f 100644
--- a/docs/threat_model/threat_model_spm.rst
+++ b/docs/threat_model/threat_model_spm.rst
@@ -35,7 +35,7 @@
 - The TF-A implementation for the S-EL2 SPMC based on the Hafnium hypervisor
   running in the secure world of TrustZone (at S-EL2 exception level).
   The threat model is not related to the normal world Hypervisor or VMs.
-  The S-EL1 SPMC solution is not covered.
+  The S-EL1 and EL3 SPMC solutions are not covered.
 - The implementation complies with the FF-A v1.0 specification, and a few
   features of FF-A v1.1 specification.
 - Secure partitions are statically provisioned at boot time.
@@ -235,8 +235,8 @@
 +------------------------+------------------+-----------------+---------------+
 | ``Total Risk Rating``  | High (16)        | High (16)       |               |
 +------------------------+------------------+-----------------+---------------+
-| ``Mitigations``        | In context of FF-A v1.0 this is the case of sharing|
-|                        | the RX/TX buffer pair and usage in the             |
+| ``Mitigations``        | In context of FF-A v1.0 and v1.1 this is the case  |
+|                        | of sharing the RX/TX buffer pair and usage in the  |
 |                        | PARTITION_INFO_GET or mem sharing primitives.      |
 |                        | The SPMC must copy the contents of the TX buffer   |
 |                        | to an internal temporary buffer before processing  |
@@ -1151,11 +1151,189 @@
 |                        | interrupted.                                       |
 +------------------------+----------------------------------------------------+
 
++------------------------+----------------------------------------------------+
+| ID                     | 25                                                 |
++========================+====================================================+
+| ``Threat``             | **A rogue FF-A endpoint can use memory sharing     |
+|                        | calls to exhaust SPMC resources.**                 |
+|                        | For each on-going operation that involves an SP,   |
+|                        | the SPMC allocates resources to track its state.   |
+|                        | If the operation is never concluded, the resources |
+|                        | are never freed.                                   |
+|                        | In the worst scenario, multiple operations that    |
+|                        | never conclude may exhaust the SPMC resources to a |
+|                        | point in which renders memory sharing operations   |
+|                        | impossible. This could affect other, non-harmful   |
+|                        | FF-A endpoints, from legitimately using memory     |
+|                        | share functionality. The intent might even be      |
+|                        | to cause the SPMC to consume excessive CPU cycles, |
+|                        | attempting to make it deny its service to the NWd. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, SPMD                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state                                         |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | High (4)         | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (16)        | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC uses a statically allocated pool of  |
+|                        | memory to keep track of on-going memory sharing    |
+|                        | operations. After a possible attack, this could    |
+|                        | fail due to insufficient memory, and return an     |
+|                        | error to the caller. At this point, any other      |
+|                        | endpoint that requires use of memory sharing for   |
+|                        | its operation could get itself in an unusable      |
+|                        | state.                                             |
+|                        | Regarding CPU cycles starving threat, the SPMC     |
+|                        | doesn't provide any mitigation for this, as any    |
+|                        | FF-A endpoint, at the virtual FF-A instance is     |
+|                        | allowed to invoke memory share/lend/donate.        |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 26                                                 |
++========================+====================================================+
+| ``Threat``             | **A borrower may interfere with lender's           |
+|                        | operation, if it terminates due to a fatal error   |
+|                        | condition without releasing the memory             |
+|                        | shared/lent.**                                     |
+|                        | Such scenario may render the lender inoperable.    |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (12)        | Medium(6)       |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC does not provide mitigation for such |
+|                        | scenario. The FF-A endpoints must attempt to       |
+|                        | relinquish memory shared/lent themselves in        |
+|                        | case of failure. The memory used to track the      |
+|                        | operation in the SPMC will also remain usuable.    |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 27                                                 |
++========================+====================================================+
+| ``Threat``             | **A rogue FF-A endpoint may attempt to tamper with |
+|                        | the content of the memory shared/lent, whilst      |
+|                        | being accessed by other FF-A endpoints.**          |
+|                        | It might attempt to do so: using one of the clear  |
+|                        | flags, when either retrieving or relinquishing     |
+|                        | access to the memory via the respective FF-A       |
+|                        | calls; or directly accessing memory without        |
+|                        | respecting the synchronization protocol between    |
+|                        | all involved endpoints.                            |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, FF-A endpoint                                |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service, Tampering                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Low (2)          | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (6)       | Medium(6)       |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The first case defined in the threat, the TF-A     |
+|                        | SPMC mitigates it, by ensuring a memory is cleared |
+|                        | only when all borrowers have relinquished access   |
+|                        | to the memory, in a scenario involving multiple    |
+|                        | borrowers. Also, if the receiver is granted RO,    |
+|                        | permissions, the SPMC will reject any request      |
+|                        | to clear memory on behalf of the borrower, by      |
+|                        | returning an error to the respective FF-A call.    |
+|                        | The second case defined in the threat can't be     |
+|                        | mitigated by the SPMC. It is up to the NS/S FF-A   |
+|                        | endpoints to establish a robust protocol for using |
+|                        | the shared memory.                                 |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 28                                                 |
++========================+====================================================+
+| ``Threat``             | **A rogue FF-A endpoint may attempt to share       |
+|                        | memory that is not in its translation regime, or   |
+|                        | attempt to specify attributes more permissive than |
+|                        | those it possesses at a given time.**              |
+|                        | Both ways could be an attempt for escalating its   |
+|                        | privileges.                                        |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, FF-A endpoint                                |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service, Tampering                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (12)        | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC mitigates this threat by performing  |
+|                        | sanity checks to the provided memory region        |
+|                        | descriptor.                                        |
+|                        | For operations at the virtual FF-A instance, and   |
+|                        | once the full memory descriptor is provided,       |
+|                        | the SPMC validates that the memory is part of the  |
+|                        | caller's translation regime. The SPMC also checks  |
+|                        | that the memory attributes provided are within     |
+|                        | those the owner possesses, in terms of             |
+|                        | permissiveness. If more permissive attributes are  |
+|                        | specified, the SPMC returns an error               |
+|                        | FFA_INVALID_PARAMETERS. The permissiveness rules   |
+|                        | are enforced in any call to share/lend or donate   |
+|                        | the memory, and in retrieve requests.              |
++------------------------+----------------------------------------------------+
+
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
 .. _Secure Partition Manager: ../components/secure-partition-manager.html
 .. _Generic TF-A threat model: ./threat_model.html#threat-analysis
 .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
+
diff --git a/docs/tools/index.rst b/docs/tools/index.rst
new file mode 100644
index 0000000..2dee2c0
--- /dev/null
+++ b/docs/tools/index.rst
@@ -0,0 +1,12 @@
+Tools
+=====
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents
+
+   memory-layout-tool
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/tools/memory-layout-tool.rst b/docs/tools/memory-layout-tool.rst
new file mode 100644
index 0000000..8874bd7
--- /dev/null
+++ b/docs/tools/memory-layout-tool.rst
@@ -0,0 +1,236 @@
+TF-A Memory Layout Tool
+=======================
+
+TF-A's memory layout tool is a Python script for analyzing the virtual
+memory layout of TF-A builds.
+
+Prerequisites
+~~~~~~~~~~~~~
+
+#. Python (3.8 or later)
+#. `Poetry`_ Python package manager
+
+Getting Started
+~~~~~~~~~~~~~~~
+
+#. Install Poetry
+
+    .. code:: shell
+
+        curl -sSL https://install.python-poetry.org | python3 -
+
+#. Install the required packages
+
+    .. code:: shell
+
+        poetry install --with memory
+
+#. Verify that the tool runs in the installed virtual environment
+
+    .. code:: shell
+
+        poetry run memory --help
+
+Symbol Virtual Map
+~~~~~~~~~~~~~~~~~~
+
+The tool can be used to generate a visualisation of the symbol table. By
+default, it prints the symbols representing the start and end address of the
+main memory regions in an ELF file (i.e. text, bss, rodata) but can be modified
+to print any set of symbols.
+
+.. code:: shell
+
+    $ poetry run memory -s
+    build-path: build/fvp/release
+    Virtual Address Map:
+               +------------__BL1_RAM_END__------------+---------------------------------------+
+               +---------__COHERENT_RAM_END__----------+                                       |
+               +--------__COHERENT_RAM_START__---------+                                       |
+    0x0403b000 +----------__XLAT_TABLE_END__-----------+                                       |
+    0x04036000 +---------__XLAT_TABLE_START__----------+                                       |
+               +--------__BASE_XLAT_TABLE_END__--------+                                       |
+    0x04035600 +--------------__BSS_END__--------------+                                       |
+               +-------__BASE_XLAT_TABLE_START__-------+                                       |
+               +-----__PMF_PERCPU_TIMESTAMP_END__------+                                       |
+               +---------__PMF_TIMESTAMP_END__---------+                                       |
+    0x04035400 +--------__PMF_TIMESTAMP_START__--------+                                       |
+               +-------------__BSS_START__-------------+                                       |
+    0x04034a00 +------------__STACKS_END__-------------+                                       |
+    0x04034500 +-----------__STACKS_START__------------+                                       |
+    0x040344c5 +-----------__DATA_RAM_END__------------+                                       |
+               +-----------__BL1_RAM_START__-----------+                                       |
+    0x04034000 +----------__DATA_RAM_START__-----------+                                       |
+               |                                       +---------__COHERENT_RAM_END__----------+
+               |                                       +--------__COHERENT_RAM_START__---------+
+    0x0402e000 |                                       +----------__XLAT_TABLE_END__-----------+
+    0x04029000 |                                       +---------__XLAT_TABLE_START__----------+
+               |                                       +--------__BASE_XLAT_TABLE_END__--------+
+    0x04028800 |                                       +--------------__BSS_END__--------------+
+               |                                       +-------__BASE_XLAT_TABLE_START__-------+
+               |                                       +-----__PMF_PERCPU_TIMESTAMP_END__------+
+               |                                       +---------__PMF_TIMESTAMP_END__---------+
+    0x04028580 |                                       +--------__PMF_TIMESTAMP_START__--------+
+    0x04028000 |                                       +-------------__BSS_START__-------------+
+    0x04027e40 |                                       +------------__STACKS_END__-------------+
+    0x04027840 |                                       +-----------__STACKS_START__------------+
+    0x04027000 |                                       +------------__RODATA_END__-------------+
+               |                                       +------------__CPU_OPS_END__------------+
+               |                                       +-----------__CPU_OPS_START__-----------+
+               |                                       +--------__FCONF_POPULATOR_END__--------+
+               |                                       +--------------__GOT_END__--------------+
+               |                                       +-------------__GOT_START__-------------+
+               |                                       +---------__PMF_SVC_DESCS_END__---------+
+    0x04026c10 |                                       +--------__PMF_SVC_DESCS_START__--------+
+    0x04026bf8 |                                       +-------__FCONF_POPULATOR_START__-------+
+               |                                       +-----------__RODATA_START__------------+
+    0x04026000 |                                       +-------------__TEXT_END__--------------+
+    0x04021000 |                                       +------------__TEXT_START__-------------+
+    0x000062b5 +------------__BL1_ROM_END__------------+                                       |
+    0x00005df0 +----------__DATA_ROM_START__-----------+                                       |
+               +------------__CPU_OPS_END__------------+                                       |
+               +--------------__GOT_END__--------------+                                       |
+               +-------------__GOT_START__-------------+                                       |
+    0x00005de8 +------------__RODATA_END__-------------+                                       |
+               +-----------__CPU_OPS_START__-----------+                                       |
+               +--------__FCONF_POPULATOR_END__--------+                                       |
+               +---------__PMF_SVC_DESCS_END__---------+                                       |
+    0x00005c98 +--------__PMF_SVC_DESCS_START__--------+                                       |
+    0x00005c80 +-------__FCONF_POPULATOR_START__-------+                                       |
+               +-----------__RODATA_START__------------+                                       |
+    0x00005000 +-------------__TEXT_END__--------------+                                       |
+    0x00000000 +------------__TEXT_START__-------------+---------------------------------------+
+
+Addresses are displayed in hexadecimal by default but can be printed in decimal
+instead with the ``-d`` option.
+
+Because of the length of many of the symbols, the tool defaults to a text width
+of 120 chars. This can be increased if needed with the ``-w`` option.
+
+For more detailed help instructions, run:
+
+.. code:: shell
+
+    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.*
+
+.. _Poetry: https://python-poetry.org/docs/
diff --git a/drivers/arm/css/scmi/vendor/scmi_sq.c b/drivers/arm/css/scmi/vendor/scmi_sq.c
index f185424..1037633 100644
--- a/drivers/arm/css/scmi/vendor/scmi_sq.c
+++ b/drivers/arm/css/scmi/vendor/scmi_sq.c
@@ -15,7 +15,7 @@
 
 #include <sq_common.h>
 
-/* SCMI messge ID to get the available DRAM region */
+/* SCMI message ID to get the available DRAM region */
 #define SCMI_VENDOR_EXT_MEMINFO_GET_MSG		0x3
 
 #define SCMI_VENDOR_EXT_MEMINFO_GET_MSG_LEN	4
diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c
new file mode 100644
index 0000000..628f5d9
--- /dev/null
+++ b/drivers/arm/ethosn/ethosn_big_fw.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include "ethosn_big_fw.h"
+
+/* Magic (FourCC) number to identify the big firmware binary */
+#define ETHOSN_BIG_FW_MAGIC	('E' | ('N' << 8) | ('F' << 16) | ('W' << 24))
+
+/* Supported big firmware version */
+#define ETHOSN_BIG_FW_VERSION_MAJOR	11
+
+#define ETHOSN_ARCH_VER_MAJOR_MASK	U(0xF000)
+#define ETHOSN_ARCH_VER_MAJOR_SHIFT	U(0xC)
+#define ETHOSN_ARCH_VER_MINOR_MASK	U(0xF00)
+#define ETHOSN_ARCH_VER_MINOR_SHIFT	U(0x8)
+#define ETHOSN_ARCH_VER_REV_MASK	U(0xFF)
+
+/* Convert Arm(R) Ethos(TM)-N NPU architecture version to big firmware format */
+#define ETHOSN_BIG_FW_FORMAT_ARCH_VER(arch_ver)					 \
+	(arch_ver & ETHOSN_ARCH_VER_MAJOR_MASK) << ETHOSN_ARCH_VER_MAJOR_SHIFT | \
+	(arch_ver & ETHOSN_ARCH_VER_MINOR_MASK) << ETHOSN_ARCH_VER_MINOR_SHIFT | \
+	(arch_ver & ETHOSN_ARCH_VER_REV_MASK)
+
+
+bool ethosn_big_fw_verify_header(const struct ethosn_big_fw *big_fw,
+				 uint32_t npu_arch_ver)
+{
+	const uint32_t arch_ver = ETHOSN_BIG_FW_FORMAT_ARCH_VER(npu_arch_ver);
+
+	if (big_fw->fw_magic != ETHOSN_BIG_FW_MAGIC) {
+		ERROR("ETHOSN: Unable to find firmware. Invalid magic value: 0x%02x\n",
+		      big_fw->fw_magic);
+
+		return false;
+	}
+
+	if (big_fw->fw_ver_major != ETHOSN_BIG_FW_VERSION_MAJOR) {
+		ERROR("ETHOSN: Unsupported firmware version: %u.%u.%u. Expected Version %u.x.x.\n",
+		      big_fw->fw_ver_major, big_fw->fw_ver_minor,
+		      big_fw->fw_ver_patch, ETHOSN_BIG_FW_VERSION_MAJOR);
+
+		return false;
+	}
+
+	if (big_fw->arch_min > arch_ver || arch_ver > big_fw->arch_max) {
+		ERROR("ETHOSN: Firmware is not compatbile with architecture version: 0x%02x\n",
+		      npu_arch_ver);
+		return false;
+	}
+
+	return true;
+}
diff --git a/drivers/arm/ethosn/ethosn_big_fw.h b/drivers/arm/ethosn/ethosn_big_fw.h
new file mode 100644
index 0000000..a321322
--- /dev/null
+++ b/drivers/arm/ethosn/ethosn_big_fw.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/*
+ * Big FW binary structure.
+ * Must be kept in sync with the Arm(R) Ethos(TM)-N NPU firmware binary layout.
+ */
+struct ethosn_big_fw {
+	uint32_t fw_magic;
+	uint32_t fw_ver_major;
+	uint32_t fw_ver_minor;
+	uint32_t fw_ver_patch;
+	uint32_t arch_min;
+	uint32_t arch_max;
+	uint32_t offset;
+	uint32_t size;
+	uint32_t code_offset;
+	uint32_t code_size;
+	uint32_t ple_offset;
+	uint32_t ple_size;
+	uint32_t vector_table_offset;
+	uint32_t vector_table_size;
+	uint32_t unpriv_stack_offset;
+	uint32_t unpriv_stack_size;
+	uint32_t priv_stack_offset;
+	uint32_t priv_stack_size;
+} __packed;
+
+bool ethosn_big_fw_verify_header(const struct ethosn_big_fw *big_fw,
+				 uint32_t npu_arch_ver);
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 915a0d8..85a12c5 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,12 @@
 #include <lib/utils_def.h>
 #include <plat/arm/common/fconf_ethosn_getter.h>
 
+#include <platform_def.h>
+
+#if ARM_ETHOSN_NPU_TZMP1
+#include "ethosn_big_fw.h"
+#endif
+
 /*
  * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available
  */
@@ -28,27 +34,89 @@
 #define ETHOSN_CORE_SEC_REG(core_addr, reg_offset) \
 	(core_addr + reg_offset)
 
+#define ETHOSN_FW_VA_BASE              0x20000000UL
+#define ETHOSN_WORKING_DATA_VA_BASE    0x40000000UL
+#define ETHOSN_COMMAND_STREAM_VA_BASE  0x60000000UL
+
 /* Reset timeout in us */
 #define ETHOSN_RESET_TIMEOUT_US		U(10 * 1000 * 1000)
 #define ETHOSN_RESET_WAIT_US		U(1)
 
+#define ETHOSN_AUX_FEAT_LEVEL_IRQ	U(0x1)
+#define ETHOSN_AUX_FEAT_STASHING	U(0x2)
+
+#define SEC_AUXCTLR_REG			U(0x0024)
+#define SEC_AUXCTLR_VAL			U(0x80)
+#define SEC_AUXCTLR_LEVEL_IRQ_VAL	U(0x04)
+#define SEC_AUXCTLR_STASHING_VAL	U(0xA5000000)
+
 #define SEC_DEL_REG			U(0x0004)
-#define SEC_DEL_VAL			U(0x81C)
+#if ARM_ETHOSN_NPU_TZMP1
+#define SEC_DEL_VAL			U(0x808)
+#else
+#define SEC_DEL_VAL			U(0x80C)
+#endif
 #define SEC_DEL_EXCC_MASK		U(0x20)
 
 #define SEC_SECCTLR_REG			U(0x0010)
-#define SEC_SECCTLR_VAL			U(0x3)
+/* Set bit[10] = 1 to workaround erratum 2838783 */
+#define SEC_SECCTLR_VAL			U(0x403)
 
-#define SEC_DEL_ADDR_EXT_REG		U(0x201C)
-#define SEC_DEL_ADDR_EXT_VAL		U(0x15)
+#define SEC_DEL_ADDR_EXT_REG            U(0x201C)
+#define SEC_DEL_ADDR_EXT_VAL            U(0x1)
 
 #define SEC_SYSCTRL0_REG		U(0x0018)
+#define SEC_SYSCTRL0_CPU_WAIT		U(1)
+#define SEC_SYSCTRL0_SLEEPING		U(1U << 4)
+#define SEC_SYSCTRL0_INITVTOR_MASK	U(0x1FFFFF80)
 #define SEC_SYSCTRL0_SOFT_RESET		U(3U << 29)
 #define SEC_SYSCTRL0_HARD_RESET		U(1U << 31)
 
+#define SEC_SYSCTRL1_REG		U(0x001C)
+#define SEC_SYSCTRL1_VAL		U(0x180110)
+
+#define SEC_NSAID_REG_BASE		U(0x3004)
+#define SEC_NSAID_OFFSET		U(0x1000)
+
 #define SEC_MMUSID_REG_BASE		U(0x3008)
 #define SEC_MMUSID_OFFSET		U(0x1000)
 
+#define SEC_ADDR_EXT_REG_BASE		U(0x3018)
+#define SEC_ADDR_EXT_OFFSET		U(0x1000)
+#define SEC_ADDR_EXT_SHIFT		U(0x14)
+#define SEC_ADDR_EXT_MASK		U(0x1FFFFE00)
+
+#define SEC_ATTR_CTLR_REG_BASE		U(0x3010)
+#define SEC_ATTR_CTLR_OFFSET		U(0x1000)
+#define SEC_ATTR_CTLR_NUM		U(9)
+#define SEC_ATTR_CTLR_VAL		U(0x1)
+
+#define SEC_NPU_ID_REG			U(0xF000)
+#define SEC_NPU_ID_ARCH_VER_SHIFT	U(0X10)
+
+#define FIRMWARE_STREAM_INDEX		U(0x0)
+#define WORKING_STREAM_INDEX		U(0x1)
+#define PLE_STREAM_INDEX		U(0x4)
+#define INPUT_STREAM_INDEX		U(0x6)
+#define INTERMEDIATE_STREAM_INDEX	U(0x7)
+#define OUTPUT_STREAM_INDEX		U(0x8)
+
+#define TO_EXTEND_ADDR(addr) \
+	((addr >> SEC_ADDR_EXT_SHIFT) & SEC_ADDR_EXT_MASK)
+
+#if ARM_ETHOSN_NPU_TZMP1
+CASSERT(ARM_ETHOSN_NPU_FW_IMAGE_BASE > 0U, assert_ethosn_invalid_fw_image_base);
+static const struct ethosn_big_fw *big_fw;
+
+#define FW_INITVTOR_ADDR(big_fw) \
+	((ETHOSN_FW_VA_BASE + big_fw->vector_table_offset) & \
+	 SEC_SYSCTRL0_INITVTOR_MASK)
+
+#define SYSCTRL0_INITVTOR_ADDR(value) \
+	(value & SEC_SYSCTRL0_INITVTOR_MASK)
+
+#endif
+
 static bool ethosn_get_device_and_core(uintptr_t core_addr,
 				       const struct ethosn_device_t **dev_match,
 				       const struct ethosn_core_t **core_match)
@@ -74,6 +142,83 @@
 	return false;
 }
 
+#if ARM_ETHOSN_NPU_TZMP1
+static uint32_t ethosn_core_read_arch_version(uintptr_t core_addr)
+{
+	uint32_t npu_id = mmio_read_32(ETHOSN_CORE_SEC_REG(core_addr,
+							   SEC_NPU_ID_REG));
+
+	return (npu_id >> SEC_NPU_ID_ARCH_VER_SHIFT);
+}
+
+static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core,
+					  bool is_protected)
+{
+	size_t i;
+	uint32_t streams[9] = {[0 ... 8] = ARM_ETHOSN_NPU_NS_RO_DATA_NSAID};
+
+	streams[FIRMWARE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID;
+	streams[PLE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID;
+
+	streams[WORKING_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RW_DATA_NSAID;
+
+	if (is_protected) {
+		streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_RO_DATA_NSAID;
+		streams[INTERMEDIATE_STREAM_INDEX] =
+			ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID;
+		streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID;
+	} else {
+		streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RO_DATA_NSAID;
+		streams[INTERMEDIATE_STREAM_INDEX] =
+			ARM_ETHOSN_NPU_NS_RW_DATA_NSAID;
+		streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RW_DATA_NSAID;
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(streams); ++i) {
+		const uintptr_t reg_addr = SEC_NSAID_REG_BASE +
+			(SEC_NSAID_OFFSET * i);
+		mmio_write_32(ETHOSN_CORE_SEC_REG(core->addr, reg_addr),
+			      streams[i]);
+	}
+}
+
+static void ethosn_configure_vector_table(uintptr_t core_addr)
+{
+	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG),
+			FW_INITVTOR_ADDR(big_fw));
+}
+
+#endif
+
+static void ethosn_configure_events(uintptr_t core_addr)
+{
+	mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL1_REG), SEC_SYSCTRL1_VAL);
+}
+
+static bool ethosn_configure_aux_features(const struct ethosn_device_t *device,
+					  uintptr_t core_addr,
+					  uint32_t features)
+{
+	uint32_t val = SEC_AUXCTLR_VAL;
+
+	if (features & ETHOSN_AUX_FEAT_LEVEL_IRQ) {
+		val |= SEC_AUXCTLR_LEVEL_IRQ_VAL;
+	}
+
+	if (features & ETHOSN_AUX_FEAT_STASHING) {
+		/* Stashing can't be used with reserved memory */
+		if (device->has_reserved_memory) {
+			return false;
+		}
+
+		val |= SEC_AUXCTLR_STASHING_VAL;
+	}
+
+	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_AUXCTLR_REG), val);
+
+	return true;
+}
+
 static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device,
 					  const struct ethosn_core_t *core,
 					  uint32_t asset_alloc_idx)
@@ -103,6 +248,44 @@
 	}
 }
 
+static void ethosn_configure_stream_addr_extends(const struct ethosn_device_t *device,
+						 uintptr_t core_addr)
+{
+	uint32_t addr_extends[3] = { 0 };
+	size_t i;
+
+	if (device->has_reserved_memory) {
+		const uint32_t addr = TO_EXTEND_ADDR(device->reserved_memory_addr);
+
+		addr_extends[0] = addr;
+		addr_extends[1] = addr;
+		addr_extends[2] = addr;
+	} else {
+		addr_extends[0] = TO_EXTEND_ADDR(ETHOSN_FW_VA_BASE);
+		addr_extends[1] = TO_EXTEND_ADDR(ETHOSN_WORKING_DATA_VA_BASE);
+		addr_extends[2] = TO_EXTEND_ADDR(ETHOSN_COMMAND_STREAM_VA_BASE);
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(addr_extends); ++i) {
+		const uintptr_t reg_addr = SEC_ADDR_EXT_REG_BASE +
+			(SEC_ADDR_EXT_OFFSET * i);
+		mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, reg_addr),
+			      addr_extends[i]);
+	}
+}
+
+static void ethosn_configure_stream_attr_ctlr(uintptr_t core_addr)
+{
+	size_t i;
+
+	for (i = 0U; i < SEC_ATTR_CTLR_NUM; ++i) {
+		const uintptr_t reg_addr = SEC_ATTR_CTLR_REG_BASE +
+			(SEC_ATTR_CTLR_OFFSET * i);
+		mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, reg_addr),
+			      SEC_ATTR_CTLR_VAL);
+	}
+}
+
 static void ethosn_delegate_to_ns(uintptr_t core_addr)
 {
 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG),
@@ -125,13 +308,22 @@
 	return 1;
 }
 
+static int ethosn_core_is_sleeping(uintptr_t core_addr)
+{
+	const uintptr_t sysctrl0_reg =
+		ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG);
+	const uint32_t sleeping_mask = SEC_SYSCTRL0_SLEEPING;
+
+	return ((mmio_read_32(sysctrl0_reg) & sleeping_mask) == sleeping_mask);
+}
+
-static bool ethosn_reset(uintptr_t core_addr, int hard_reset)
+static bool ethosn_core_reset(uintptr_t core_addr, bool hard_reset)
 {
 	unsigned int timeout;
 	const uintptr_t sysctrl0_reg =
 		ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG);
-	const uint32_t reset_val = (hard_reset != 0) ? SEC_SYSCTRL0_HARD_RESET
-						    : SEC_SYSCTRL0_SOFT_RESET;
+	const uint32_t reset_val = hard_reset ? SEC_SYSCTRL0_HARD_RESET :
+						SEC_SYSCTRL0_SOFT_RESET;
 
 	mmio_write_32(sysctrl0_reg, reset_val);
 
@@ -149,18 +341,184 @@
 	return timeout < ETHOSN_RESET_TIMEOUT_US;
 }
 
+static int ethosn_core_boot_fw(uintptr_t core_addr)
+{
+#if ARM_ETHOSN_NPU_TZMP1
+	const uintptr_t sysctrl0_reg = ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG);
+	const uint32_t sysctrl0_val = mmio_read_32(sysctrl0_reg);
+	const bool waiting = (sysctrl0_val & SEC_SYSCTRL0_CPU_WAIT);
+
+	if (!waiting) {
+		WARN("ETHOSN: Firmware is already running.\n");
+		return ETHOSN_INVALID_STATE;
+	}
+
+	if (SYSCTRL0_INITVTOR_ADDR(sysctrl0_val) != FW_INITVTOR_ADDR(big_fw)) {
+		WARN("ETHOSN: Unknown vector table won't boot firmware.\n");
+		return ETHOSN_INVALID_CONFIGURATION;
+	}
+
+	mmio_clrbits_32(sysctrl0_reg, SEC_SYSCTRL0_CPU_WAIT);
+
+	return ETHOSN_SUCCESS;
+#else
+	return ETHOSN_NOT_SUPPORTED;
+#endif
+}
+
+static int ethosn_core_full_reset(const struct ethosn_device_t *device,
+				  const struct ethosn_core_t *core,
+				  bool hard_reset,
+				  u_register_t asset_alloc_idx,
+				  u_register_t is_protected,
+				  u_register_t aux_features)
+{
+	if (!device->has_reserved_memory &&
+	    asset_alloc_idx >= device->num_allocators) {
+		WARN("ETHOSN: Unknown asset allocator index given to SMC call.\n");
+		return ETHOSN_UNKNOWN_ALLOCATOR_IDX;
+	}
+
+	if (!ethosn_core_reset(core->addr, hard_reset)) {
+		return ETHOSN_FAILURE;
+	}
+
+	if (!ethosn_configure_aux_features(device, core->addr, aux_features)) {
+		return ETHOSN_INVALID_CONFIGURATION;
+	}
+
+	ethosn_configure_events(core->addr);
+
+	if (!device->has_reserved_memory) {
+		ethosn_configure_smmu_streams(device, core, asset_alloc_idx);
+
+#if ARM_ETHOSN_NPU_TZMP1
+		ethosn_configure_stream_nsaid(core, is_protected);
+#endif
+	}
+
+	ethosn_configure_stream_addr_extends(device, core->addr);
+	ethosn_configure_stream_attr_ctlr(core->addr);
+
+#if ARM_ETHOSN_NPU_TZMP1
+	ethosn_configure_vector_table(core->addr);
+#endif
+
+	ethosn_delegate_to_ns(core->addr);
+
+	return ETHOSN_SUCCESS;
+}
+
+static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *device,
+					       const struct ethosn_core_t *core,
+					       bool hard_reset,
+					       u_register_t asset_alloc_idx,
+					       u_register_t reset_type,
+					       u_register_t is_protected,
+					       u_register_t aux_features,
+					       void *handle)
+{
+	int ret;
+
+	switch (reset_type) {
+	case ETHOSN_RESET_TYPE_FULL:
+		ret = ethosn_core_full_reset(device, core, hard_reset,
+					     asset_alloc_idx, is_protected,
+					     aux_features);
+		break;
+	case ETHOSN_RESET_TYPE_HALT:
+		ret = ethosn_core_reset(core->addr, hard_reset) ? ETHOSN_SUCCESS : ETHOSN_FAILURE;
+		break;
+	default:
+		WARN("ETHOSN: Invalid reset type given to SMC call.\n");
+		ret = ETHOSN_INVALID_PARAMETER;
+		break;
+	}
+
+	SMC_RET1(handle, ret);
+}
+
+static uintptr_t ethosn_smc_core_handler(uint32_t fid,
+					 u_register_t core_addr,
+					 u_register_t asset_alloc_idx,
+					 u_register_t reset_type,
+					 u_register_t is_protected,
+					 u_register_t aux_features,
+					 void *handle)
+{
+	bool hard_reset = false;
+	const struct ethosn_device_t *device = NULL;
+	const struct ethosn_core_t *core = NULL;
+
+	if (!ethosn_get_device_and_core(core_addr, &device, &core))  {
+		SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS);
+	}
+
+	switch (fid) {
+	case ETHOSN_FNUM_IS_SEC:
+		SMC_RET1(handle, ethosn_is_sec(core->addr));
+	case ETHOSN_FNUM_IS_SLEEPING:
+		SMC_RET1(handle, ethosn_core_is_sleeping(core->addr));
+	case ETHOSN_FNUM_HARD_RESET:
+		hard_reset = true;
+		/* Fallthrough */
+	case ETHOSN_FNUM_SOFT_RESET:
+		return ethosn_smc_core_reset_handler(device, core,
+						     hard_reset,
+						     asset_alloc_idx,
+						     reset_type,
+						     is_protected,
+						     aux_features,
+						     handle);
+	case ETHOSN_FNUM_BOOT_FW:
+		SMC_RET1(handle, ethosn_core_boot_fw(core->addr));
+	default:
+		WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+static uintptr_t ethosn_smc_fw_prop_handler(u_register_t fw_property,
+					    void *handle)
+{
+#if ARM_ETHOSN_NPU_TZMP1
+	switch (fw_property) {
+	case ETHOSN_FW_PROP_VERSION:
+		SMC_RET4(handle, ETHOSN_SUCCESS,
+			 big_fw->fw_ver_major,
+			 big_fw->fw_ver_minor,
+			 big_fw->fw_ver_patch);
+	case ETHOSN_FW_PROP_MEM_INFO:
+		SMC_RET3(handle, ETHOSN_SUCCESS,
+			 ((void *)big_fw) + big_fw->offset,
+			 big_fw->size);
+	case ETHOSN_FW_PROP_OFFSETS:
+		SMC_RET3(handle, ETHOSN_SUCCESS,
+			 big_fw->ple_offset,
+			 big_fw->unpriv_stack_offset);
+	case ETHOSN_FW_PROP_VA_MAP:
+		SMC_RET4(handle, ETHOSN_SUCCESS,
+			 ETHOSN_FW_VA_BASE,
+			 ETHOSN_WORKING_DATA_VA_BASE,
+			 ETHOSN_COMMAND_STREAM_VA_BASE);
+	default:
+		WARN("ETHOSN: Unknown firmware property\n");
+		SMC_RET1(handle, ETHOSN_INVALID_PARAMETER);
+	}
+#else
+	SMC_RET1(handle, ETHOSN_NOT_SUPPORTED);
+#endif
+}
+
 uintptr_t ethosn_smc_handler(uint32_t smc_fid,
-			     u_register_t core_addr,
-			     u_register_t asset_alloc_idx,
+			     u_register_t x1,
+			     u_register_t x2,
 			     u_register_t x3,
 			     u_register_t x4,
 			     void *cookie,
 			     void *handle,
 			     u_register_t flags)
 {
-	int hard_reset = 0;
-	const struct ethosn_device_t *device = NULL;
-	const struct ethosn_core_t *core = NULL;
 	const uint32_t fid = smc_fid & FUNCID_NUM_MASK;
 
 	/* Only SiP fast calls are expected */
@@ -171,59 +529,69 @@
 
 	/* Truncate parameters to 32-bits for SMC32 */
 	if (GET_SMC_CC(smc_fid) == SMC_32) {
-		core_addr &= 0xFFFFFFFF;
-		asset_alloc_idx &= 0xFFFFFFFF;
+		x1 &= 0xFFFFFFFF;
+		x2 &= 0xFFFFFFFF;
 		x3 &= 0xFFFFFFFF;
 		x4 &= 0xFFFFFFFF;
 	}
 
-	if (!is_ethosn_fid(smc_fid) ||
-	    (fid < ETHOSN_FNUM_VERSION || fid > ETHOSN_FNUM_SOFT_RESET)) {
+	if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_BOOT_FW)) {
 		WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
 
-	/* Commands that do not require a valid core address */
 	switch (fid) {
 	case ETHOSN_FNUM_VERSION:
 		SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR);
+	case ETHOSN_FNUM_GET_FW_PROP:
+		return ethosn_smc_fw_prop_handler(x1, handle);
 	}
 
-	if (!ethosn_get_device_and_core(core_addr, &device, &core))  {
-		SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS);
-	}
+	return ethosn_smc_core_handler(fid, x1, x2, x3, x4,
+				       SMC_GET_GP(handle, CTX_GPREG_X5),
+				       handle);
+}
 
-	/* Commands that require a valid core address */
-	switch (fid) {
-	case ETHOSN_FNUM_IS_SEC:
-		SMC_RET1(handle, ethosn_is_sec(core->addr));
+int ethosn_smc_setup(void)
+{
+#if ARM_ETHOSN_NPU_TZMP1
+	struct ethosn_device_t *dev;
+	uint32_t arch_ver;
+#endif
+
+	if (ETHOSN_NUM_DEVICES == 0U) {
+		ERROR("ETHOSN: No NPU found\n");
+		return ETHOSN_FAILURE;
 	}
 
-	if (!device->has_reserved_memory &&
-	    asset_alloc_idx >= device->num_allocators) {
-		WARN("ETHOSN: Unknown asset allocator index given to SMC call.\n");
-		SMC_RET1(handle, ETHOSN_UNKNOWN_ALLOCATOR_IDX);
+#if ARM_ETHOSN_NPU_TZMP1
+
+	/* Only one NPU core is supported in the TZMP1 setup */
+	if ((ETHOSN_NUM_DEVICES != 1U) ||
+	    (ETHOSN_GET_DEVICE(0U)->num_cores != 1U)) {
+		ERROR("ETHOSN: TZMP1 doesn't support multiple NPU cores\n");
+		return ETHOSN_FAILURE;
 	}
 
-	/* Commands that require a valid device, core and asset allocator */
-	switch (fid) {
-	case ETHOSN_FNUM_HARD_RESET:
-		hard_reset = 1;
-		/* Fallthrough */
-	case ETHOSN_FNUM_SOFT_RESET:
-		if (!ethosn_reset(core->addr, hard_reset)) {
-			SMC_RET1(handle, ETHOSN_FAILURE);
-		}
+	dev = ETHOSN_GET_DEVICE(0U);
+	if (dev->has_reserved_memory) {
+		ERROR("ETHOSN: TZMP1 doesn't support using reserved memory\n");
+		return ETHOSN_FAILURE;
+	}
 
-		if (!device->has_reserved_memory) {
-			ethosn_configure_smmu_streams(device, core,
-						      asset_alloc_idx);
-		}
+	arch_ver = ethosn_core_read_arch_version(dev->cores[0U].addr);
+	big_fw = (struct ethosn_big_fw *)ARM_ETHOSN_NPU_FW_IMAGE_BASE;
 
-		ethosn_delegate_to_ns(core->addr);
-		SMC_RET1(handle, ETHOSN_SUCCESS);
-	default:
-		WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid);
-		SMC_RET1(handle, SMC_UNK);
+	if (!ethosn_big_fw_verify_header(big_fw, arch_ver)) {
+		return ETHOSN_FAILURE;
 	}
+
+	NOTICE("ETHOSN: TZMP1 setup succeeded with firmware version %u.%u.%u\n",
+	       big_fw->fw_ver_major, big_fw->fw_ver_minor,
+	       big_fw->fw_ver_patch);
+#else
+	NOTICE("ETHOSN: Setup succeeded\n");
+#endif
+
+	return 0;
 }
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index 1925a13..ca2a038 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -252,7 +252,7 @@
 	 * Ensure the write to peripheral registers are *complete* before the write
 	 * to GIC_EOIR.
 	 *
-	 * Note: The completion gurantee depends on various factors of system design
+	 * Note: The completion guarantee depends on various factors of system design
 	 * and the barrier is the best core can do by which execution of further
 	 * instructions waits till the barrier is alive.
 	 */
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index e85dbc1..a4786bb 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- * Copyright (c) 2022, NVIDIA Corporation. 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
  */
@@ -19,6 +19,29 @@
 #include "../common/gic_common_private.h"
 #include "gic600_multichip_private.h"
 
+static struct gic600_multichip_data *plat_gic_multichip_data;
+
+/*******************************************************************************
+ * Retrieve the address of the chip owner for a given SPI ID
+ ******************************************************************************/
+uintptr_t gic600_multichip_gicd_base_for_spi(uint32_t spi_id)
+{
+	unsigned int i;
+
+	/* Find the multichip instance */
+	for (i = 0U; i < GIC600_MAX_MULTICHIP; i++) {
+		if ((spi_id <= plat_gic_multichip_data->spi_ids[i].spi_id_max) &&
+		     (spi_id >= plat_gic_multichip_data->spi_ids[i].spi_id_min)) {
+			break;
+		}
+	}
+
+	/* Ensure that plat_gic_multichip_data contains valid values */
+	assert(i < GIC600_MAX_MULTICHIP);
+
+	return plat_gic_multichip_data->spi_ids[i].gicd_base;
+}
+
 /*******************************************************************************
  * GIC-600 multichip operation related helper functions
  ******************************************************************************/
@@ -27,7 +50,7 @@
 	unsigned int retry = GICD_PUP_UPDATE_RETRIES;
 
 	while ((read_gicd_dchipr(base) & GICD_DCHIPR_PUP_BIT) != 0U) {
-		if (retry-- == 0) {
+		if (retry-- == 0U) {
 			ERROR("GIC-600 connection to Routing Table Owner timed "
 					 "out\n");
 			panic();
@@ -186,15 +209,15 @@
 		panic();
 	}
 
-	for (i = 0; i < multichip_data->chip_count; i++) {
-		spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
-		spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
+	for (i = 0U; i < multichip_data->chip_count; i++) {
+		spi_id_min = multichip_data->spi_ids[i].spi_id_min;
+		spi_id_max = multichip_data->spi_ids[i].spi_id_max;
 
-		if ((spi_id_min != 0) || (spi_id_max != 0)) {
+		if ((spi_id_min != 0U) || (spi_id_max != 0U)) {
 
 			/* 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 "
@@ -232,8 +255,8 @@
 	}
 
 	for (i = 0U; i < multichip_data->chip_count; i++) {
-		spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
-		spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
+		spi_id_min = multichip_data->spi_ids[i].spi_id_min;
+		spi_id_max = multichip_data->spi_ids[i].spi_id_max;
 
 		if ((spi_id_min == 0U) || (spi_id_max == 0U)) {
 			continue;
@@ -299,7 +322,7 @@
 }
 
 /*******************************************************************************
- * Intialize GIC-600 and GIC-700 Multichip operation.
+ * Initialize GIC-600 and GIC-700 Multichip operation.
  ******************************************************************************/
 void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
 {
@@ -342,9 +365,9 @@
 	set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner,
 			multichip_data->chip_addrs[multichip_data->rt_owner],
 			multichip_data->
-			spi_ids[multichip_data->rt_owner][SPI_MIN_INDEX],
+			spi_ids[multichip_data->rt_owner].spi_id_min,
 			multichip_data->
-			spi_ids[multichip_data->rt_owner][SPI_MAX_INDEX]);
+			spi_ids[multichip_data->rt_owner].spi_id_max);
 
 	for (i = 0; i < multichip_data->chip_count; i++) {
 		if (i == multichip_data->rt_owner)
@@ -352,7 +375,17 @@
 
 		set_gicd_chipr_n(multichip_data->rt_owner_base, i,
 				multichip_data->chip_addrs[i],
-				multichip_data->spi_ids[i][SPI_MIN_INDEX],
-				multichip_data->spi_ids[i][SPI_MAX_INDEX]);
+				multichip_data->spi_ids[i].spi_id_min,
+				multichip_data->spi_ids[i].spi_id_max);
 	}
+
+	plat_gic_multichip_data = multichip_data;
+}
+
+/*******************************************************************************
+ * Allow a way to query the status of the GIC600 multichip driver
+ ******************************************************************************/
+bool gic600_multichip_is_initialized(void)
+{
+	return (plat_gic_multichip_data != NULL);
 }
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
index 414bd5b..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
@@ -49,9 +49,6 @@
 /* Number of retries for PUP update */
 #define GICD_PUP_UPDATE_RETRIES		10000
 
-#define SPI_MIN_INDEX			0
-#define SPI_MAX_INDEX			1
-
 #define SPI_BLOCK_MIN_VALUE(spi_id_min) \
 			(((spi_id_min) - GIC600_SPI_ID_MIN) / \
 			GIC600_SPI_ID_MIN)
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index 1d20ff3..89bce95 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -41,6 +41,10 @@
 $(eval $(call assert_boolean,GICV3_SUPPORT_GIC600AE_FMU))
 $(eval $(call add_define,GICV3_SUPPORT_GIC600AE_FMU))
 
+# Set GIC-600 multichip support
+$(eval $(call assert_boolean,GICV3_IMPL_GIC600_MULTICHIP))
+$(eval $(call add_define,GICV3_IMPL_GIC600_MULTICHIP))
+
 # Set GICv4 extension
 $(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
 $(eval $(call add_define,GIC_ENABLE_V4_EXTN))
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 940c939..b27debf 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -1,5 +1,6 @@
 /*
- * 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
  */
@@ -10,6 +11,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/interrupt_props.h>
+#include <drivers/arm/gic600_multichip.h>
 #include <drivers/arm/gic_common.h>
 
 #include <platform_def.h>
@@ -17,6 +19,16 @@
 #include "../common/gic_common_private.h"
 #include "gicv3_private.h"
 
+uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base)
+{
+#if GICV3_IMPL_GIC600_MULTICHIP
+	if (gic600_multichip_is_initialized()) {
+		return gic600_multichip_gicd_base_for_spi(spi_id);
+	}
+#endif
+	return gicd_base;
+}
+
 /******************************************************************************
  * This function marks the core as awake in the re-distributor and
  * ensures that the interface is active.
@@ -148,7 +160,7 @@
 
 	/* Treat all (E)SPIs as G1NS by default. We do 32 at a time. */
 	for (i = MIN_SPI_ID; i < num_ints; i += (1U << IGROUPR_SHIFT)) {
-		gicd_write_igroupr(gicd_base, i, ~0U);
+		gicd_write_igroupr(gicv3_get_multichip_base(i, gicd_base), i, ~0U);
 	}
 
 #if GIC_EXT_INTID
@@ -158,7 +170,7 @@
 
 		for (i = MIN_ESPI_ID; i < num_eints;
 					i += (1U << IGROUPR_SHIFT)) {
-			gicd_write_igroupr(gicd_base, i, ~0U);
+			gicd_write_igroupr(gicv3_get_multichip_base(i, gicd_base), i, ~0U);
 		}
 	} else {
 		INFO("ESPI range is not implemented.\n");
@@ -167,25 +179,25 @@
 
 	/* Setup the default (E)SPI priorities doing four at a time */
 	for (i = MIN_SPI_ID; i < num_ints; i += (1U << IPRIORITYR_SHIFT)) {
-		gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL);
+		gicd_write_ipriorityr(gicv3_get_multichip_base(i, gicd_base), i, GICD_IPRIORITYR_DEF_VAL);
 	}
 
 #if GIC_EXT_INTID
 	for (i = MIN_ESPI_ID; i < num_eints;
 					i += (1U << IPRIORITYR_SHIFT)) {
-		gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL);
+		gicd_write_ipriorityr(gicv3_get_multichip_base(i, gicd_base), i, GICD_IPRIORITYR_DEF_VAL);
 	}
 #endif
 	/*
 	 * Treat all (E)SPIs as level triggered by default, write 16 at a time
 	 */
 	for (i = MIN_SPI_ID; i < num_ints; i += (1U << ICFGR_SHIFT)) {
-		gicd_write_icfgr(gicd_base, i, 0U);
+		gicd_write_icfgr(gicv3_get_multichip_base(i, gicd_base), i, 0U);
 	}
 
 #if GIC_EXT_INTID
 	for (i = MIN_ESPI_ID; i < num_eints; i += (1U << ICFGR_SHIFT)) {
-		gicd_write_icfgr(gicd_base, i, 0U);
+		gicd_write_icfgr(gicv3_get_multichip_base(i, gicd_base), i, 0U);
 	}
 #endif
 }
@@ -211,42 +223,47 @@
 		current_prop = &interrupt_props[i];
 
 		unsigned int intr_num = current_prop->intr_num;
+		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(gicd_base, intr_num);
+		gicd_clr_igroupr(multichip_gicd_base, intr_num);
 
 		/* Configure this interrupt as G0 or a G1S interrupt */
 		assert((current_prop->intr_grp == INTR_GROUP0) ||
 				(current_prop->intr_grp == INTR_GROUP1S));
 
 		if (current_prop->intr_grp == INTR_GROUP1S) {
-			gicd_set_igrpmodr(gicd_base, intr_num);
+			gicd_set_igrpmodr(multichip_gicd_base, intr_num);
 			ctlr_enable |= CTLR_ENABLE_G1S_BIT;
 		} else {
-			gicd_clr_igrpmodr(gicd_base, intr_num);
+			gicd_clr_igrpmodr(multichip_gicd_base, intr_num);
 			ctlr_enable |= CTLR_ENABLE_G0_BIT;
 		}
 
 		/* Set interrupt configuration */
-		gicd_set_icfgr(gicd_base, intr_num, current_prop->intr_cfg);
+		gicd_set_icfgr(multichip_gicd_base, intr_num,
+				current_prop->intr_cfg);
 
 		/* Set the priority of this interrupt */
-		gicd_set_ipriorityr(gicd_base, intr_num,
-					current_prop->intr_pri);
+		gicd_set_ipriorityr(multichip_gicd_base, intr_num,
+				current_prop->intr_pri);
 
 		/* Target (E)SPIs to the primary CPU */
 		gic_affinity_val =
 			gicd_irouter_val_from_mpidr(read_mpidr(), 0U);
-		gicd_write_irouter(gicd_base, intr_num,
-					gic_affinity_val);
+		gicd_write_irouter(multichip_gicd_base, intr_num,
+			gic_affinity_val);
 
 		/* Enable this interrupt */
-		gicd_set_isenabler(gicd_base, intr_num);
+		gicd_set_isenabler(multichip_gicd_base, intr_num);
 	}
 
 	return ctlr_enable;
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index f6c251d..2c74800 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +11,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/interrupt_props.h>
+#include <drivers/arm/gic600_multichip.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/spinlock.h>
 #include <plat/common/platform.h>
@@ -328,6 +330,8 @@
 	/* Enable Group1 Secure interrupts */
 	write_icc_igrpen1_el3(read_icc_igrpen1_el3() |
 				IGRPEN1_EL3_ENABLE_G1S_BIT);
+	/* and restore the original */
+	write_scr_el3(scr_el3);
 	isb();
 	/* Add DSB to ensure visibility of System register writes */
 	dsb();
@@ -430,6 +434,7 @@
 {
 	unsigned int igroup, grpmodr;
 	uintptr_t gicr_base;
+	uintptr_t gicd_base;
 
 	assert(IS_IN_EL3());
 	assert(gicv3_driver_data != NULL);
@@ -453,8 +458,9 @@
 	} else {
 		/* SPIs: 32-1019, ESPIs: 4096-5119 */
 		assert(gicv3_driver_data->gicd_base != 0U);
-		igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id);
-		grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+		igroup = gicd_get_igroupr(gicd_base, id);
+		grpmodr = gicd_get_igrpmodr(gicd_base, id);
 	}
 
 	/*
@@ -930,6 +936,8 @@
  ******************************************************************************/
 unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
 {
+	uintptr_t gicd_base;
+
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
 	assert(proc_num < gicv3_driver_data->rdistif_num);
@@ -943,7 +951,8 @@
 	}
 
 	/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
-	return gicd_get_isactiver(gicv3_driver_data->gicd_base, id);
+	gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+	return gicd_get_isactiver(gicd_base, id);
 }
 
 /*******************************************************************************
@@ -953,6 +962,8 @@
  ******************************************************************************/
 void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
 {
+	uintptr_t gicd_base;
+
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
 	assert(proc_num < gicv3_driver_data->rdistif_num);
@@ -971,7 +982,8 @@
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
 	} else {
 		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
-		gicd_set_isenabler(gicv3_driver_data->gicd_base, id);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+		gicd_set_isenabler(gicd_base, id);
 	}
 }
 
@@ -982,6 +994,8 @@
  ******************************************************************************/
 void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
 {
+	uintptr_t gicd_base;
+
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
 	assert(proc_num < gicv3_driver_data->rdistif_num);
@@ -1003,10 +1017,11 @@
 			gicv3_driver_data->rdistif_base_addrs[proc_num]);
 	} else {
 		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
-		gicd_set_icenabler(gicv3_driver_data->gicd_base, id);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+		gicd_set_icenabler(gicd_base, id);
 
 		/* Write to clear enable requires waiting for pending writes */
-		gicd_wait_for_pending_write(gicv3_driver_data->gicd_base);
+		gicd_wait_for_pending_write(gicd_base);
 	}
 
 	dsbishst();
@@ -1020,6 +1035,7 @@
 		unsigned int priority)
 {
 	uintptr_t gicr_base;
+	uintptr_t gicd_base;
 
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
@@ -1033,7 +1049,8 @@
 		gicr_set_ipriorityr(gicr_base, id, priority);
 	} else {
 		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
-		gicd_set_ipriorityr(gicv3_driver_data->gicd_base, id, priority);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+		gicd_set_ipriorityr(gicd_base, id, priority);
 	}
 }
 
@@ -1047,6 +1064,7 @@
 {
 	bool igroup = false, grpmod = false;
 	uintptr_t gicr_base;
+	uintptr_t gicd_base;
 
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
@@ -1086,10 +1104,12 @@
 		/* Serialize read-modify-write to Distributor registers */
 		spin_lock(&gic_lock);
 
-		igroup ? gicd_set_igroupr(gicv3_driver_data->gicd_base, id) :
-			 gicd_clr_igroupr(gicv3_driver_data->gicd_base, id);
-		grpmod ? gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id) :
-			 gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+
+		igroup ? gicd_set_igroupr(gicd_base, id) :
+			 gicd_clr_igroupr(gicd_base, id);
+		grpmod ? gicd_set_igrpmodr(gicd_base, id) :
+			 gicd_clr_igrpmodr(gicd_base, id);
 
 		spin_unlock(&gic_lock);
 	}
@@ -1165,6 +1185,7 @@
 {
 	unsigned long long aff;
 	uint64_t router;
+	uintptr_t gicd_base;
 
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
@@ -1174,14 +1195,15 @@
 	assert(IS_SPI(id));
 
 	aff = gicd_irouter_val_from_mpidr(mpidr, irm);
-	gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff);
+	gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+	gicd_write_irouter(gicd_base, id, aff);
 
 	/*
 	 * In implementations that do not require 1 of N distribution of SPIs,
 	 * IRM might be RAZ/WI. Read back and verify IRM bit.
 	 */
 	if (irm == GICV3_IRM_ANY) {
-		router = gicd_read_irouter(gicv3_driver_data->gicd_base, id);
+		router = gicd_read_irouter(gicd_base, id);
 		if (((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK) == 0U) {
 			ERROR("GICv3 implementation doesn't support routing ANY\n");
 			panic();
@@ -1196,6 +1218,8 @@
  ******************************************************************************/
 void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
 {
+	uintptr_t gicd_base;
+
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
 	assert(proc_num < gicv3_driver_data->rdistif_num);
@@ -1213,7 +1237,8 @@
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
 	} else {
 		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
-		gicd_set_icpendr(gicv3_driver_data->gicd_base, id);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+		gicd_set_icpendr(gicd_base, id);
 	}
 
 	dsbishst();
@@ -1226,6 +1251,8 @@
  ******************************************************************************/
 void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
 {
+	uintptr_t gicd_base;
+
 	assert(gicv3_driver_data != NULL);
 	assert(gicv3_driver_data->gicd_base != 0U);
 	assert(proc_num < gicv3_driver_data->rdistif_num);
@@ -1244,7 +1271,8 @@
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
 	} else {
 		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
-		gicd_set_ispendr(gicv3_driver_data->gicd_base, id);
+		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
+		gicd_set_ispendr(gicd_base, id);
 	}
 }
 
diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h
index 3af0500..8ad251b 100644
--- a/drivers/arm/gic/v3/gicv3_private.h
+++ b/drivers/arm/gic/v3/gicv3_private.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -233,6 +234,7 @@
 /*******************************************************************************
  * Private GICv3 helper function prototypes
  ******************************************************************************/
+uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base);
 unsigned int gicv3_get_spi_limit(uintptr_t gicd_base);
 unsigned int gicv3_get_espi_limit(uintptr_t gicd_base);
 void gicv3_spis_config_defaults(uintptr_t gicd_base);
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
index 79c6f26..a88e20c 100644
--- a/drivers/arm/sbsa/sbsa.c
+++ b/drivers/arm/sbsa/sbsa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,3 +40,9 @@
 {
 	mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, (0x0));
 }
+
+/* Refresh the secure watchdog timer explicitly */
+void sbsa_wdog_refresh(uintptr_t refresh_base)
+{
+	mmio_write_32(refresh_base + SBSA_WDOG_WRR_OFFSET, SBSA_WDOG_WRR_REFRESH);
+}
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 1bf03d4..7a9cca8 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,8 +31,6 @@
 	} while (0)
 
 #pragma weak plat_set_nv_ctr2
-#pragma weak plat_convert_pk
-
 
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
 		const auth_param_type_desc_t *b)
@@ -150,8 +148,8 @@
 			  const auth_img_desc_t *img_desc,
 			  void *img, unsigned int img_len)
 {
-	void *data_ptr, *pk_ptr, *pk_hash_ptr, *sig_ptr, *sig_alg_ptr;
-	unsigned int data_len, pk_len, pk_hash_len, sig_len, sig_alg_len;
+	void *data_ptr, *pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr;
+	unsigned int data_len, pk_len, pk_plat_len, sig_len, sig_alg_len;
 	unsigned int flags = 0;
 	int rc = 0;
 
@@ -173,52 +171,69 @@
 	/* Get the public key from the parent. If there is no parent (NULL),
 	 * the certificate has been signed with the ROTPK, so we have to get
 	 * the PK from the platform */
-	if (img_desc->parent) {
+	if (img_desc->parent != NULL) {
 		rc = auth_get_param(param->pk, img_desc->parent,
 				&pk_ptr, &pk_len);
+		return_if_error(rc);
 	} else {
-		rc = plat_get_rotpk_info(param->pk->cookie, &pk_ptr, &pk_len,
-				&flags);
-	}
-	return_if_error(rc);
-
-	if (flags & (ROTPK_IS_HASH | ROTPK_NOT_DEPLOYED)) {
-		/* If the PK is a hash of the key or if the ROTPK is not
-		   deployed on the platform, retrieve the key from the image */
-		pk_hash_ptr = pk_ptr;
-		pk_hash_len = pk_len;
-		rc = img_parser_get_auth_param(img_desc->img_type,
-					param->pk, img, img_len,
-					&pk_ptr, &pk_len);
+		/*
+		 * Root certificates are signed with the ROTPK, so we have to
+		 * get it from the platform.
+		 */
+		rc = plat_get_rotpk_info(param->pk->cookie, &pk_plat_ptr,
+					 &pk_plat_len, &flags);
 		return_if_error(rc);
 
+		assert(is_rotpk_flags_valid(flags));
+
-		/* Ask the crypto module to verify the signature */
-		rc = crypto_mod_verify_signature(data_ptr, data_len,
-						 sig_ptr, sig_len,
-						 sig_alg_ptr, sig_alg_len,
-						 pk_ptr, pk_len);
+		/* Also retrieve the key from the image. */
+		rc = img_parser_get_auth_param(img_desc->img_type,
+					       param->pk, img, img_len,
+					       &pk_ptr, &pk_len);
 		return_if_error(rc);
 
-		if (flags & ROTPK_NOT_DEPLOYED) {
+		/*
+		 * Validate the certificate's key against the platform ROTPK.
+		 *
+		 * Platform may store key in one of the following way -
+		 * 1. Hash of ROTPK
+		 * 2. Hash if prefixed, suffixed or modified ROTPK
+		 * 3. Full ROTPK
+		 */
+		if ((flags & ROTPK_NOT_DEPLOYED) != 0U) {
 			NOTICE("ROTPK is not deployed on platform. "
 				"Skipping ROTPK verification.\n");
-		} else {
-			/* platform may store the hash of a prefixed, suffixed or modified pk */
-			rc = plat_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
+		} else if ((flags & ROTPK_IS_HASH) != 0U) {
+			/*
+			 * platform may store the hash of a prefixed,
+			 * suffixed or modified pk
+			 */
+			rc = crypto_mod_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
 			return_if_error(rc);
 
-			/* Ask the crypto-module to verify the key hash */
+			/*
+			 * The hash of the certificate's public key must match
+			 * the hash of the ROTPK.
+			 */
 			rc = crypto_mod_verify_hash(pk_ptr, pk_len,
-				    pk_hash_ptr, pk_hash_len);
+						    pk_plat_ptr, pk_plat_len);
+			return_if_error(rc);
+		} else {
+			/* Platform supports full ROTPK */
+			if ((pk_len != pk_plat_len) ||
+			    (memcmp(pk_plat_ptr, pk_ptr, pk_len) != 0)) {
+				ERROR("plat and cert ROTPK len mismatch\n");
+				return -1;
+			}
 		}
-	} else {
-		/* Ask the crypto module to verify the signature */
-		rc = crypto_mod_verify_signature(data_ptr, data_len,
-						 sig_ptr, sig_len,
-						 sig_alg_ptr, sig_alg_len,
-						 pk_ptr, pk_len);
 	}
 
+	/* Ask the crypto module to verify the signature */
+	rc = crypto_mod_verify_signature(data_ptr, data_len,
+					 sig_ptr, sig_len,
+					 sig_alg_ptr, sig_alg_len,
+					 pk_ptr, pk_len);
+
 	return rc;
 }
 
@@ -314,15 +329,6 @@
 	return plat_set_nv_ctr(cookie, nv_ctr);
 }
 
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
-{
-	*hashed_pk_ptr = full_pk_ptr;
-	*hashed_pk_len = full_pk_len;
-
-	return 0;
-}
-
 /*
  * Return the parent id in the output parameter '*parent_id'
  *
diff --git a/drivers/auth/cca/cot.c b/drivers/auth/cca/cot.c
index e8f4d9c..2a03604 100644
--- a/drivers/auth/cca/cot.c
+++ b/drivers/auth/cca/cot.c
@@ -42,8 +42,8 @@
 /*
  * Parameter type descriptors.
  */
-static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t cca_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, CCA_FW_NVCOUNTER_OID);
 static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, 0);
 static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
@@ -69,6 +69,8 @@
 		AUTH_PARAM_HASH, RMM_HASH_OID);
 
 #ifdef IMAGE_BL2
+static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
 static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
 
@@ -127,8 +129,8 @@
 		[1] = {
 			.type = AUTH_METHOD_NV_CTR,
 			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
+				.cert_nv_ctr = &cca_nv_ctr,
+				.plat_nv_ctr = &cca_nv_ctr
 			}
 		}
 	},
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index fa1adb4..e36b285 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -142,6 +142,20 @@
 #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
+int crypto_mod_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			  void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+{
+	if (crypto_lib_desc.convert_pk != NULL) {
+		return crypto_lib_desc.convert_pk(full_pk_ptr, full_pk_len,
+						  hashed_pk_ptr, hashed_pk_len);
+	}
+
+	*hashed_pk_ptr = full_pk_ptr;
+	*hashed_pk_len = full_pk_len;
+
+	return 0;
+}
+
 /*
  * Authenticated decryption of data
  *
diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c
index e2b189b..bba13f8 100644
--- a/drivers/auth/cryptocell/712/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c
@@ -330,5 +330,5 @@
 /*
  * Register crypto library descriptor
  */
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, NULL, NULL);
 
diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c
index 388264e..6601b3a 100644
--- a/drivers/auth/cryptocell/713/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c
@@ -302,4 +302,4 @@
 /*
  * Register crypto library descriptor
  */
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, NULL, NULL);
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 4241d21..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) {
@@ -396,18 +399,19 @@
 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 #if TF_MBEDTLS_USE_AES_GCM
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
-		    auth_decrypt);
+		    auth_decrypt, NULL);
 #else
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
-		    NULL);
+		    NULL, NULL);
 #endif
 #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
 #if TF_MBEDTLS_USE_AES_GCM
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash,
-		    auth_decrypt);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
+		    auth_decrypt, NULL);
 #else
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
+		    NULL, NULL);
 #endif
 #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
-REGISTER_CRYPTO_LIB(LIB_NAME, init, calc_hash);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
 #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
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/brcm/emmc/emmc_chal_sd.c b/drivers/brcm/emmc/emmc_chal_sd.c
index 34d761c..5379ec1 100644
--- a/drivers/brcm/emmc/emmc_chal_sd.c
+++ b/drivers/brcm/emmc/emmc_chal_sd.c
@@ -119,7 +119,7 @@
 		mmio_setbits_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL_OFFSET,
 				SD4_EMMC_TOP_CTRL_SDPWR_MASK);
 
-	/* dummy write & ack to verify if the sdio is ready to send commads */
+	/* dummy write & ack to verify if the sdio is ready to send commands */
 	mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_ARG_OFFSET, 0);
 	mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CMD_OFFSET, 0);
 
@@ -600,7 +600,7 @@
 
 	if (actual_freq > desired_freq) {
 		/*
-		 * Division does not result in exact freqency match.
+		 * Division does not result in exact frequency match.
 		 * Make sure resulting frequency does not exceed requested freq.
 		 */
 		div_ctrl_setting++;
diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c
index 40bc4a0..789ed9c 100644
--- a/drivers/brcm/emmc/emmc_csl_sdcard.c
+++ b/drivers/brcm/emmc/emmc_csl_sdcard.c
@@ -244,7 +244,7 @@
  * The function handles real data transmission on both DMA and
  * none DMA mode, In None DMA mode the data transfer starts
  * when the command is sent to the card, data has to be written
- * into the host contollers buffer at this time one block
+ * into the host controllers buffer at this time one block
  * at a time.
  * In DMA mode, the real data transfer is done by the DMA engine
  * and this functions just waits for the data transfer to complete.
@@ -318,7 +318,7 @@
 
 
 /*
- * The function initalizes the SD/SDIO/MMC/CEATA and detects
+ * The function initializes the SD/SDIO/MMC/CEATA and detects
  * the card according to the flag of detection.
  * Once this function is called, the card is put into ready state
  * so application can do data transfer to and from the card.
@@ -393,7 +393,7 @@
 
 
 /*
- * The function handles MMC/CEATA card initalization.
+ * The function handles MMC/CEATA card initialization.
  */
 int init_mmc_card(struct sd_handle *handle)
 {
diff --git a/drivers/brcm/i2c/i2c.c b/drivers/brcm/i2c/i2c.c
index 2096a82..b45c0e7 100644
--- a/drivers/brcm/i2c/i2c.c
+++ b/drivers/brcm/i2c/i2c.c
@@ -612,7 +612,7 @@
  *
  * Description:
  *	This function reads I2C data from a device without specifying
- *	a command regsiter.
+ *	a command register.
  *
  * Parameters:
  *	bus_id  - I2C bus ID
@@ -647,7 +647,7 @@
  *
  * Description:
  *	This function send I2C data to a device without specifying
- *	a command regsiter.
+ *	a command register.
  *
  * Parameters:
  *	bus_id  - I2C bus ID
diff --git a/drivers/brcm/sotp.c b/drivers/brcm/sotp.c
index 63c4820..20c6441 100644
--- a/drivers/brcm/sotp.c
+++ b/drivers/brcm/sotp.c
@@ -168,7 +168,7 @@
 	       BIT(SOTP_STATUS__FDONE))
 		;
 
-	/*  Enable OTP acces by CPU */
+	/*  Enable OTP access by CPU */
 	mmio_setbits_32(SOTP_PROG_CONTROL,
 			BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN));
 
@@ -244,7 +244,7 @@
 	/* Command done is cleared w1c */
 	mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE));
 
-	/* disable OTP acces by CPU */
+	/* disable OTP access by CPU */
 	mmio_clrbits_32(SOTP_PROG_CONTROL,
 			BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN));
 
diff --git a/drivers/cadence/combo_phy/cdns_combo_phy.c b/drivers/cadence/combo_phy/cdns_combo_phy.c
new file mode 100644
index 0000000..f00d0c1
--- /dev/null
+++ b/drivers/cadence/combo_phy/cdns_combo_phy.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_combo_phy.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+int cdns_sdmmc_write_phy_reg(uint32_t phy_reg_addr, uint32_t phy_reg_addr_value,
+			uint32_t phy_reg_data, uint32_t phy_reg_data_value)
+{
+	uint32_t data = 0U;
+	uint32_t value = 0U;
+
+	/* Get PHY register address, write HRS04*/
+	value = mmio_read_32(phy_reg_addr);
+	value &= ~PHY_REG_ADDR_MASK;
+	value |= phy_reg_addr_value;
+	mmio_write_32(phy_reg_addr, value);
+	data = mmio_read_32(phy_reg_addr);
+	if ((data & PHY_REG_ADDR_MASK) != phy_reg_addr_value) {
+		ERROR("PHY_REG_ADDR is not set properly\n");
+		return -ENXIO;
+	}
+
+	/* Get PHY register data, write HRS05 */
+	value &= ~PHY_REG_DATA_MASK;
+	value |= phy_reg_data_value;
+	mmio_write_32(phy_reg_data, value);
+	data = mmio_read_32(phy_reg_data);
+	if (data != phy_reg_data_value) {
+		ERROR("PHY_REG_DATA is not set properly\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int cdns_sd_card_detect(void)
+{
+	uint32_t value = 0;
+
+	/* Card detection */
+	do {
+		value = mmio_read_32(SDMMC_CDN(SRS09));
+	/* Wait for card insertion. SRS09.CI = 1 */
+	} while ((value & (1 << SDMMC_CDN_CI)) == 0);
+
+	if ((value & (1 << SDMMC_CDN_CI)) == 0) {
+		ERROR("Card does not detect\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int cdns_emmc_card_reset(void)
+{
+	uint32_t _status = 0;
+
+	/* Reset embedded card */
+	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
+	mdelay(68680); /* ~68680us */
+	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
+	udelay(340); /* ~340us */
+
+	/* Turn on supply voltage */
+	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
+	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
+
+	return 0;
+}
diff --git a/drivers/cadence/emmc/cdns_sdmmc.c b/drivers/cadence/emmc/cdns_sdmmc.c
new file mode 100644
index 0000000..d2cd4d6
--- /dev/null
+++ b/drivers/cadence/emmc/cdns_sdmmc.c
@@ -0,0 +1,824 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <drivers/mmc.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+/* Card busy and present */
+#define CARD_BUSY					1
+#define CARD_NOT_BUSY					0
+
+/* 500 ms delay to read the RINST register */
+#define DELAY_MS_SRS_READ				500
+#define DELAY_RES					10
+
+/* SRS12 error mask */
+#define SRS12_ERR_MASK					0xFFFF8000
+
+/* Check DV dfi_init val=0 */
+#define IO_MASK_END_DATA				0x0
+
+/* Check DV dfi_init val=2; DDR Mode */
+#define IO_MASK_END_DATA_DDR				0x2
+#define IO_MASK_START_DATA				0x0
+#define DATA_SELECT_OE_END_DATA				0x1
+
+#define TIMEOUT						100000
+
+/* General define */
+#define SDHC_REG_MASK					UINT_MAX
+#define SD_HOST_BLOCK_SIZE				0x200
+#define DTCVVAL_DEFAULT_VAL				0xE
+#define CDMMC_DMA_MAX_BUFFER_SIZE			64*1024
+#define CDNSMMC_ADDRESS_MASK				U(0x0f)
+#define CONFIG_CDNS_DESC_COUNT				8
+
+void cdns_init(void);
+int cdns_send_cmd(struct mmc_cmd *cmd);
+int cdns_set_ios(unsigned int clk, unsigned int width);
+int cdns_prepare(int lba, uintptr_t buf, size_t size);
+int cdns_read(int lba, uintptr_t buf, size_t size);
+int cdns_write(int lba, uintptr_t buf, size_t size);
+
+const struct mmc_ops cdns_sdmmc_ops = {
+	.init			= cdns_init,
+	.send_cmd		= cdns_send_cmd,
+	.set_ios		= cdns_set_ios,
+	.prepare		= cdns_prepare,
+	.read			= cdns_read,
+	.write			= cdns_write,
+};
+
+struct cdns_sdmmc_params cdns_params;
+struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
+struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT];
+#else
+struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT] __aligned(32);
+#endif
+
+bool data_cmd;
+
+int cdns_wait_ics(uint16_t timeout, uint32_t cdn_srs_res)
+{
+	/* Clock for sdmclk and sdclk */
+	uint32_t count = 0;
+	uint32_t data = 0;
+
+	/* Wait status command response ready */
+	do {
+		data = mmio_read_32(cdn_srs_res);
+		count++;
+		if (count >= timeout) {
+			return -ETIMEDOUT;
+		}
+	} while ((data & (1 << SDMMC_CDN_ICS)) == 0);
+
+	return 0;
+}
+
+int cdns_busy(void)
+{
+	unsigned int data;
+
+	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS09);
+	return (data & STATUS_DATA_BUSY) ? CARD_BUSY : CARD_NOT_BUSY;
+}
+
+int cdns_vol_reset(void)
+{
+	/* Reset embedded card */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+	udelay(250);
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
+	udelay(500);
+
+	/* Turn on supply voltage */
+	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+	udelay(250);
+	return 0;
+}
+
+void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+	struct cdns_sdmmc_sdhc *sdhc_reg)
+{
+	/* Values are taken by the reference of cadence IP documents */
+	combo_phy_reg->cp_clk_wr_delay = 0;
+	combo_phy_reg->cp_clk_wrdqs_delay = 0;
+	combo_phy_reg->cp_data_select_oe_end = 0;
+	combo_phy_reg->cp_dll_bypass_mode = 1;
+	combo_phy_reg->cp_dll_locked_mode = 0;
+	combo_phy_reg->cp_dll_start_point = 0;
+	combo_phy_reg->cp_gate_cfg_always_on = 1;
+	combo_phy_reg->cp_io_mask_always_on = 0;
+	combo_phy_reg->cp_io_mask_end = 0;
+	combo_phy_reg->cp_io_mask_start = 0;
+	combo_phy_reg->cp_rd_del_sel = 52;
+	combo_phy_reg->cp_read_dqs_cmd_delay = 0;
+	combo_phy_reg->cp_read_dqs_delay = 0;
+	combo_phy_reg->cp_sw_half_cycle_shift = 0;
+	combo_phy_reg->cp_sync_method = 1;
+	combo_phy_reg->cp_underrun_suppress = 1;
+	combo_phy_reg->cp_use_ext_lpbk_dqs = 1;
+	combo_phy_reg->cp_use_lpbk_dqs = 1;
+	combo_phy_reg->cp_use_phony_dqs = 1;
+	combo_phy_reg->cp_use_phony_dqs_cmd = 1;
+
+	sdhc_reg->sdhc_extended_rd_mode = 1;
+	sdhc_reg->sdhc_extended_wr_mode = 1;
+	sdhc_reg->sdhc_hcsdclkadj = 0;
+	sdhc_reg->sdhc_idelay_val = 0;
+	sdhc_reg->sdhc_rdcmd_en = 1;
+	sdhc_reg->sdhc_rddata_en = 1;
+	sdhc_reg->sdhc_rw_compensate = 9;
+	sdhc_reg->sdhc_sdcfsh = 0;
+	sdhc_reg->sdhc_sdcfsl = 1;
+	sdhc_reg->sdhc_wrcmd0_dly = 1;
+	sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0;
+	sdhc_reg->sdhc_wrcmd1_dly = 0;
+	sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0;
+	sdhc_reg->sdhc_wrdata0_dly = 1;
+	sdhc_reg->sdhc_wrdata0_sdclk_dly = 0;
+	sdhc_reg->sdhc_wrdata1_dly = 0;
+	sdhc_reg->sdhc_wrdata1_sdclk_dly = 0;
+}
+
+static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+	struct cdns_sdmmc_sdhc *sdhc_reg)
+{
+	uint32_t value = 0;
+	int ret = 0;
+
+	/* program PHY_DQS_TIMING_REG */
+	value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) |
+		(CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) |
+		(CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) |
+		(CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DQS_TIMING_REG, MMC_REG_BASE +
+			SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_GATE_LPBK_CTRL_REG */
+	value = (CP_SYNC_METHOD(combo_phy_reg->cp_sync_method)) |
+		(CP_SW_HALF_CYCLE_SHIFT(combo_phy_reg->cp_sw_half_cycle_shift)) |
+		(CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) |
+		(CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) |
+		(CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, MMC_REG_BASE +
+			SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_DLL_MASTER_CTRL_REG */
+	value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode))
+			| (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, MMC_REG_BASE
+			+ SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_DLL_SLAVE_CTRL_REG */
+	value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay))
+		| (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay))
+		| (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay))
+		| (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, MMC_REG_BASE
+			+ SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_CTRL_REG */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS04, COMBO_PHY_REG
+			+ PHY_CTRL_REG);
+	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS05);
+
+	/* phony_dqs_timing=0 */
+	value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS05, value);
+
+	/* switch off DLL_RESET */
+	do {
+		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+		value |= SDHC_PHY_SW_RESET;
+		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	/* polling PHY_INIT_COMPLETE */
+	} while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE);
+
+	/* program PHY_DQ_TIMING_REG */
+	combo_phy_reg->cp_io_mask_end = 0U;
+	value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on))
+		| (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end))
+		| (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start))
+		| (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
+
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DQ_TIMING_REG, MMC_REG_BASE
+			+ SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+	return 0;
+}
+
+int cdns_read(int lba, uintptr_t buf, size_t size)
+{
+	inv_dcache_range(buf, size);
+
+	return 0;
+}
+
+void cdns_init(void)
+{
+	/* Dummy function pointer for cdns_init. */
+}
+
+int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size)
+{
+	data_cmd = true;
+	struct cdns_idmac_desc *desc;
+	uint32_t desc_cnt, i;
+	uint64_t desc_base;
+
+	assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) &&
+			(cdns_params.desc_size > 0) &&
+			((MMC_REG_BASE & MMC_BLOCK_MASK) == 0) &&
+			((cdns_params.desc_base & MMC_BLOCK_MASK) == 0) &&
+			((cdns_params.desc_size & MMC_BLOCK_MASK) == 0));
+
+	flush_dcache_range(dma_buff, size);
+
+	desc_cnt = (size + (CDMMC_DMA_MAX_BUFFER_SIZE) - 1) / (CDMMC_DMA_MAX_BUFFER_SIZE);
+	assert(desc_cnt * sizeof(struct cdns_idmac_desc) < cdns_params.desc_size);
+
+	if (desc_cnt > CONFIG_CDNS_DESC_COUNT) {
+		ERROR("Requested data transfer length %ld is greater than configured length %d",
+				size, (CONFIG_CDNS_DESC_COUNT * CDMMC_DMA_MAX_BUFFER_SIZE));
+		return -EINVAL;
+	}
+
+	desc = (struct cdns_idmac_desc *)cdns_params.desc_base;
+	desc_base = (uint64_t)desc;
+	i = 0;
+
+	while ((i + 1) < desc_cnt) {
+		desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
+		desc->reserved = 0;
+		desc->len = MAX_64KB_PAGE;
+		desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+		desc->addr_hi = (dma_buff >> 32) & 0xffffffff;
+#endif
+		size -= CDMMC_DMA_MAX_BUFFER_SIZE;
+		desc++;
+		i++;
+	}
+
+	desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA |
+			ADMA_DESC_ATTR_END;
+	desc->reserved = 0;
+	desc->len = size;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+	desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
+	desc->addr_hi = (dma_buff >> 32) & UINT_MAX;
+#else
+	desc->addr_lo = (dma_buff & UINT_MAX);
+#endif
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS22, (uint32_t)desc_base);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS23, (uint32_t)(desc_base >> 32));
+	flush_dcache_range(cdns_params.desc_base,
+				desc_cnt * CDMMC_DMA_MAX_BUFFER_SIZE);
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS01,
+			((512 << BLOCK_SIZE) | ((size/512) << BLK_COUNT_CT) | SDMA_BUF));
+	return 0;
+}
+
+static void cdns_host_set_clk(int clk)
+{
+	uint32_t ret = 0;
+	uint32_t sdclkfsval = 0;
+	uint32_t dtcvval = DTCVVAL_DEFAULT_VAL;
+
+	sdclkfsval = (cdns_params.clk_rate / 2000) / clk;
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+			(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+
+	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
+	if (ret != 0U) {
+		ERROR("Waiting SDMMC_CDN_ICS timeout");
+	}
+
+	/* Enable DLL reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &
+			~SDHC_DLL_RESET_MASK);
+	/* Set extended_wr_mode */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09)
+			& SDHC_EXTENDED_WR_MODE_MASK) | (1 << EXTENDED_WR_MODE));
+	/* Release DLL reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | 1);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+
+	do {
+		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+	(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+}
+
+int cdns_set_ios(unsigned int clk, unsigned int width)
+{
+
+	switch (width) {
+	case MMC_BUS_WIDTH_1:
+		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), LEDC_OFF);
+		break;
+	case MMC_BUS_WIDTH_4:
+		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), DTW_4BIT);
+		break;
+	case MMC_BUS_WIDTH_8:
+		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), EDTW_8BIT);
+		break;
+	default:
+		assert(0);
+		break;
+	}
+	cdns_host_set_clk(clk);
+
+	return 0;
+}
+
+int cdns_sdmmc_write_sd_host_reg(uint32_t addr, uint32_t data)
+{
+	uint32_t value = 0;
+
+	value = mmio_read_32(addr);
+	value &= ~SDHC_REG_MASK;
+	value |= data;
+	mmio_write_32(addr, value);
+	value = mmio_read_32(addr);
+	if (value != data) {
+		ERROR("SD host address is not set properly\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int cdns_write(int lba, uintptr_t buf, size_t size)
+{
+	return 0;
+}
+
+static int cdns_init_hrs_io(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+	struct cdns_sdmmc_sdhc *sdhc_reg)
+{
+	uint32_t value = 0;
+	int ret = 0;
+
+	/* program HRS09, register 42 */
+	value = (SDHC_RDDATA_EN(sdhc_reg->sdhc_rddata_en))
+		| (SDHC_RDCMD_EN(sdhc_reg->sdhc_rdcmd_en))
+		| (SDHC_EXTENDED_WR_MODE(sdhc_reg->sdhc_extended_wr_mode))
+		| (SDHC_EXTENDED_RD_MODE(sdhc_reg->sdhc_extended_rd_mode));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+	if (ret != 0) {
+		ERROR("Program HRS09 failed");
+		return ret;
+	}
+
+	/* program HRS10, register 43 */
+	value = (SDHC_HCSDCLKADJ(sdhc_reg->sdhc_hcsdclkadj));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS10, value);
+	if (ret != 0) {
+		ERROR("Program HRS10 failed");
+		return ret;
+	}
+
+	/* program HRS16, register 48 */
+	value = (SDHC_WRDATA1_SDCLK_DLY(sdhc_reg->sdhc_wrdata1_sdclk_dly))
+		| (SDHC_WRDATA0_SDCLK_DLY(sdhc_reg->sdhc_wrdata0_sdclk_dly))
+		| (SDHC_WRCMD1_SDCLK_DLY(sdhc_reg->sdhc_wrcmd1_sdclk_dly))
+		| (SDHC_WRCMD0_SDCLK_DLY(sdhc_reg->sdhc_wrcmd0_sdclk_dly))
+		| (SDHC_WRDATA1_DLY(sdhc_reg->sdhc_wrdata1_dly))
+		| (SDHC_WRDATA0_DLY(sdhc_reg->sdhc_wrdata0_dly))
+		| (SDHC_WRCMD1_DLY(sdhc_reg->sdhc_wrcmd1_dly))
+		| (SDHC_WRCMD0_DLY(sdhc_reg->sdhc_wrcmd0_dly));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS16, value);
+	if (ret != 0) {
+		ERROR("Program HRS16 failed");
+		return ret;
+	}
+
+	/* program HRS07, register 40 */
+	value = (SDHC_RW_COMPENSATE(sdhc_reg->sdhc_rw_compensate))
+		| (SDHC_IDELAY_VAL(sdhc_reg->sdhc_idelay_val));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS07, value);
+	if (ret != 0) {
+		ERROR("Program HRS07 failed");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int cdns_hc_set_clk(struct cdns_sdmmc_params *cdn_sdmmc_dev_mode_params)
+{
+	uint32_t ret = 0;
+	uint32_t dtcvval, sdclkfsval;
+
+	dtcvval = DTC_VAL;
+	sdclkfsval = 0;
+
+	if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_DS) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR12) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR_BC)) {
+		sdclkfsval = 4;
+	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_HS) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR25) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_DDR50) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR)) {
+		sdclkfsval = 2;
+	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR50) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_DDR) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400es)) {
+		sdclkfsval = 1;
+	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR104) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS200)) {
+		sdclkfsval = 0;
+	}
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
+	if (ret != 0U) {
+		ERROR("Waiting SDMMC_CDN_ICS timeout");
+		return ret;
+	}
+
+	/* Enable DLL reset */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09), mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) & ~SDHC_DLL_RESET_MASK);
+	/* Set extended_wr_mode */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09),
+	(mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &	SDHC_EXTENDED_WR_MODE_MASK) |
+			(1 << EXTENDED_WR_MODE));
+	/* Release DLL reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | 1);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+	do {
+		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+	return 0;
+}
+
+int cdns_reset(void)
+{
+	uint32_t data = 0;
+	uint32_t count = 0;
+	uint32_t value = 0;
+
+	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
+	value &= ~(0xFFFF);
+	value |= 0x0;
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, value);
+	udelay(500);
+
+	/* Software reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS00, 1);
+	/* Wait status command response ready */
+	do {
+		data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS00);
+		count++;
+		if (count >= 5000) {
+			return -ETIMEDOUT;
+		}
+	/* Wait for HRS00.SWR */
+	} while ((data & 1) == 1);
+
+	/* Step 1, switch on DLL_RESET */
+	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	value &= ~SDHC_PHY_SW_RESET;
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+
+	return 0;
+}
+
+int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
+struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
+{
+	int ret = 0;
+
+	ret = cdns_reset();
+	if (ret != 0) {
+		ERROR("Program phy reg init failed");
+		return ret;
+	}
+
+	ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (ret != 0) {
+		ERROR("Program phy reg init failed");
+		return ret;
+	}
+
+	ret = cdns_init_hrs_io(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (ret != 0) {
+		ERROR("Program init for HRS reg is failed");
+		return ret;
+	}
+
+	ret = cdns_sd_card_detect();
+	if (ret != 0) {
+		ERROR("SD card does not detect");
+		return ret;
+	}
+
+	ret = cdns_vol_reset();
+	if (ret != 0) {
+		ERROR("eMMC card reset failed");
+		return ret;
+	}
+
+	ret = cdns_hc_set_clk(&cdns_params);
+	if (ret != 0) {
+		ERROR("hc set clk failed");
+		return ret;
+	}
+
+	return 0;
+}
+
+void cdns_srs10_value_toggle(uint8_t write_val, uint8_t prev_val)
+{
+	uint32_t data_op = 0U;
+
+	data_op = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, (data_op & (prev_val << 0)));
+	mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, data_op | (write_val << 0));
+}
+
+void cdns_srs11_srs15_config(uint32_t srs11_val, uint32_t srs15_val)
+{
+	uint32_t data = 0U;
+
+	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (data | srs11_val));
+	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS15);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS15, (data | srs15_val));
+}
+
+int cdns_send_cmd(struct mmc_cmd *cmd)
+{
+	uint32_t op = 0, ret = 0;
+	uint8_t write_value = 0, prev_val = 0;
+	uint32_t value;
+	int32_t timeout;
+	uint32_t cmd_indx;
+	uint32_t status = 0, srs15_val = 0, srs11_val = 0;
+	uint32_t status_check = 0;
+
+	assert(cmd);
+	cmd_indx = (cmd->cmd_idx) << COM_IDX;
+
+	if (data_cmd) {
+		switch (cmd->cmd_idx) {
+		case SD_SWITCH:
+			op = DATA_PRESENT;
+			write_value = ADMA2_32 | DT_WIDTH;
+			prev_val = ADMA2_32 | DT_WIDTH;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			srs15_val = BIT_AD_64 | HV4E | V18SE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_WRITE_SINGLE_BLOCK:
+		case SD_READ_SINGLE_BLOCK:
+			op = DATA_PRESENT;
+			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
+			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
+			break;
+
+		case SD_WRITE_MULTIPLE_BLOCK:
+		case SD_READ_MULTIPLE_BLOCK:
+			op = DATA_PRESENT | AUTO_CMD_EN | MULTI_BLK_READ;
+			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
+			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
+			break;
+
+		case SD_APP_SEND_SCR:
+			op = DATA_PRESENT;
+			write_value = ADMA2_32 | LEDC;
+			prev_val = LEDC;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = BIT_AD_64 | HV4E | V18SE;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_SEND_IF_COND:
+			op = DATA_PRESENT | CMD_IDX_CHK_ENABLE;
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		default:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			op = 0;
+			break;
+		}
+	} else {
+		switch (cmd->cmd_idx) {
+		case SD_GO_IDLE_STATE:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E;
+			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_ALL_SEND_CID:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E | V18SE;
+			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_SEND_IF_COND:
+			op = CMD_IDX_CHK_ENABLE;
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_STOP_TRANSMISSION:
+			op = CMD_STOP_ABORT_CMD;
+			break;
+
+		case SD_SEND_STATUS:
+			break;
+
+		case 1:
+			cmd->cmd_arg = 0;
+			break;
+
+		case SD_SELECT_CARD:
+			op = MULTI_BLK_READ;
+			break;
+
+		case SD_APP_CMD:
+		default:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			op = 0;
+			break;
+		}
+	}
+
+	switch (cmd->resp_type) {
+	case MMC_RESPONSE_NONE:
+		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN;
+		break;
+
+	case MMC_RESPONSE_R2:
+		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
+			RES_TYPE_SEL_136 | CMD_CHECK_RESP_CRC;
+		break;
+
+	case MMC_RESPONSE_R3:
+		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
+			RES_TYPE_SEL_48;
+		break;
+
+	case MMC_RESPONSE_R1:
+		if ((cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK) || (cmd->cmd_idx
+			== SD_WRITE_MULTIPLE_BLOCK)) {
+			op |= DMA_ENABLED | BLK_CNT_EN | RES_TYPE_SEL_48
+			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+		} else {
+			op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | RES_TYPE_SEL_48
+			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+		}
+		break;
+
+	default:
+		op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | MULTI_BLK_READ |
+			RES_TYPE_SEL_48 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+		break;
+	}
+
+	timeout = TIMEOUT;
+	do {
+		udelay(100);
+		ret = cdns_busy();
+		if (--timeout <= 0) {
+			udelay(50);
+			panic();
+		}
+	} while (ret);
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS12, UINT_MAX);
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS02, cmd->cmd_arg);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS14, 0x00000000);
+	if (cmd_indx == 1)
+		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, SDHC_CDNS_SRS03_VALUE);
+	else
+		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, op | cmd_indx);
+
+	timeout = TIMEOUT;
+	do {
+		udelay(500);
+		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS12);
+	} while (((value & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
+
+	timeout = TIMEOUT;
+
+	if (data_cmd) {
+		data_cmd = false;
+		do {
+			udelay(250);
+		} while (((value & TRAN_COMP) == 0) && (timeout-- > 0));
+	}
+
+	status_check = value & SRS12_ERR_MASK;
+	if (status_check != 0U) {
+		ERROR("SD host controller send command failed, SRS12 = %x", status);
+		return -1;
+	}
+
+	if ((op & RES_TYPE_SEL_48) || (op & RES_TYPE_SEL_136)) {
+		cmd->resp_data[0] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS04);
+		if (op & RES_TYPE_SEL_136) {
+			cmd->resp_data[1] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS05);
+			cmd->resp_data[2] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS06);
+			cmd->resp_data[3] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS07);
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/cadence/nand/cdns_nand.c b/drivers/cadence/nand/cdns_nand.c
new file mode 100644
index 0000000..5a66262
--- /dev/null
+++ b/drivers/cadence/nand/cdns_nand.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_nand.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <platform_def.h>
+
+/* NAND flash device information struct */
+static cnf_dev_info_t dev_info;
+
+/* Scratch buffers for read and write operations */
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+/* Wait for controller to be in idle state */
+static inline void cdns_nand_wait_idle(void)
+{
+	uint32_t reg = 0U;
+
+	do {
+		udelay(CNF_DEF_DELAY_US);
+		reg = mmio_read_32(CNF_CMDREG(CTRL_STATUS));
+	} while (CNF_GET_CTRL_BUSY(reg) != 0U);
+}
+
+/* Wait for given thread to be in ready state */
+static inline void cdns_nand_wait_thread_ready(uint8_t thread_id)
+{
+	uint32_t reg = 0U;
+
+	do {
+		udelay(CNF_DEF_DELAY_US);
+		reg = mmio_read_32(CNF_CMDREG(TRD_STATUS));
+		reg &= (1U << (uint32_t)thread_id);
+	} while (reg != 0U);
+}
+
+/* Check if the last operation/command in selected thread is completed */
+static int cdns_nand_last_opr_status(uint8_t thread_id)
+{
+	uint8_t nthreads = 0U;
+	uint32_t reg = 0U;
+
+	/* Get number of threads */
+	reg = mmio_read_32(CNF_CTRLPARAM(FEATURE));
+	nthreads = CNF_GET_NTHREADS(reg);
+
+	if (thread_id > nthreads) {
+		ERROR("%s: Invalid thread ID\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Select thread */
+	mmio_write_32(CNF_CMDREG(CMD_STAT_PTR), (uint32_t)thread_id);
+
+	uint32_t err_mask = CNF_ECMD | CNF_EECC | CNF_EDEV | CNF_EDQS | CNF_EFAIL |
+				CNF_EBUS | CNF_EDI | CNF_EPAR | CNF_ECTX | CNF_EPRO;
+
+	do {
+		udelay(CNF_DEF_DELAY_US * 2);
+		reg = mmio_read_32(CNF_CMDREG(CMD_STAT));
+	} while ((reg & CNF_CMPLT) == 0U);
+
+	/* last operation is completed, make sure no other error bits are set */
+	if ((reg & err_mask) == 1U) {
+		ERROR("%s, CMD_STATUS:0x%x\n", __func__, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/* Set feature command */
+int cdns_nand_set_feature(uint8_t feat_addr, uint8_t feat_val, uint8_t thread_id)
+{
+	/* Wait for thread to be ready */
+	cdns_nand_wait_thread_ready(thread_id);
+
+	/* Set feature address */
+	mmio_write_32(CNF_CMDREG(CMD_REG1), (uint32_t)feat_addr);
+	/* Set feature volume */
+	mmio_write_32(CNF_CMDREG(CMD_REG2), (uint32_t)feat_val);
+
+	/* Set feature command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (thread_id << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_CT_SET_FEATURE << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	return cdns_nand_last_opr_status(thread_id);
+}
+
+/* Reset command to the selected device */
+int cdns_nand_reset(uint8_t thread_id)
+{
+	/* Operation is executed in selected thread */
+	cdns_nand_wait_thread_ready(thread_id);
+
+	/* Select memory */
+	mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+
+	/* Issue reset command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (thread_id << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_CT_RESET_ASYNC << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	return cdns_nand_last_opr_status(thread_id);
+}
+
+/* Set operation work mode */
+static void cdns_nand_set_opr_mode(uint8_t opr_mode)
+{
+	/* Wait for controller to be in idle state */
+	cdns_nand_wait_idle();
+
+	/* Reset DLL PHY */
+	uint32_t reg = mmio_read_32(CNF_MINICTRL(DLL_PHY_CTRL));
+
+	reg &= ~(1 << CNF_DLL_PHY_RST_N);
+	mmio_write_32(CNF_MINICTRL(DLL_PHY_CTRL), reg);
+
+	if (opr_mode == CNF_OPR_WORK_MODE_SDR) {
+		/* Combo PHY Control Timing Block register settings */
+		mmio_write_32(CP_CTB(CTRL_REG), CP_CTRL_REG_SDR);
+		mmio_write_32(CP_CTB(TSEL_REG), CP_TSEL_REG_SDR);
+
+		/* Combo PHY DLL register settings */
+		mmio_write_32(CP_DLL(DQ_TIMING_REG), CP_DQ_TIMING_REG_SDR);
+		mmio_write_32(CP_DLL(DQS_TIMING_REG), CP_DQS_TIMING_REG_SDR);
+		mmio_write_32(CP_DLL(GATE_LPBK_CTRL_REG), CP_GATE_LPBK_CTRL_REG_SDR);
+		mmio_write_32(CP_DLL(MASTER_CTRL_REG), CP_DLL_MASTER_CTRL_REG_SDR);
+
+		/* Async mode timing settings */
+		mmio_write_32(CNF_MINICTRL(ASYNC_TOGGLE_TIMINGS),
+								(2 << CNF_ASYNC_TIMINGS_TRH) |
+								(4 << CNF_ASYNC_TIMINGS_TRP) |
+								(2 << CNF_ASYNC_TIMINGS_TWH) |
+								(4 << CNF_ASYNC_TIMINGS_TWP));
+
+		/* Set extended read and write mode */
+		reg |= (1 << CNF_DLL_PHY_EXT_RD_MODE);
+		reg |= (1 << CNF_DLL_PHY_EXT_WR_MODE);
+
+		/* Set operation work mode in common settings */
+		uint32_t data = mmio_read_32(CNF_MINICTRL(CMN_SETTINGS));
+
+		data |= (CNF_OPR_WORK_MODE_SDR << CNF_CMN_SETTINGS_OPR);
+		mmio_write_32(CNF_MINICTRL(CMN_SETTINGS), data);
+
+	} else if (opr_mode == CNF_OPR_WORK_MODE_NVDDR) {
+		; /* ToDo: add DDR mode settings also once available on SIMICS */
+	} else {
+		;
+	}
+
+	reg |= (1 << CNF_DLL_PHY_RST_N);
+	mmio_write_32(CNF_MINICTRL(DLL_PHY_CTRL), reg);
+}
+
+/* Data transfer configuration */
+static void cdns_nand_transfer_config(void)
+{
+	/* Wait for controller to be in idle state */
+	cdns_nand_wait_idle();
+
+	/* Configure data transfer parameters */
+	mmio_write_32(CNF_CTRLCFG(TRANS_CFG0), 1);
+
+	/* ECC is disabled */
+	mmio_write_32(CNF_CTRLCFG(ECC_CFG0), 0);
+
+	/* DMA burst select */
+	mmio_write_32(CNF_CTRLCFG(DMA_SETTINGS),
+					(CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
+					(1 << CNF_DMA_SETTINGS_OTE));
+
+	/* Enable pre-fetching for 1K */
+	mmio_write_32(CNF_CTRLCFG(FIFO_TLEVEL),
+					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
+					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
+
+	/* Select access type */
+	mmio_write_32(CNF_CTRLCFG(MULTIPLANE_CFG), 0);
+	mmio_write_32(CNF_CTRLCFG(CACHE_CFG), 0);
+}
+
+/* Update the nand flash device info */
+static int cdns_nand_update_dev_info(void)
+{
+	uint32_t reg = 0U;
+
+	/* Read the device type and number of LUNs */
+	reg = mmio_read_32(CNF_CTRLPARAM(DEV_PARAMS0));
+	dev_info.type = CNF_GET_DEV_TYPE(reg);
+	if (dev_info.type == CNF_DT_UNKNOWN) {
+		ERROR("%s: device type unknown\n", __func__);
+		return -ENXIO;
+	}
+	dev_info.nluns = CNF_GET_NLUNS(reg);
+
+	/* Pages per block */
+	reg = mmio_read_32(CNF_CTRLCFG(DEV_LAYOUT));
+	dev_info.npages_per_block = CNF_GET_NPAGES_PER_BLOCK(reg);
+
+	/* Sector size and last sector size */
+	reg = mmio_read_32(CNF_CTRLCFG(TRANS_CFG1));
+	dev_info.sector_size = CNF_GET_SCTR_SIZE(reg);
+	dev_info.last_sector_size = CNF_GET_LAST_SCTR_SIZE(reg);
+
+	/* Page size and spare size */
+	reg = mmio_read_32(CNF_CTRLPARAM(DEV_AREA));
+	dev_info.page_size = CNF_GET_PAGE_SIZE(reg);
+	dev_info.spare_size = CNF_GET_SPARE_SIZE(reg);
+
+	/* Device blocks per LUN */
+	dev_info.nblocks_per_lun = mmio_read_32(CNF_CTRLPARAM(DEV_BLOCKS_PLUN));
+
+	/* Calculate block size and total device size */
+	dev_info.block_size = (dev_info.npages_per_block * dev_info.page_size);
+	dev_info.total_size = (dev_info.block_size * dev_info.nblocks_per_lun *
+							dev_info.nluns);
+
+	VERBOSE("CNF params: page %d, spare %d, block %d, total %lld\n",
+				dev_info.page_size, dev_info.spare_size,
+				dev_info.block_size, dev_info.total_size);
+
+	return 0;
+}
+
+/* NAND Flash Controller/Host initialization */
+int cdns_nand_host_init(void)
+{
+	uint32_t reg = 0U;
+	int ret = 0;
+
+	do {
+		/* Read controller status register for init complete */
+		reg = mmio_read_32(CNF_CMDREG(CTRL_STATUS));
+	} while (CNF_GET_INIT_COMP(reg) == 0);
+
+	ret = cdns_nand_update_dev_info();
+	if (ret != 0) {
+		return ret;
+	}
+
+	INFO("CNF: device discovery process completed and device type %d\n",
+			dev_info.type);
+
+	/* Enable data integrity, enable CRC and parity */
+	reg = mmio_read_32(CNF_DI(CONTROL));
+	reg |= (1 << CNF_DI_PAR_EN);
+	reg |= (1 << CNF_DI_CRC_EN);
+	mmio_write_32(CNF_DI(CONTROL), reg);
+
+	/* Status polling mode, device control and status register */
+	cdns_nand_wait_idle();
+	reg = mmio_read_32(CNF_CTRLCFG(DEV_STAT));
+	reg = reg & ~1;
+	mmio_write_32(CNF_CTRLCFG(DEV_STAT), reg);
+
+	/* Set operation work mode */
+	cdns_nand_set_opr_mode(CNF_OPR_WORK_MODE_SDR);
+
+	/* Set data transfer configuration parameters */
+	cdns_nand_transfer_config();
+
+	return 0;
+}
+
+/* erase: Block erase command */
+int cdns_nand_erase(uint32_t offset, uint32_t size)
+{
+	/* Determine the starting block offset i.e row address */
+	uint32_t row_address = dev_info.npages_per_block * offset;
+
+	/* Wait for thread to be in ready state */
+	cdns_nand_wait_thread_ready(CNF_DEF_TRD);
+
+	/*Set row address */
+	mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+
+	/* Operation bank number */
+	mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+
+	/* Block erase command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (CNF_DEF_TRD << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_CT_ERASE << CNF_CMDREG0_CMD);
+	reg |= (((size-1) & 0xFF) << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	/* Wait for erase operation to complete */
+	return cdns_nand_last_opr_status(CNF_DEF_TRD);
+}
+
+/* io mtd functions */
+int cdns_nand_init_mtd(unsigned long long *size, unsigned int *erase_size)
+{
+	*size = dev_info.total_size;
+	*erase_size = dev_info.block_size;
+
+	return 0;
+}
+
+/* NAND Flash page read */
+static int cdns_nand_read_page(uint32_t block, uint32_t page, uintptr_t buffer)
+{
+	/* Wait for thread to be ready */
+	cdns_nand_wait_thread_ready(CNF_DEF_TRD);
+
+	/* Select device */
+	mmio_write_32(CNF_CMDREG(CMD_REG4),
+					(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+
+	/* Set host memory address for DMA transfers */
+	mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & 0xFFFF));
+	mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & 0xFFFF));
+
+	/* Set row address */
+	uint32_t row_address = 0U;
+
+	row_address |= ((page & 0x3F) | (block << 6));
+	mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+
+	/* Page read command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (CNF_DEF_TRD << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_DMA_MASTER_SEL << CNF_CMDREG0_DMA);
+	reg |= (CNF_CT_PAGE_READ << CNF_CMDREG0_CMD);
+	reg |= (((CNF_READ_SINGLE_PAGE-1) & 0xFF) << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	/* Wait for read operation to complete */
+	if (cdns_nand_last_opr_status(CNF_DEF_TRD)) {
+		ERROR("%s: Page read failed\n", __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int cdns_nand_read(unsigned int offset, uintptr_t buffer, size_t length,
+					size_t *out_length)
+{
+	uint32_t block = offset / dev_info.block_size;
+	uint32_t end_block = (offset + length - 1U) / dev_info.block_size;
+	uint32_t page_start = (offset % dev_info.block_size) / dev_info.page_size;
+	uint32_t start_offset = offset % dev_info.page_size;
+	uint32_t nb_pages = dev_info.block_size / dev_info.page_size;
+	uint32_t bytes_read = 0U;
+	uint32_t page = 0U;
+	int result = 0;
+
+	VERBOSE("CNF: block %u-%u, page_start %u, len %zu, offset %u\n",
+				block, end_block, page_start, length, offset);
+
+	if ((offset >= dev_info.total_size) ||
+		(offset + length-1 >= dev_info.total_size) ||
+		(length == 0U)) {
+		ERROR("CNF: Invalid read parameters\n");
+		return -EINVAL;
+	}
+
+	*out_length = 0UL;
+
+	while (block <= end_block) {
+		for (page = page_start; page < nb_pages; page++) {
+			if ((start_offset != 0U) || (length < dev_info.page_size)) {
+				/* Partial page read */
+				result = cdns_nand_read_page(block, page,
+				(uintptr_t)scratch_buff);
+				if (result != 0) {
+					return result;
+				}
+
+				bytes_read = MIN((size_t)(dev_info.page_size - start_offset),
+								length);
+
+				memcpy((uint8_t *)buffer, scratch_buff + start_offset,
+						bytes_read);
+				start_offset = 0U;
+			} else {
+				/* Full page read */
+				result = cdns_nand_read_page(block, page,
+				(uintptr_t)scratch_buff);
+				if (result != 0) {
+					return result;
+				}
+
+				bytes_read = dev_info.page_size;
+				memcpy((uint8_t *)buffer, scratch_buff, bytes_read);
+			}
+
+			length -= bytes_read;
+			buffer += bytes_read;
+			*out_length += bytes_read;
+
+			/* All the bytes have read */
+			if (length == 0U) {
+				break;
+			}
+
+			udelay(CNF_READ_INT_DELAY_US);
+		} /* for */
+
+		page_start = 0U;
+		block++;
+	} /* while */
+
+	return 0;
+}
diff --git a/drivers/io/io_dummy.c b/drivers/io/io_dummy.c
deleted file mode 100644
index 4f0cda6..0000000
--- a/drivers/io/io_dummy.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_dummy.h>
-#include <drivers/io/io_storage.h>
-
-struct file_state {
-	int in_use;
-	size_t size;
-};
-
-static struct file_state current_file = {0};
-
-/* Identify the device type as dummy */
-static io_type_t device_type_dummy(void)
-{
-	return IO_TYPE_DUMMY;
-}
-
-/* Dummy device functions */
-static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
-static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			     io_entity_t *entity);
-static int dummy_block_len(io_entity_t *entity, size_t *length);
-static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
-			     size_t length, size_t *length_read);
-static int dummy_block_close(io_entity_t *entity);
-static int dummy_dev_close(io_dev_info_t *dev_info);
-
-
-static const io_dev_connector_t dummy_dev_connector = {
-	.dev_open = dummy_dev_open
-};
-
-
-static const io_dev_funcs_t dummy_dev_funcs = {
-	.type = device_type_dummy,
-	.open = dummy_block_open,
-	.seek = NULL,
-	.size = dummy_block_len,
-	.read = dummy_block_read,
-	.write = NULL,
-	.close = dummy_block_close,
-	.dev_init = NULL,
-	.dev_close = dummy_dev_close,
-};
-
-
-static const io_dev_info_t dummy_dev_info = {
-	.funcs = &dummy_dev_funcs,
-	.info = (uintptr_t)NULL
-};
-
-
-/* Open a connection to the dummy device */
-static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
-			   io_dev_info_t **dev_info)
-{
-	assert(dev_info != NULL);
-	*dev_info = (io_dev_info_t *)&dummy_dev_info;
-
-	return 0;
-}
-
-
-/* Close a connection to the dummy device */
-static int dummy_dev_close(io_dev_info_t *dev_info)
-{
-	return 0;
-}
-
-
-/* Open a file on the dummy device */
-static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			     io_entity_t *entity)
-{
-	int result;
-	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
-
-	if (current_file.in_use == 0) {
-		assert(block_spec != NULL);
-		assert(entity != NULL);
-
-		current_file.in_use = 1;
-		current_file.size = block_spec->length;
-		entity->info = (uintptr_t)&current_file;
-		result = 0;
-	} else {
-		WARN("A Dummy device is already active. Close first.\n");
-		result = -ENOMEM;
-	}
-
-	return result;
-}
-
-
-/* Return the size of a file on the dummy device */
-static int dummy_block_len(io_entity_t *entity, size_t *length)
-{
-	assert(entity != NULL);
-	assert(length != NULL);
-
-	*length =  ((struct file_state *)entity->info)->size;
-
-	return 0;
-}
-
-
-/* Read data from a file on the dummy device */
-static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
-			     size_t length, size_t *length_read)
-{
-	assert(length_read != NULL);
-
-	*length_read = length;
-
-	return 0;
-}
-
-
-/* Close a file on the dummy device */
-static int dummy_block_close(io_entity_t *entity)
-{
-	assert(entity != NULL);
-
-	entity->info = 0;
-	current_file.in_use = 0;
-
-	return 0;
-}
-
-
-/* Exported functions */
-
-/* Register the dummy driver with the IO abstraction */
-int register_io_dev_dummy(const io_dev_connector_t **dev_con)
-{
-	int result;
-
-	assert(dev_con != NULL);
-
-	result = io_register_device(&dummy_dev_info);
-	if (result == 0)
-		*dev_con = &dummy_dev_connector;
-
-	return result;
-}
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index fa9fe41..e256fa7 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -2053,7 +2053,7 @@
 	mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
 	data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
 	reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
-	/* Confifure SSC amplitude */
+	/* Configure SSC amplitude */
 	mask = HPIPE_G2_TX_SSC_AMP_MASK;
 	data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
 	reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
diff --git a/drivers/marvell/gwin.c b/drivers/marvell/gwin.c
index fa59cb0..40f8c93 100644
--- a/drivers/marvell/gwin.c
+++ b/drivers/marvell/gwin.c
@@ -213,7 +213,7 @@
 	 * remote AP should be accompanied with proper configuration to
 	 * GWIN registers group and therefore the GWIN Miss feature
 	 * should be set into Bypass mode, need to make sure all GWIN regions
-	 * are defined correctly that will assure no GWIN miss occurrance
+	 * are defined correctly that will assure no GWIN miss occurrence
 	 * JIRA-AURORA2-1630
 	 */
 	INFO("Update GWIN miss bypass\n");
diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c
index 98e1896..9352437 100644
--- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c
+++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c
@@ -55,7 +55,7 @@
 
 	/* Don't release MG CM3 from reset - it will be done by next step
 	 * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which
-	 * has enabeld 802.3. auto-neg) will be choosen.
+	 * has enabeld 802.3. auto-neg) will be chosen.
 	 */
 
 	return 0;
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c
index cf545a7..1b2f177 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rss/rss_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,23 +32,10 @@
 #  error Invalid Measured Boot algorithm.
 #endif /* MBOOT_ALG_ID */
 
-/* Pointer to struct rss_mboot_metadata */
-static struct rss_mboot_metadata *plat_metadata_ptr;
-
 /* Functions' declarations */
-void rss_measured_boot_init(void)
+void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr)
 {
-	/* At this point it is expected that communication channel over MHU
-	 * is already initialised by platform init.
-	 */
-	struct rss_mboot_metadata *metadata_ptr;
-
-	/* Get pointer to platform's struct rss_mboot_metadata structure */
-	plat_metadata_ptr = plat_rss_mboot_get_metadata();
-	assert(plat_metadata_ptr != NULL);
-
-	/* Use a local variable to preserve the value of the global pointer */
-	metadata_ptr = plat_metadata_ptr;
+	assert(metadata_ptr != NULL);
 
 	/* Init the non-const members of the metadata structure */
 	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
@@ -58,13 +45,15 @@
 	}
 }
 
-int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
+int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
+				 uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id)
 {
 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
 	int rc;
 	psa_status_t ret;
-	const struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
+
+	assert(metadata_ptr != NULL);
 
 	/* Get the metadata associated with this image. */
 	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
@@ -103,14 +92,16 @@
 	return 0;
 }
 
-int rss_mboot_set_signer_id(unsigned int img_id,
+int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+			    unsigned int img_id,
 			    const void *pk_ptr,
 			    size_t pk_len)
 {
 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
-	struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
 	int rc;
 
+	assert(metadata_ptr != NULL);
+
 	/* Get the metadata associated with this image. */
 	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
 		(metadata_ptr->id != img_id)) {
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 2b727d4..57f4748 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -452,11 +452,6 @@
 	int ret, n;
 	unsigned int resp_data[4];
 
-	ret = mmc_reset_to_idle();
-	if (ret != 0) {
-		return ret;
-	}
-
 	for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
 		ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
 				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
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/nxp/crypto/caam/src/auth/hash.c b/drivers/nxp/crypto/caam/src/auth/hash.c
index 1665df1..0f3cf95 100644
--- a/drivers/nxp/crypto/caam/src/auth/hash.c
+++ b/drivers/nxp/crypto/caam/src/auth/hash.c
@@ -106,7 +106,7 @@
  * Function	: hash_final
  * Arguments	: ctx - SHA context
  * Return	: SUCCESS or FAILURE
- * Description	: This function sets the final bit and enqueues the decriptor
+ * Description	: This function sets the final bit and enqueues the descriptor
  ***************************************************************************/
 int hash_final(enum hash_algo algo, void *context, void *hash_ptr,
 	       unsigned int hash_len)
diff --git a/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c b/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c
index 646e981..408d974 100644
--- a/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c
+++ b/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c
@@ -120,4 +120,4 @@
 /*
  * Register crypto library descriptor
  */
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, NULL, NULL);
diff --git a/drivers/nxp/crypto/caam/src/hw_key_blob.c b/drivers/nxp/crypto/caam/src/hw_key_blob.c
index 0720695..6bcb6ba 100644
--- a/drivers/nxp/crypto/caam/src/hw_key_blob.c
+++ b/drivers/nxp/crypto/caam/src/hw_key_blob.c
@@ -18,7 +18,7 @@
 #include "sec_hw_specific.h"
 
 
-/* Callback function after Instantiation decsriptor is submitted to SEC
+/* Callback function after Instantiation descriptor is submitted to SEC
  */
 static void blob_done(uint32_t *desc, uint32_t status, void *arg,
 		      void *job_ring)
diff --git a/drivers/nxp/crypto/caam/src/rng.c b/drivers/nxp/crypto/caam/src/rng.c
index 0b9d87d..58430db 100644
--- a/drivers/nxp/crypto/caam/src/rng.c
+++ b/drivers/nxp/crypto/caam/src/rng.c
@@ -17,7 +17,7 @@
 #include "sec_hw_specific.h"
 
 
-/* Callback function after Instantiation decsriptor is submitted to SEC */
+/* Callback function after Instantiation descriptor is submitted to SEC */
 static void rng_done(uint32_t *desc, uint32_t status, void *arg,
 		     void *job_ring)
 {
@@ -183,7 +183,7 @@
 		/*if instantiate_rng(...) fails, the loop will rerun
 		 *and the kick_trng(...) function will modify the
 		 *upper and lower limits of the entropy sampling
-		 *interval, leading to a sucessful initialization of
+		 *interval, leading to a successful initialization of
 		 */
 		ret = instantiate_rng();
 	} while ((ret == -1) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
index faf20e9..17c2bbb 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
@@ -293,7 +293,7 @@
 	}
 
 	if (pdodt == NULL) {
-		ERROR("Error determing ODT.\n");
+		ERROR("Error determining ODT.\n");
 		return -EINVAL;
 	}
 
@@ -916,7 +916,7 @@
 	debug("Program controller registers\n");
 	ret = write_ddrc_regs(priv);
 	if (ret != 0) {
-		ERROR("Programing DDRC error\n");
+		ERROR("Programming DDRC error\n");
 		return ret;
 	}
 
diff --git a/drivers/nxp/ddr/nxp-ddr/ddrc.c b/drivers/nxp/ddr/nxp-ddr/ddrc.c
index 17a2b6a..4133fac 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddrc.c
+++ b/drivers/nxp/ddr/nxp-ddr/ddrc.c
@@ -346,7 +346,7 @@
 
 #ifdef ERRATA_DDR_A008511
 	/* Part 1 of 2 */
-	/* This erraum only applies to verion 5.2.1 */
+	/* This erraum only applies to version 5.2.1 */
 	if (get_ddrc_version(ddr) == 0x50200) {
 		ERROR("Unsupported SoC.\n");
 	} else if (get_ddrc_version(ddr) == 0x50201) {
diff --git a/drivers/nxp/ddr/phy-gen2/messages.h b/drivers/nxp/ddr/phy-gen2/messages.h
index a2310f2..bf2d459 100644
--- a/drivers/nxp/ddr/phy-gen2/messages.h
+++ b/drivers/nxp/ddr/phy-gen2/messages.h
@@ -144,7 +144,7 @@
 	 "PMU3: Precharge all open banks\n"
 	},
 	{0x002b0002,
-	 "PMU: Error: Dbyte %d nibble %d found mutliple working coarse delay setting for MRD/MWD\n"
+	 "PMU: Error: Dbyte %d nibble %d found multiple working coarse delay setting for MRD/MWD\n"
 	},
 	{0x002c0000,
 	 "PMU4: MRD Passing Regions (coarseVal, fineLeft fineRight -> fineCenter)\n"
@@ -536,7 +536,7 @@
 	 "PMU3: Resetting DRAM\n"
 	},
 	{0x00b10000,
-	 "PMU3: setup for RCD initalization\n"
+	 "PMU3: setup for RCD initialization\n"
 	},
 	{0x00b20000,
 	 "PMU3: pmu_exit_SR from dev_init()\n"
@@ -974,10 +974,10 @@
 	 "PMU0: PHY VREF @ (%d/1000) VDDQ\n"
 	},
 	{0x01430002,
-	 "PMU0: initalizing phy vrefDacs to %d ExtVrefRange %x\n"
+	 "PMU0: initializing phy vrefDacs to %d ExtVrefRange %x\n"
 	},
 	{0x01440002,
-	 "PMU0: initalizing global vref to %d range %d\n"
+	 "PMU0: initializing global vref to %d range %d\n"
 	},
 	{0x01450002,
 	 "PMU4: Setting initial device vrefDQ for CS%d to MR6 = 0x%04x\n"
@@ -1811,7 +1811,7 @@
 	 "PMU3: Precharge all open banks\n"
 	},
 	{0x00be0002,
-	 "PMU: Error: Dbyte %d nibble %d found mutliple working coarse delay setting for MRD/MWD\n"
+	 "PMU: Error: Dbyte %d nibble %d found multiple working coarse delay setting for MRD/MWD\n"
 	},
 	{0x00bf0000,
 	 "PMU4: MRD Passing Regions (coarseVal, fineLeft fineRight -> fineCenter)\n"
@@ -2203,7 +2203,7 @@
 	 "PMU3: Resetting DRAM\n"
 	},
 	{0x01440000,
-	 "PMU3: setup for RCD initalization\n"
+	 "PMU3: setup for RCD initialization\n"
 	},
 	{0x01450000,
 	 "PMU3: pmu_exit_SR from dev_init()\n"
@@ -2641,10 +2641,10 @@
 	 "PMU0: PHY VREF @ (%d/1000) VDDQ\n"
 	},
 	{0x01d60002,
-	 "PMU0: initalizing phy vrefDacs to %d ExtVrefRange %x\n"
+	 "PMU0: initializing phy vrefDacs to %d ExtVrefRange %x\n"
 	},
 	{0x01d70002,
-	 "PMU0: initalizing global vref to %d range %d\n"
+	 "PMU0: initializing global vref to %d range %d\n"
 	},
 	{0x01d80002,
 	 "PMU4: Setting initial device vrefDQ for CS%d to MR6 = 0x%04x\n"
diff --git a/drivers/nxp/ifc/nand/ifc_nand.c b/drivers/nxp/ifc/nand/ifc_nand.c
index 1f7092a..df7ec85 100644
--- a/drivers/nxp/ifc/nand/ifc_nand.c
+++ b/drivers/nxp/ifc/nand/ifc_nand.c
@@ -531,7 +531,7 @@
 		return 0;
 
 	/* special case for lgb == 0 */
-	/* if blk <= lgb retrun */
+	/* if blk <= lgb return */
 	if (nand->lgb != 0 && blk <= nand->lgb)
 		return 0;
 
diff --git a/drivers/nxp/sd/sd_mmc.c b/drivers/nxp/sd/sd_mmc.c
index f7f48e7..48b27c1 100644
--- a/drivers/nxp/sd/sd_mmc.c
+++ b/drivers/nxp/sd/sd_mmc.c
@@ -344,7 +344,7 @@
  * Function    :    mmc_switch_to_high_frquency
  * Arguments   :    mmc - Pointer to mmc struct
  * Return      :    SUCCESS or Error Code
- * Description :    mmc card bellow ver 4.0 does not support high speed
+ * Description :    mmc card below ver 4.0 does not support high speed
  *                  freq = 20 MHz
  *                  Send CMD6 (CMD_SWITCH_FUNC) With args 0x03B90100
  *                  Send CMD13 (CMD_SEND_STATUS)
@@ -358,7 +358,7 @@
 	uint64_t start_time;
 
 	mmc->card.bus_freq = MMC_SS_20MHZ;
-	/* mmc card bellow ver 4.0 does not support high speed */
+	/* mmc card below ver 4.0 does not support high speed */
 	if (mmc->card.version < MMC_CARD_VERSION_4_X) {
 		return 0;
 	}
@@ -463,7 +463,7 @@
 /***************************************************************************
  * Function    :    esdhc_read_data_nodma
  * Arguments   :    mmc - Pointer to mmc struct
- *                  dest_ptr - Bufffer where read data is to be copied
+ *                  dest_ptr - Buffer where read data is to be copied
  *                  len - Length of Data to be read
  * Return      :    SUCCESS or Error Code
  * Description :    Read data from the sdhc buffer without using DMA
@@ -698,7 +698,7 @@
 /***************************************************************************
  * Function    :    esdhc_read_data
  * Arguments   :    mmc - Pointer to mmc struct
- *                  dest_ptr - Bufffer where read data is to be copied
+ *                  dest_ptr - Buffer where read data is to be copied
  *                  len - Length of Data to be read
  * Return      :    SUCCESS or Error Code
  * Description :    Calls esdhc_read_data_nodma and clear interrupt status
diff --git a/drivers/nxp/trdc/imx_trdc.c b/drivers/nxp/trdc/imx_trdc.c
new file mode 100644
index 0000000..ab66585
--- /dev/null
+++ b/drivers/nxp/trdc/imx_trdc.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/nxp/trdc/imx_trdc.h>
+#include <lib/mmio.h>
+
+
+int trdc_mda_set_cpu(uintptr_t trdc_base, uint32_t mda_inst,
+		     uint32_t mda_reg, uint8_t sa, uint8_t dids,
+		     uint8_t did, uint8_t pe, uint8_t pidm, uint8_t pid)
+{
+	uint32_t val = mmio_read_32(trdc_base + MDAC_W_X(mda_inst, mda_reg));
+	/* invalid: config non-cpu master with cpu config format. */
+	if ((val & MDA_DFMT) != 0U) {
+		return -EINVAL;
+	}
+
+	val = MDA_VLD | MDA_DFMT0_DID(pid) | MDA_DFMT0_PIDM(pidm) | MDA_DFMT0_PE(pe) |
+	      MDA_DFMT0_SA(sa) | MDA_DFMT0_DIDS(dids) | MDA_DFMT0_DID(did);
+
+	mmio_write_32(trdc_base + MDAC_W_X(mda_inst, mda_reg), val);
+
+	return 0;
+}
+
+int trdc_mda_set_noncpu(uintptr_t trdc_base, uint32_t mda_inst,
+			bool did_bypass, uint8_t sa, uint8_t pa,
+			uint8_t did)
+{
+	uint32_t val = mmio_read_32(trdc_base + MDAC_W_X(mda_inst, 0));
+
+	/* invalid: config cpu master with non-cpu config format. */
+	if ((val & MDA_DFMT) == 0U) {
+		return -EINVAL;
+	}
+
+	val = MDA_VLD | MDA_DFMT1_SA(sa) | MDA_DFMT1_PA(pa) | MDA_DFMT1_DID(did) |
+	      MDA_DFMT1_DIDB(did_bypass ? 1U : 0U);
+
+	mmio_write_32(trdc_base + MDAC_W_X(mda_inst, 0), val);
+
+	return 0;
+}
+
+static uintptr_t trdc_get_mbc_base(uintptr_t trdc_reg, uint32_t mbc_x)
+{
+	struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
+	uint32_t mbc_num = MBC_NUM(trdc_base->trdc_hwcfg0);
+
+	if (mbc_x >= mbc_num) {
+		return 0U;
+	}
+
+	return trdc_reg + 0x10000 + 0x2000 * mbc_x;
+}
+
+static uintptr_t trdc_get_mrc_base(uintptr_t trdc_reg, uint32_t mrc_x)
+{
+	struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
+	uint32_t mbc_num = MBC_NUM(trdc_base->trdc_hwcfg0);
+	uint32_t mrc_num = MRC_NUM(trdc_base->trdc_hwcfg0);
+
+	if (mrc_x >= mrc_num) {
+		return 0U;
+	}
+
+	return trdc_reg + 0x10000 + 0x2000 * mbc_num + 0x1000 * mrc_x;
+}
+
+uint32_t trdc_mbc_blk_num(uintptr_t trdc_reg, uint32_t mbc_x, uint32_t mem_x)
+{
+	uint32_t glbcfg;
+	struct mbc_mem_dom *mbc_dom;
+	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
+
+	if (mbc_base == NULL) {
+		return 0;
+	}
+
+	/* only first dom has the glbcfg */
+	mbc_dom = &mbc_base->mem_dom[0];
+	glbcfg = mmio_read_32((uintptr_t)&mbc_dom->mem_glbcfg[mem_x]);
+
+	return MBC_BLK_NUM(glbcfg);
+}
+
+uint32_t trdc_mrc_rgn_num(uintptr_t trdc_reg, uint32_t mrc_x)
+{
+	uint32_t glbcfg;
+	struct mrc_rgn_dom *mrc_dom;
+	struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
+
+	if (mrc_base == NULL) {
+		return 0;
+	}
+
+	/* only first dom has the glbcfg */
+	mrc_dom = &mrc_base->mrc_dom[0];
+	glbcfg = mmio_read_32((uintptr_t)&mrc_dom->mrc_glbcfg[0]);
+
+	return MBC_BLK_NUM(glbcfg);
+}
+
+int trdc_mbc_set_control(uintptr_t trdc_reg, uint32_t mbc_x,
+			 uint32_t glbac_id, uint32_t glbac_val)
+{
+	struct mbc_mem_dom *mbc_dom;
+	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
+
+	if (mbc_base == NULL || glbac_id >= GLBAC_NUM) {
+		return -EINVAL;
+	}
+
+	/* only first dom has the glbac */
+	mbc_dom = &mbc_base->mem_dom[0];
+
+	mmio_write_32((uintptr_t)&mbc_dom->memn_glbac[glbac_id], glbac_val);
+
+	return 0;
+}
+
+int trdc_mbc_blk_config(uintptr_t trdc_reg, uint32_t mbc_x,
+			uint32_t dom_x, uint32_t mem_x, uint32_t blk_x,
+			bool sec_access, uint32_t glbac_id)
+{
+	uint32_t *cfg_w;
+	uint32_t index, offset, val;
+	struct mbc_mem_dom *mbc_dom;
+	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
+
+	if (mbc_base == NULL || glbac_id >= GLBAC_NUM) {
+		return -EINVAL;
+	}
+
+	mbc_dom = &mbc_base->mem_dom[dom_x];
+
+	switch (mem_x) {
+	case 0:
+		cfg_w = &mbc_dom->mem0_blk_cfg_w[blk_x / 8];
+		break;
+	case 1:
+		cfg_w = &mbc_dom->mem1_blk_cfg_w[blk_x / 8];
+		break;
+	case 2:
+		cfg_w = &mbc_dom->mem2_blk_cfg_w[blk_x / 8];
+		break;
+	case 3:
+		cfg_w = &mbc_dom->mem3_blk_cfg_w[blk_x / 8];
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	index = blk_x % 8;
+	offset = index * 4;
+
+	val = mmio_read_32((uintptr_t)cfg_w);
+	val &= ~(0xF << offset);
+
+	/*
+	 * MBC0-3
+	 * Global 0, 0x7777 secure pri/user read/write/execute,
+	 * S400 has already set it. So select MBC0_MEMN_GLBAC0
+	 */
+	if (sec_access) {
+		val |= ((0x0 | (glbac_id & 0x7)) << offset);
+		mmio_write_32((uintptr_t)cfg_w, val);
+	} else {
+		/* nse bit set */
+		val |= ((0x8 | (glbac_id & 0x7)) << offset);
+		mmio_write_32((uintptr_t)cfg_w, val);
+	}
+
+	return 0;
+}
+
+int trdc_mrc_set_control(uintptr_t trdc_reg, uint32_t mrc_x,
+			 uint32_t glbac_id, uint32_t glbac_val)
+{
+	struct mrc_rgn_dom *mrc_dom;
+	struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
+
+	if (mrc_base == NULL || glbac_id >= GLBAC_NUM) {
+		return -EINVAL;
+	}
+
+	/* only first dom has the glbac */
+	mrc_dom = &mrc_base->mrc_dom[0];
+
+	mmio_write_32((uintptr_t)&mrc_dom->memn_glbac[glbac_id], glbac_val);
+
+	return 0;
+}
+
+int trdc_mrc_rgn_config(uintptr_t trdc_reg, uint32_t mrc_x,
+			uint32_t dom_x, uint32_t rgn_id,
+			uint32_t addr_start, uint32_t addr_size,
+			bool sec_access, uint32_t glbac_id)
+{
+	uint32_t *desc_w;
+	uint32_t addr_end;
+	struct mrc_rgn_dom *mrc_dom;
+	struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
+
+	if (mrc_base == NULL || glbac_id >= GLBAC_NUM || rgn_id >= MRC_REG_ALL) {
+		return -EINVAL;
+	}
+
+	mrc_dom = &mrc_base->mrc_dom[dom_x];
+
+	addr_end = addr_start + addr_size - 1;
+	addr_start &= ~0x3fff;
+	addr_end &= ~0x3fff;
+
+	desc_w = &mrc_dom->rgn_desc_words[rgn_id][0];
+
+	if (sec_access) {
+		mmio_write_32((uintptr_t)desc_w, addr_start | (glbac_id & 0x7));
+		mmio_write_32((uintptr_t)(desc_w + 1), addr_end | 0x1);
+	} else {
+		mmio_write_32((uintptr_t)desc_w, addr_start | (glbac_id & 0x7));
+		mmio_write_32((uintptr_t)(desc_w + 1), (addr_end | 0x1 | 0x10));
+	}
+
+	return 0;
+}
+
+bool trdc_mrc_enabled(uintptr_t mrc_base)
+{
+	return (mmio_read_32(mrc_base) & BIT(15));
+}
+
+bool trdc_mbc_enabled(uintptr_t mbc_base)
+{
+	return (mmio_read_32(mbc_base) & BIT(14));
+}
+
+static bool is_trdc_mgr_slot(uintptr_t trdc_base, uint8_t mbc_id,
+			     uint8_t mem_id, uint16_t blk_id)
+{
+	unsigned int i;
+
+	for (i = 0U; i < trdc_mgr_num; i++) {
+		if (trdc_mgr_blks[i].trdc_base == trdc_base) {
+			if (mbc_id == trdc_mgr_blks[i].mbc_id &&
+			    mem_id == trdc_mgr_blks[i].mbc_mem_id &&
+			   (blk_id == trdc_mgr_blks[i].blk_mgr ||
+			    blk_id == trdc_mgr_blks[i].blk_mc)) {
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+/*
+ * config the TRDC MGR & MC's access policy. only the secure privilege
+ * mode SW can access it.
+ */
+void trdc_mgr_mbc_setup(struct trdc_mgr_info *mgr)
+{
+	unsigned int i;
+
+	/*
+	 * If the MBC is global enabled, need to cconfigure the MBCs of
+	 * TRDC MGR & MC correctly.
+	 */
+	if (trdc_mbc_enabled(mgr->trdc_base)) {
+		/* ONLY secure privilige can access */
+		trdc_mbc_set_control(mgr->trdc_base, mgr->mbc_id, 7, 0x6000);
+		for (i = 0U; i < 16U; i++) {
+			trdc_mbc_blk_config(mgr->trdc_base, mgr->mbc_id, i,
+				mgr->mbc_mem_id, mgr->blk_mgr, true, 7);
+
+			trdc_mbc_blk_config(mgr->trdc_base, mgr->mbc_id, i,
+				mgr->mbc_mem_id, mgr->blk_mc, true, 7);
+		}
+	}
+}
+
+/*
+ * Set up the TRDC access policy for all the resources under
+ * the TRDC control.
+ */
+void trdc_setup(struct trdc_config_info *cfg)
+{
+	unsigned int i, j, num;
+	bool is_mgr;
+
+	/* config the MRCs */
+	if (trdc_mrc_enabled(cfg->trdc_base)) {
+		/* set global access policy */
+		for (i = 0U; i < cfg->num_mrc_glbac; i++) {
+			trdc_mrc_set_control(cfg->trdc_base,
+					     cfg->mrc_glbac[i].mbc_mrc_id,
+					     cfg->mrc_glbac[i].glbac_id,
+					     cfg->mrc_glbac[i].glbac_val);
+		}
+
+		/* set each MRC region access policy */
+		for (i = 0U; i < cfg->num_mrc_cfg; i++) {
+			trdc_mrc_rgn_config(cfg->trdc_base, cfg->mrc_cfg[i].mrc_id,
+					    cfg->mrc_cfg[i].dom_id,
+					    cfg->mrc_cfg[i].region_id,
+					    cfg->mrc_cfg[i].region_start,
+					    cfg->mrc_cfg[i].region_size,
+					    cfg->mrc_cfg[i].secure,
+					    cfg->mrc_cfg[i].glbac_id);
+		}
+	}
+
+	/* config the MBCs */
+	if (trdc_mbc_enabled(cfg->trdc_base)) {
+		/* set MBC global access policy */
+		for (i = 0U; i < cfg->num_mbc_glbac; i++) {
+			trdc_mbc_set_control(cfg->trdc_base,
+					     cfg->mbc_glbac[i].mbc_mrc_id,
+					     cfg->mbc_glbac[i].glbac_id,
+					     cfg->mbc_glbac[i].glbac_val);
+		}
+
+		for (i = 0U; i < cfg->num_mbc_cfg; i++) {
+			if (cfg->mbc_cfg[i].blk_id == MBC_BLK_ALL) {
+				num = trdc_mbc_blk_num(cfg->trdc_base,
+						       cfg->mbc_cfg[i].mbc_id,
+						       cfg->mbc_cfg[i].mem_id);
+
+				for (j = 0U; j < num; j++) {
+					/* Skip mgr and mc */
+					is_mgr = is_trdc_mgr_slot(cfg->trdc_base,
+								  cfg->mbc_cfg[i].mbc_id,
+								  cfg->mbc_cfg[i].mem_id, j);
+					if (is_mgr) {
+						continue;
+					}
+
+					trdc_mbc_blk_config(cfg->trdc_base,
+							    cfg->mbc_cfg[i].mbc_id,
+							    cfg->mbc_cfg[i].dom_id,
+							    cfg->mbc_cfg[i].mem_id, j,
+							    cfg->mbc_cfg[i].secure,
+							    cfg->mbc_cfg[i].glbac_id);
+				}
+			} else {
+				trdc_mbc_blk_config(cfg->trdc_base,
+						    cfg->mbc_cfg[i].mbc_id,
+						    cfg->mbc_cfg[i].dom_id,
+						    cfg->mbc_cfg[i].mem_id,
+						    cfg->mbc_cfg[i].blk_id,
+						    cfg->mbc_cfg[i].secure,
+						    cfg->mbc_cfg[i].glbac_id);
+			}
+		}
+	}
+}
diff --git a/drivers/renesas/common/console/rcar_printf.c b/drivers/renesas/common/console/rcar_printf.c
index ad074fe..6af10ee 100644
--- a/drivers/renesas/common/console/rcar_printf.c
+++ b/drivers/renesas/common/console/rcar_printf.c
@@ -24,7 +24,7 @@
 /*
  * The log is initialized and used before BL31 xlat tables are initialized,
  * therefore the log memory is a device memory at that point. Make sure the
- * memory is correclty aligned and accessed only with up-to 32bit, aligned,
+ * memory is correctly aligned and accessed only with up-to 32bit, aligned,
  * writes.
  */
 CASSERT((RCAR_BL31_LOG_BASE & 0x7) == 0, assert_bl31_log_base_unaligned);
diff --git a/drivers/renesas/common/emmc/emmc_hal.h b/drivers/renesas/common/emmc/emmc_hal.h
index 0a85517..4e6942f 100644
--- a/drivers/renesas/common/emmc/emmc_hal.h
+++ b/drivers/renesas/common/emmc/emmc_hal.h
@@ -512,7 +512,7 @@
 	/* maximum block count which can be transferred at once */
 	uint32_t max_block_count;
 
-	/* maximum clock frequence in Hz supported by HW */
+	/* maximum clock frequency in Hz supported by HW */
 	uint32_t max_clock_freq;
 
 	/* maximum data bus width supported by HW */
diff --git a/drivers/renesas/common/pfc_regs.h b/drivers/renesas/common/pfc_regs.h
index 4187733..36084f5 100644
--- a/drivers/renesas/common/pfc_regs.h
+++ b/drivers/renesas/common/pfc_regs.h
@@ -146,10 +146,10 @@
 #define GPIO_OUTDTL7		(GPIO_BASE + 0x5848U)
 #define GPIO_BOTHEDGE7		(GPIO_BASE + 0x584CU)
 
-/* Pin functon base address */
+/* Pin function base address */
 #define PFC_BASE		(0xE6060000U)
 
-/* Pin functon registers */
+/* Pin function registers */
 #define PFC_PMMR		(PFC_BASE + 0x0000U)
 #define PFC_GPSR0		(PFC_BASE + 0x0100U)
 #define PFC_GPSR1		(PFC_BASE + 0x0104U)
diff --git a/drivers/renesas/rcar/pfc/V3M/pfc_init_v3m.c b/drivers/renesas/rcar/pfc/V3M/pfc_init_v3m.c
index 6063758..5de4f1f 100644
--- a/drivers/renesas/rcar/pfc/V3M/pfc_init_v3m.c
+++ b/drivers/renesas/rcar/pfc/V3M/pfc_init_v3m.c
@@ -12,7 +12,7 @@
 #include "rcar_private.h"
 #include "../pfc_regs.h"
 
-/* Pin functon bit */
+/* Pin function bit */
 #define GPSR0_DU_EXODDF_DU_ODDF_DISP_CDE	BIT(21)
 #define GPSR0_DU_EXVSYNC_DU_VSYNC		BIT(20)
 #define GPSR0_DU_EXHSYNC_DU_HSYNC		BIT(19)
diff --git a/drivers/rpi3/sdhost/rpi3_sdhost.c b/drivers/rpi3/sdhost/rpi3_sdhost.c
index c4b6fca..90c8509 100644
--- a/drivers/rpi3/sdhost/rpi3_sdhost.c
+++ b/drivers/rpi3/sdhost/rpi3_sdhost.c
@@ -245,13 +245,12 @@
 
 static void rpi3_sdhost_initialize(void)
 {
-	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
-
 	assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);
 
 	rpi3_sdhost_reset();
 
-	mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_PREFERVAL);
+	rpi3_sdhost_set_ios(rpi3_sdhost_params.clk_rate_initial,
+		rpi3_sdhost_params.bus_width);
 	udelay(300);
 }
 
diff --git a/drivers/scmi-msg/base.c b/drivers/scmi-msg/base.c
index 2db4d7e..52502a5 100644
--- a/drivers/scmi-msg/base.c
+++ b/drivers/scmi-msg/base.c
@@ -151,7 +151,8 @@
 	count = count_protocols_in_list(list);
 
 	if (count > a2p->skip) {
-		count = MIN(count - a2p->skip, msg->out_size - sizeof(p2a));
+		count = MIN((uint32_t)(count - a2p->skip),
+			    (uint32_t)(msg->out_size - sizeof(p2a)));
 	} else {
 		count = 0U;
 	}
diff --git a/drivers/scmi-msg/clock.c b/drivers/scmi-msg/clock.c
index 85bf7d2..98fdc6a 100644
--- a/drivers/scmi-msg/clock.c
+++ b/drivers/scmi-msg/clock.c
@@ -344,7 +344,7 @@
 		scmi_status_response(msg, status);
 	} else {
 		/*
-		 * Message payload is already writen to msg->out, and
+		 * Message payload is already written to msg->out, and
 		 * msg->out_size_out updated.
 		 */
 	}
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/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index aa5db6f..c9c3c5f 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -2049,7 +2049,7 @@
 
 		stm32mp1_pll_start(i);
 	}
-	/* Wait and start PLLs ouptut when ready */
+	/* Wait and start PLLs output when ready */
 	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
 		if (!pllcfg_valid[i]) {
 			continue;
diff --git a/drivers/st/crypto/stm32_pka.c b/drivers/st/crypto/stm32_pka.c
index 2bbb31d..9124cf2 100644
--- a/drivers/st/crypto/stm32_pka.c
+++ b/drivers/st/crypto/stm32_pka.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +19,11 @@
 
 #include <platform_def.h>
 
+#if !PKA_USE_NIST_P256 && !PKA_USE_BRAINPOOL_P256R1 && !PKA_USE_BRAINPOOL_P256T1 && \
+	!PKA_USE_NIST_P521
+#error "At least one ECDSA curve needs to be selected"
+#endif
+
 /*
  * For our comprehension in this file
  *  _len are in BITs
@@ -28,10 +33,10 @@
 
 #define UINT8_LEN			8U
 #define UINT64_LEN			(UINT8_LEN * sizeof(uint64_t))
-#define WORD_SIZE			(sizeof(uint64_t))
+#define PKA_WORD_SIZE			(sizeof(uint64_t))
 #define OP_NBW_FROM_LEN(len)		(DIV_ROUND_UP_2EVAL((len), UINT64_LEN) + 1)
 #define OP_NBW_FROM_SIZE(s)		OP_NBW_FROM_LEN((s) * UINT8_LEN)
-#define OP_SIZE_FROM_SIZE(s)		(OP_NBW_FROM_SIZE(s) * WORD_SIZE)
+#define OP_SIZE_FROM_SIZE(s)		(OP_NBW_FROM_SIZE(s) * PKA_WORD_SIZE)
 
 #define DT_PKA_COMPAT			"st,stm32-pka64"
 
@@ -690,7 +695,7 @@
 	mmio_setbits_32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
 
 out:
-	/* Disable PKA (will stop all pending proccess and reset RAM) */
+	/* Disable PKA (will stop all pending process and reset RAM) */
 	pka_disable(base);
 
 	return ret;
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
index 4719e1e..27d8b2c 100644
--- a/drivers/st/ddr/stm32mp1_ddr.c
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -755,7 +755,7 @@
 	stm32mp1_ddrphy_idone_wait(priv->phy);
 
 	/*
-	 * 12. set back registers in step 8 to the orginal values if desidered
+	 * 12. set back registers in step 8 to the original values if desidered
 	 */
 	stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
 				 config->c_reg.pwrctl);
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index e3e0e67..e063941 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]
+	tst	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/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index ea82d02..b8137c2 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -161,14 +161,22 @@
 int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd)
 {
 	unsigned int data;
-	int result;
+	int result, retries;
 
 	if (base == 0 || cmd == NULL)
 		return -EINVAL;
 
-	data = mmio_read_32(base + HCS);
-	if ((data & HCS_UCRDY) == 0)
+	for (retries = 0; retries < 100; retries++) {
+		data = mmio_read_32(base + HCS);
+		if ((data & HCS_UCRDY) != 0) {
+			break;
+		}
+		mdelay(1);
+	}
+	if (retries >= 100) {
 		return -EBUSY;
+	}
+
 	mmio_write_32(base + IS, ~0);
 	mmio_write_32(base + UCMDARG1, cmd->arg1);
 	mmio_write_32(base + UCMDARG2, cmd->arg2);
@@ -187,7 +195,6 @@
 int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val)
 {
 	uintptr_t base;
-	unsigned int data;
 	int result, retries;
 	uic_cmd_t cmd;
 
@@ -197,19 +204,11 @@
 		return -EINVAL;
 
 	base = ufs_params.reg_base;
-	for (retries = 0; retries < 100; retries++) {
-		data = mmio_read_32(base + HCS);
-		if ((data & HCS_UCRDY) != 0)
-			break;
-		mdelay(1);
-	}
-	if (retries >= 100)
-		return -EBUSY;
-
 	cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);
 	cmd.arg2 = 0;
 	cmd.arg3 = 0;
 	cmd.op = DME_GET;
+
 	for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {
 		result = ufshc_send_uic_cmd(base, &cmd);
 		if (result == 0)
diff --git a/fdts/juno-ethosn.dtsi b/fdts/juno-ethosn.dtsi
index 4609524..6f8e8ae 100644
--- a/fdts/juno-ethosn.dtsi
+++ b/fdts/juno-ethosn.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,28 +48,253 @@
 			 };
 		 };
 
-		 asset_allocator {
+		 asset_allocator0 {
 			 compatible = "ethosn-asset_allocator";
 			 status = "okay";
 
 			 command_stream {
 				 compatible = "ethosn-memory";
-				 iommus = <&smmu_ethosn0 2>;
+				 iommus = <&smmu_ethosn0 4>;
 			 };
 
 			 weight_data {
 				 compatible = "ethosn-memory";
-				 iommus = <&smmu_ethosn0 3>;
+				 iommus = <&smmu_ethosn0 5>;
 			 };
 
 			 buffer_data {
 				 compatible = "ethosn-memory";
-				 iommus = <&smmu_ethosn0 4>;
+				 iommus = <&smmu_ethosn0 6>;
 			 };
 
 			 intermediate_data {
 				 compatible = "ethosn-memory";
-				 iommus = <&smmu_ethosn0 5>;
+				 iommus = <&smmu_ethosn0 7>;
+			 };
+		 };
+
+		 asset_allocator1 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 8>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 9>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 10>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 11>;
+			 };
+		 };
+
+		 asset_allocator2 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 12>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 13>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 14>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 15>;
+			 };
+		 };
+
+		 asset_allocator3 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 16>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 17>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 18>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 19>;
+			 };
+		 };
+
+		 asset_allocator4 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 20>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 21>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 22>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 23>;
+			 };
+		 };
+
+		 asset_allocator5 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 24>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 25>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 26>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 27>;
+			 };
+		 };
+
+		 asset_allocator6 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 28>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 29>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 30>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 31>;
+			 };
+		 };
+
+		 asset_allocator7 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 32>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 33>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 34>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 35>;
+			 };
+		 };
+
+		 asset_allocator8 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 36>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 37>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 38>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 39>;
+			 };
+		 };
+
+		 asset_allocator9 {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 40>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 41>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 42>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 43>;
 			 };
 		 };
 	 };
diff --git a/fdts/morello-coresight.dtsi b/fdts/morello-coresight.dtsi
new file mode 100644
index 0000000..ed3e9e5
--- /dev/null
+++ b/fdts/morello-coresight.dtsi
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	/*
+	 * Morello TRMs specify the size for these coresight components as 64K.
+	 * The actual size is just 4K though 64K is reserved. Access to the
+	 * unmapped reserved region results in a DECERR response.
+	 */
+	cpu_debug0: cpu-debug@402010000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu0>;
+		reg = <0x4 0x02010000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm0: etm@402040000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu0>;
+		reg = <0x4 0x02040000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster0_etm0_out_port: endpoint {
+					remote-endpoint = <&cluster0_static_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	cpu_debug1: cpu-debug@402110000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu1>;
+		reg = <0x4 0x02110000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm1: etm@402140000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu1>;
+		reg = <0x4 0x02140000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster0_etm1_out_port: endpoint {
+					remote-endpoint = <&cluster0_static_funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	cpu_debug2: cpu-debug@403010000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu2>;
+		reg = <0x4 0x03010000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm2: etm@403040000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu2>;
+		reg = <0x4 0x03040000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster1_etm0_out_port: endpoint {
+					remote-endpoint = <&cluster1_static_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	cpu_debug3: cpu-debug@403110000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu3>;
+		reg = <0x4 0x03110000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm3: etm@403140000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu3>;
+		reg = <0x4 0x03140000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster1_etm1_out_port: endpoint {
+					remote-endpoint = <&cluster1_static_funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	sfunnel0: funnel@0 { /* cluster0 funnel */
+		compatible = "arm,coresight-static-funnel";
+		out-ports {
+			port {
+				cluster0_static_funnel_out_port: endpoint {
+					remote-endpoint = <&etf0_in_port>;
+				};
+			};
+		};
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				cluster0_static_funnel_in_port0: endpoint {
+					remote-endpoint = <&cluster0_etm0_out_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				cluster0_static_funnel_in_port1: endpoint {
+					remote-endpoint = <&cluster0_etm1_out_port>;
+				};
+			};
+		};
+	};
+
+	sfunnel1: funnel@1 { /* cluster1 funnel */
+		compatible = "arm,coresight-static-funnel";
+		out-ports {
+			port {
+				cluster1_static_funnel_out_port: endpoint {
+					remote-endpoint = <&etf1_in_port>;
+				};
+			};
+		};
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				cluster1_static_funnel_in_port0: endpoint {
+					remote-endpoint = <&cluster1_etm0_out_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				cluster1_static_funnel_in_port1: endpoint {
+					remote-endpoint = <&cluster1_etm1_out_port>;
+				};
+			};
+		};
+	};
+
+	tpiu@400130000 {
+		compatible = "arm,coresight-tpiu", "arm,primecell";
+		reg = <0x4 0x00130000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				tpiu_in_port: endpoint {
+					remote-endpoint = <&replicator_out_port0>;
+				};
+			};
+		};
+	};
+
+	main_funnel: funnel@4000a0000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0x4 0x000a0000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				main_funnel_out_port: endpoint {
+					remote-endpoint = <&replicator_in_port>;
+				};
+			};
+		};
+		main_funnel_in_ports: in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				main_funnel_in_port0: endpoint {
+					remote-endpoint = <&cluster_funnel_out_port>;
+				};
+			};
+			port@5 {
+				reg = <5>;
+				main_funnel_in_port5: endpoint {
+					remote-endpoint = <&etf2_out_port>;
+				};
+			};
+		};
+	};
+
+	etr@400120000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00120000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		arm,scatter-gather;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "etrbufint";
+		in-ports {
+			port {
+				etr_in_port: endpoint {
+					remote-endpoint = <&replicator_out_port1>;
+				};
+			};
+		};
+	};
+
+	replicator@400110000 {
+		compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+		reg = <0x4 0x00110000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			/* replicator output ports */
+			port@0 {
+				reg = <0>;
+				replicator_out_port0: endpoint {
+					remote-endpoint = <&tpiu_in_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				replicator_out_port1: endpoint {
+					remote-endpoint = <&etr_in_port>;
+				};
+			};
+		};
+		in-ports {
+			port {
+				replicator_in_port: endpoint {
+					remote-endpoint = <&main_funnel_out_port>;
+				};
+			};
+		};
+	};
+
+	cluster_funnel: funnel@4000b0000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0x4 0x000b0000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster_funnel_out_port: endpoint {
+					remote-endpoint = <&main_funnel_in_port0>;
+				};
+			};
+		};
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				cluster_funnel_in_port0: endpoint {
+					remote-endpoint = <&etf0_out_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				cluster_funnel_in_port1: endpoint {
+					remote-endpoint = <&etf1_out_port>;
+				};
+			};
+		};
+	};
+
+	etf0: etf@400410000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00410000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etf0_in_port: endpoint {
+					remote-endpoint = <&cluster0_static_funnel_out_port>;
+				};
+			};
+		};
+		out-ports {
+			port {
+				etf0_out_port: endpoint {
+					remote-endpoint = <&cluster_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	etf1: etf@400420000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00420000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etf1_in_port: endpoint {
+					remote-endpoint = <&cluster1_static_funnel_out_port>;
+				};
+			};
+		};
+		out-ports {
+			port {
+				etf1_out_port: endpoint {
+					remote-endpoint = <&cluster_funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	stm_etf: etf@400010000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00010000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etf2_in_port: endpoint {
+					remote-endpoint = <&stm_out_port>;
+				};
+			};
+		};
+		out-ports {
+			port {
+				etf2_out_port: endpoint {
+					remote-endpoint = <&main_funnel_in_port5>;
+				};
+			};
+		};
+	};
+
+	stm@400800000 {
+		compatible = "arm,coresight-stm", "arm,primecell";
+		reg = <4 0x00800000 0 0x1000>,
+		      <0 0x4d000000 0 0x1000000>;
+		reg-names = "stm-base", "stm-stimulus-base";
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				stm_out_port: endpoint {
+					remote-endpoint = <&etf2_in_port>;
+				};
+			};
+		};
+	};
+};
diff --git a/fdts/morello-soc.dts b/fdts/morello-soc.dts
index e87b617..61b5763 100644
--- a/fdts/morello-soc.dts
+++ b/fdts/morello-soc.dts
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include "morello.dtsi"
+#include "morello-coresight.dtsi"
 
 / {
 	model = "Arm Morello System Development Platform";
@@ -28,28 +29,28 @@
 	cpus {
 		#address-cells = <2>;
 		#size-cells = <0>;
-		cpu0@0 {
+		cpu0: cpu0@0 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x0>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 		};
-		cpu1@100 {
+		cpu1: cpu1@100 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x100>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 		};
-		cpu2@10000 {
+		cpu2: cpu2@10000 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x10000>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 		};
-		cpu3@10100 {
+		cpu3: cpu3@10100 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x10100>;
 			device_type = "cpu";
diff --git a/fdts/stm32mp13-bl2.dtsi b/fdts/stm32mp13-bl2.dtsi
index 836e9ae..2b23daf 100644
--- a/fdts/stm32mp13-bl2.dtsi
+++ b/fdts/stm32mp13-bl2.dtsi
@@ -1,8 +1,17 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * 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
@@ -32,13 +41,6 @@
 #if !STM32MP_USB_PROGRAMMER
 		/delete-node/ usbphyc@5a006000;
 #endif
-
-		pinctrl@50002000 {
-#if !STM32MP_EMMC && !STM32MP_SDMMC
-			/delete-node/ sdmmc1-b4-0;
-			/delete-node/ sdmmc2-b4-0;
-#endif
-		};
 	};
 
 	/*
diff --git a/fdts/stm32mp13-pinctrl.dtsi b/fdts/stm32mp13-pinctrl.dtsi
index 879da9c..323d5ba 100644
--- a/fdts/stm32mp13-pinctrl.dtsi
+++ b/fdts/stm32mp13-pinctrl.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com>
  */
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
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 5489a62..53aeec5 100644
--- a/fdts/stm32mp15-bl2.dtsi
+++ b/fdts/stm32mp15-bl2.dtsi
@@ -1,8 +1,40 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2020-2022 - All Rights Reserved
+ * 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
 	aliases {
@@ -39,34 +71,10 @@
 #if !STM32MP_USB_PROGRAMMER
 		/delete-node/ usbphyc@5a006000;
 #endif
-		/delete-node/ spi@5c001000;
 		/delete-node/ rtc@5c004000;
 		/delete-node/ etzpc@5c007000;
 		/delete-node/ stgen@5c008000;
-		/delete-node/ i2c@5c009000;
 		/delete-node/ tamp@5c00a000;
-
-		pinctrl@50002000 {
-#if !STM32MP_RAW_NAND
-			/delete-node/ fmc-0;
-#endif
-#if !STM32MP_SPI_NAND && !STM32MP_SPI_NOR
-			/delete-node/ qspi-clk-0;
-			/delete-node/ qspi-bk1-0;
-			/delete-node/ qspi-bk2-0;
-#endif
-#if !STM32MP_EMMC && !STM32MP_SDMMC
-			/delete-node/ sdmmc1-b4-0;
-			/delete-node/ sdmmc1-dir-0;
-			/delete-node/ sdmmc2-b4-0;
-			/delete-node/ sdmmc2-b4-1;
-			/delete-node/ sdmmc2-d47-0;
-#endif
-#if !STM32MP_USB_PROGRAMMER
-			/delete-node/ usbotg_hs-0;
-			/delete-node/ usbotg-fs-dp-dm-0;
-#endif
-		};
 	};
 
 	/*
diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi
index 31b24f6..7b63f1b 100644
--- a/fdts/stm32mp15-bl32.dtsi
+++ b/fdts/stm32mp15-bl32.dtsi
@@ -1,8 +1,40 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2020-2021 - All Rights Reserved
+ * 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 {
 		/delete-property/ mmc0;
@@ -23,24 +55,6 @@
 		/delete-node/ mmc@58005000;
 		/delete-node/ mmc@58007000;
 		/delete-node/ usbphyc@5a006000;
-		/delete-node/ spi@5c001000;
 		/delete-node/ stgen@5c008000;
-		/delete-node/ i2c@5c009000;
-
-		pinctrl@50002000 {
-			/delete-node/ fmc-0;
-			/delete-node/ qspi-clk-0;
-			/delete-node/ qspi-bk1-0;
-			/delete-node/ qspi-bk2-0;
-			/delete-node/ sdmmc1-b4-0;
-			/delete-node/ sdmmc1-dir-0;
-			/delete-node/ sdmmc2-b4-0;
-			/delete-node/ sdmmc2-b4-1;
-			/delete-node/ sdmmc2-d47-0;
-			/delete-node/ sdmmc2-d47-1;
-			/delete-node/ sdmmc2-d47-3;
-			/delete-node/ usbotg_hs-0;
-			/delete-node/ usbotg-fs-dp-dm-0;
-		};
 	};
 };
diff --git a/fdts/stm32mp15-ddr3-1x2Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x2Gb-1066-binG.dtsi
new file mode 100644
index 0000000..332d1bf
--- /dev/null
+++ b/fdts/stm32mp15-ddr3-1x2Gb-1066-binG.dtsi
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs
+ * DDR type: DDR3 / DDR3L
+ * DDR width: 16bits
+ * DDR density: 4Gb
+ * System frequency: 533000Khz
+ * Relaxed Timing Mode: false
+ * Address mapping type: RBC
+ *
+ * Save Date: 2020.02.20, save Time: 18:45:20
+ */
+
+#define DDR_MEM_NAME	"DDR3-DDR3L 16bits 533000kHz"
+#define DDR_MEM_SPEED	533000
+#define DDR_MEM_SIZE	0x10000000
+
+#define DDR_MSTR 0x00041401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0040008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B1214
+#define DDR_DRAMTMG1 0x000A041C
+#define DDR_DRAMTMG2 0x0608090F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x08040608
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02060105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000C01
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x01000001
+#define DDR_PERFLPR1 0x08000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00010000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x02100C03
+#define DDR_PCFGQOS1_0 0x00800100
+#define DDR_PCFGWQOS0_0 0x01100C03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PCFGR_1 0x00010000
+#define DDR_PCFGW_1 0x00000000
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
+#define DDR_PCFGWQOS1_1 0x01000200
+#define DDR_ADDRMAP1 0x00151515
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x1F000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x03030303
+#define DDR_ADDRMAP6 0x0F0F0303
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200011F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x38D488D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000840
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000248
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX0DLLCR 0x40000000
+#define DDR_DX0DQTR 0xFFFFFFFF
+#define DDR_DX0DQSTR 0x3DB02000
+#define DDR_DX1GCR 0x0000CE81
+#define DDR_DX1DLLCR 0x40000000
+#define DDR_DX1DQTR 0xFFFFFFFF
+#define DDR_DX1DQSTR 0x3DB02000
+#define DDR_DX2GCR 0x0000CE80
+#define DDR_DX2DLLCR 0x40000000
+#define DDR_DX2DQTR 0xFFFFFFFF
+#define DDR_DX2DQSTR 0x3DB02000
+#define DDR_DX3GCR 0x0000CE80
+#define DDR_DX3DLLCR 0x40000000
+#define DDR_DX3DQTR 0xFFFFFFFF
+#define DDR_DX3DQSTR 0x3DB02000
+
+#include "stm32mp15-ddr.dtsi"
diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi
index 7d2be0b..a1be447 100644
--- a/fdts/stm32mp15-pinctrl.dtsi
+++ b/fdts/stm32mp15-pinctrl.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
diff --git a/fdts/stm32mp151a-prtt1a-fw-config.dts b/fdts/stm32mp151a-prtt1a-fw-config.dts
new file mode 100644
index 0000000..1bbae4e
--- /dev/null
+++ b/fdts/stm32mp151a-prtt1a-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2023, Oleksij Rempel <kernel@pengutronix.de>, Pengutronix
+ */
+
+#define DDR_SIZE	0x10000000 /* 256 MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp151a-prtt1a.dts b/fdts/stm32mp151a-prtt1a.dts
new file mode 100644
index 0000000..be9bdae
--- /dev/null
+++ b/fdts/stm32mp151a-prtt1a.dts
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2023, Protonic Holland - All Rights Reserved
+ * Author: David Jander <david@protonic.nl>
+ */
+/dts-v1/;
+
+#include "stm32mp151.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxad-pinctrl.dtsi"
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-1x2Gb-1066-binG.dtsi"
+
+/ {
+	model = "Protonic PRTT1A";
+	compatible = "prt,prtt1a", "st,stm32mp151";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		mmc0 = &sdmmc1;
+		mmc1 = &sdmmc2;
+		serial0 = &uart4;
+	};
+
+	memory@c0000000 {
+		device_type = "memory";
+		reg = <0xC0000000 0x10000000>;
+	};
+};
+
+&iwdg2 {
+	timeout-sec = <32>;
+	status = "okay";
+	secure-status = "okay";
+};
+
+&qspi {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
+	reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	flash@0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <104000000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
+
+&qspi_bk1_pins_a {
+	pins1 {
+		bias-pull-up;
+		drive-push-pull;
+		slew-rate = <1>;
+	};
+};
+
+&rcc {
+	st,clksrc = <
+		CLK_MPU_PLL1P
+		CLK_AXI_PLL2P
+		CLK_MCU_PLL3P
+		CLK_PLL12_HSE
+		CLK_PLL3_HSE
+		CLK_PLL4_HSE
+		CLK_RTC_LSI
+		CLK_MCO1_DISABLED
+		CLK_MCO2_DISABLED
+	>;
+
+	st,clkdiv = <
+		1 /*MPU*/
+		0 /*AXI*/
+		0 /*MCU*/
+		1 /*APB1*/
+		1 /*APB2*/
+		1 /*APB3*/
+		1 /*APB4*/
+		2 /*APB5*/
+		23 /*RTC*/
+		0 /*MCO1*/
+		0 /*MCO2*/
+	>;
+
+	st,pkcs = <
+		CLK_CKPER_HSE
+		CLK_FMC_ACLK
+		CLK_QSPI_ACLK
+		CLK_ETH_DISABLED
+		CLK_SDMMC12_PLL4P
+		CLK_DSI_DSIPLL
+		CLK_STGEN_HSE
+		CLK_USBPHY_HSE
+		CLK_SPI2S1_PLL3Q
+		CLK_SPI2S23_PLL3Q
+		CLK_SPI45_HSI
+		CLK_SPI6_HSI
+		CLK_I2C46_HSI
+		CLK_SDMMC3_PLL4P
+		CLK_USBO_USBPHY
+		CLK_ADC_CKPER
+		CLK_CEC_LSI
+		CLK_I2C12_HSI
+		CLK_I2C35_HSI
+		CLK_UART1_HSI
+		CLK_UART24_HSI
+		CLK_UART35_HSI
+		CLK_UART6_HSI
+		CLK_UART78_HSI
+		CLK_SPDIF_PLL4P
+		CLK_FDCAN_PLL4R
+		CLK_SAI1_PLL3Q
+		CLK_SAI2_PLL3Q
+		CLK_SAI3_PLL3Q
+		CLK_SAI4_PLL3Q
+		CLK_RNG1_LSI
+		CLK_RNG2_LSI
+		CLK_LPTIM1_PCLK1
+		CLK_LPTIM23_PCLK3
+		CLK_LPTIM45_LSI
+	>;
+
+	/* VCO = 1300.0 MHz => P = 650 (CPU) */
+	pll1: st,pll@0 {
+		compatible = "st,stm32mp1-pll";
+		reg = <0>;
+		cfg = <2 80 0 0 0 PQR(1,0,0)>;
+		frac = <0x800>;
+	};
+
+	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+	pll2: st,pll@1 {
+		compatible = "st,stm32mp1-pll";
+		reg = <1>;
+		cfg = <2 65 1 0 0 PQR(1,1,1)>;
+		frac = <0x1400>;
+	};
+
+	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+	pll3: st,pll@2 {
+		compatible = "st,stm32mp1-pll";
+		reg = <2>;
+		cfg = <1 33 1 16 36 PQR(1,1,1)>;
+		frac = <0x1a04>;
+	};
+
+	/* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */
+	pll4: st,pll@3 {
+		compatible = "st,stm32mp1-pll";
+		reg = <3>;
+		cfg = <1 39 3 11 4 PQR(1,1,1)>;
+	};
+};
+
+&rng1 {
+	status = "okay";
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sdmmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_b4_pins_a>;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&sdmmc1_b4_pins_a {
+	pins1 {
+		bias-pull-up;
+	};
+	pins2 {
+		bias-pull-up;
+	};
+};
+
+/* NOTE: Although the PRTT1A does not have an eMMC, we declare it
+ * anyway, in order to be able to use the same binary for the
+ * PRTT1C also. All involved pins are N.C. on PRTT1A/S for that
+ * reason, so it should do no harm. All inputs configured with
+ * pull-ups to avoid floating inputs. */
+&sdmmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+	bus-width = <8>;
+	status = "okay";
+};
+
+&sdmmc2_b4_pins_a {
+	pins1 {
+		pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+			 <STM32_PINMUX('B', 7, AF10)>, /* SDMMC2_D1 */
+			 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+			 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+			 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+	};
+};
+
+&sdmmc2_d47_pins_a {
+	pins {
+		pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+			 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
+			 <STM32_PINMUX('C', 6, AF10)>, /* SDMMC2_D6 */
+			 <STM32_PINMUX('C', 7, AF10)>; /* SDMMC2_D7 */
+	};
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+	status = "okay";
+};
+
+&uart4_pins_a {
+	pins1 {
+		pinmux = <STM32_PINMUX('B', 9, AF8)>; /* UART4_TX */
+		bias-disable;
+		drive-push-pull;
+		slew-rate = <0>;
+	};
+	pins2 {
+		pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+		bias-pull-up;
+	};
+};
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 8678bf3..dd2c0a6 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +16,10 @@
 #define MIDR_IMPL_SHIFT		U(24)
 #define MIDR_VAR_SHIFT		U(20)
 #define MIDR_VAR_BITS		U(4)
+#define MIDR_VAR_MASK		U(0xf)
 #define MIDR_REV_SHIFT		U(0)
 #define MIDR_REV_BITS		U(4)
+#define MIDR_REV_MASK		U(0xf)
 #define MIDR_PN_MASK		U(0xfff)
 #define MIDR_PN_SHIFT		U(4)
 
@@ -102,7 +104,11 @@
 /* CSSELR definitions */
 #define LEVEL_SHIFT		U(1)
 
-/* ID_DFR0_EL1 definitions */
+/* ID_DFR0 definitions */
+#define ID_DFR0_PERFMON_SHIFT		U(24)
+#define ID_DFR0_PERFMON_MASK		U(0xf)
+#define ID_DFR0_PERFMON_PMUV3		U(3)
+#define ID_DFR0_PERFMON_PMUV3P5		U(6)
 #define ID_DFR0_COPTRC_SHIFT		U(12)
 #define ID_DFR0_COPTRC_MASK		U(0xf)
 #define ID_DFR0_COPTRC_SUPPORTED	U(1)
@@ -116,6 +122,11 @@
 #define ID_DFR1_MTPMU_SHIFT	U(0)
 #define ID_DFR1_MTPMU_MASK	U(0xf)
 #define ID_DFR1_MTPMU_SUPPORTED	U(1)
+#define ID_DFR1_MTPMU_DISABLED	U(15)
+
+/* 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)
@@ -264,7 +275,7 @@
 #define TCP10_BIT		(U(1) << 10)
 #define HCPTR_RESET_VAL		HCPTR_RES1
 
-/* VTTBR defintions */
+/* VTTBR definitions */
 #define VTTBR_RESET_VAL		ULL(0x0)
 #define VTTBR_VMID_MASK		ULL(0xff)
 #define VTTBR_VMID_SHIFT	U(48)
@@ -458,6 +469,10 @@
 #define PMCR_LP_BIT		(U(1) << 7)
 #define PMCR_LC_BIT		(U(1) << 6)
 #define PMCR_DP_BIT		(U(1) << 5)
+#define PMCR_X_BIT		(U(1) << 4)
+#define PMCR_C_BIT		(U(1) << 2)
+#define PMCR_P_BIT		(U(1) << 1)
+#define PMCR_E_BIT		(U(1) << 0)
 #define	PMCR_RESET_VAL		U(0x0)
 
 /*******************************************************************************
@@ -531,6 +546,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 a5a5e27..f19c4c2 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -25,6 +25,37 @@
 	return ISOLATE_FIELD(read_id_mmfr4(), ID_MMFR4_CNP) != 0U;
 }
 
+static unsigned int read_feat_amu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_AMU);
+}
+
+static inline bool is_feat_amu_supported(void)
+{
+	if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_amu_id_field() >= ID_PFR0_AMU_V1;
+}
+
+static inline bool is_feat_amuv1p1_supported(void)
+{
+	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_amu_id_field() >= ID_PFR0_AMU_V1P1;
+}
+
 static inline unsigned int read_feat_trf_id_field(void)
 {
 	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_TRACEFILT);
@@ -43,4 +74,117 @@
 	return read_feat_trf_id_field() != 0U;
 }
 
+static inline unsigned int read_feat_coptrc_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_COPTRC);
+}
+
+static inline bool is_feat_sys_reg_trace_supported(void)
+{
+	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_coptrc_id_field() != 0U;
+}
+
+static inline unsigned int read_feat_dit_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT);
+}
+
+static inline bool is_feat_dit_supported(void)
+{
+	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_dit_id_field() != 0U;
+}
+
+static inline unsigned int read_feat_pan_id_field(void)
+{
+	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; }
+
+static inline unsigned int read_feat_pmuv3_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_PERFMON);
+}
+
+static inline unsigned int read_feat_mtpmu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU);
+}
+
+static inline bool is_feat_mtpmu_supported(void)
+{
+	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	unsigned int mtpmu = read_feat_mtpmu_id_field();
+
+	return mtpmu != 0U && mtpmu != ID_DFR1_MTPMU_DISABLED;
+}
+
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 95d056f..3a7c768 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,8 +218,10 @@
  ******************************************************************************/
 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_dfr1, ID_DFR1)
 DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
 DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
 DEFINE_COPROCR_READ_FUNC(isr, ISR)
@@ -288,7 +291,7 @@
 DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR)
 DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
 DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
-DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
+DEFINE_COPROCR_RW_FUNCS(pmcr, PMCR)
 
 /*
  * Address translation
@@ -351,6 +354,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/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index 483f9fe..83e94ca 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <arch.h>
 #include <common/asm_macros_common.S>
+#include <lib/cpus/cpu_ops.h>
 #include <lib/spinlock.h>
 
 /*
@@ -24,8 +25,6 @@
 	stcopr	_reg, _coproc
 #endif
 
-#define WORD_SIZE	4
-
 	/*
 	 * Co processor register accessors
 	 */
@@ -49,14 +48,14 @@
 	.macro	dcache_line_size  reg, tmp
 	ldcopr	\tmp, CTR
 	ubfx	\tmp, \tmp, #CTR_DMINLINE_SHIFT, #CTR_DMINLINE_WIDTH
-	mov	\reg, #WORD_SIZE
+	mov	\reg, #CPU_WORD_SIZE
 	lsl	\reg, \reg, \tmp
 	.endm
 
 	.macro	icache_line_size  reg, tmp
 	ldcopr	\tmp, CTR
 	and	\tmp, \tmp, #CTR_IMINLINE_MASK
-	mov	\reg, #WORD_SIZE
+	mov	\reg, #CPU_WORD_SIZE
 	lsl	\reg, \reg, \tmp
 	.endm
 
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 585a9ae..697eb82 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -277,10 +277,6 @@
 	cps	#MODE32_mon
 	isb
 
-#if DISABLE_MTPMU
-	bl	mtpmu_disable
-#endif
-
 	.if \_warm_boot_mailbox
 		/* -------------------------------------------------------------
 		 * This code will be executed for both warm and cold resets.
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b786521..5dbcd0a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -119,8 +119,11 @@
 #define MPAMVPM7_EL2		S3_4_C10_C6_7
 #define MPAMVPMV_EL2		S3_4_C10_C4_1
 #define TRFCR_EL2		S3_4_C1_C2_1
+#define VNCR_EL2		S3_4_C2_C2_0
 #define PMSCR_EL2		S3_4_C9_C9_0
 #define TFSR_EL2		S3_4_C5_C6_0
+#define CONTEXTIDR_EL2		S3_4_C13_C0_1
+#define TTBR1_EL2		S3_4_C2_C0_1
 
 /*******************************************************************************
  * Generic timer memory mapped registers & offsets
@@ -218,6 +221,12 @@
 #define ID_AA64DFR0_TRACEFILT_MASK	U(0xf)
 #define ID_AA64DFR0_TRACEFILT_SUPPORTED	U(1)
 #define ID_AA64DFR0_TRACEFILT_LENGTH	U(4)
+#define ID_AA64DFR0_PMUVER_LENGTH	U(4)
+#define ID_AA64DFR0_PMUVER_SHIFT	U(8)
+#define ID_AA64DFR0_PMUVER_MASK		U(0xf)
+#define ID_AA64DFR0_PMUVER_PMUV3	U(1)
+#define ID_AA64DFR0_PMUVER_PMUV3P7	U(7)
+#define ID_AA64DFR0_PMUVER_IMP_DEF	U(0xf)
 
 /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
 #define ID_AA64DFR0_PMS_SHIFT		U(32)
@@ -234,6 +243,7 @@
 #define ID_AA64DFR0_MTPMU_SHIFT		U(48)
 #define ID_AA64DFR0_MTPMU_MASK		ULL(0xf)
 #define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
+#define ID_AA64DFR0_MTPMU_DISABLED	ULL(15)
 
 /* ID_AA64DFR0_EL1.BRBE definitions */
 #define ID_AA64DFR0_BRBE_SHIFT		U(52)
@@ -297,6 +307,7 @@
 #define ID_AA64MMFR0_EL1_TGRAN4_SHIFT		U(28)
 #define ID_AA64MMFR0_EL1_TGRAN4_MASK		ULL(0xf)
 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED	ULL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN4_52B_SUPPORTED	ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED	ULL(0xf)
 
 #define ID_AA64MMFR0_EL1_TGRAN64_SHIFT		U(24)
@@ -308,6 +319,7 @@
 #define ID_AA64MMFR0_EL1_TGRAN16_MASK		ULL(0xf)
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED	ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED	ULL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN16_52B_SUPPORTED	ULL(0x2)
 
 /* ID_AA64MMFR1_EL1 definitions */
 #define ID_AA64MMFR1_EL1_TWED_SHIFT		U(32)
@@ -352,10 +364,25 @@
 /* ID_AA64MMFR3_EL1 definitions */
 #define ID_AA64MMFR3_EL1			S3_0_C0_C7_3
 
+#define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
+#define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S1POE_SHIFT		U(16)
+#define ID_AA64MMFR3_EL1_S1POE_MASK		ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S2PIE_SHIFT		U(12)
+#define ID_AA64MMFR3_EL1_S2PIE_MASK		ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S1PIE_SHIFT		U(8)
+#define ID_AA64MMFR3_EL1_S1PIE_MASK		ULL(0xf)
+
 #define ID_AA64MMFR3_EL1_TCRX_SHIFT		U(0)
 #define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
 
 /* ID_AA64PFR1_EL1 definitions */
+#define ID_AA64PFR1_EL1_GCS_SHIFT	U(44)
+#define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
+
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
 
@@ -375,6 +402,9 @@
 #define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED	ULL(0x1)
 #define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED	ULL(0x0)
 
+#define VDISR_EL2				S3_4_C12_C1_1
+#define VSESR_EL2				S3_4_C5_C2_3
+
 /* Memory Tagging Extension is not implemented */
 #define MTE_UNIMPLEMENTED	U(0)
 /* FEAT_MTE: MTE instructions accessible at EL0 are implemented */
@@ -390,8 +420,11 @@
 #define ID_AA64PFR1_MPAM_FRAC_SHIFT	ULL(16)
 #define ID_AA64PFR1_MPAM_FRAC_MASK	ULL(0xf)
 
-#define ID_AA64PFR1_EL1_SME_SHIFT	U(24)
-#define ID_AA64PFR1_EL1_SME_MASK	ULL(0xf)
+#define ID_AA64PFR1_EL1_SME_SHIFT		U(24)
+#define ID_AA64PFR1_EL1_SME_MASK		ULL(0xf)
+#define ID_AA64PFR1_EL1_SME_NOT_SUPPORTED	ULL(0x0)
+#define ID_AA64PFR1_EL1_SME_SUPPORTED		ULL(0x1)
+#define ID_AA64PFR1_EL1_SME2_SUPPORTED		ULL(0x2)
 
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -499,6 +532,8 @@
 #define CPACR_EL1_FP_TRAP_EL0	UL(0x1)
 #define CPACR_EL1_FP_TRAP_ALL	UL(0x2)
 #define CPACR_EL1_FP_TRAP_NONE	UL(0x3)
+#define CPACR_EL1_SMEN_SHIFT	U(24)
+#define CPACR_EL1_SMEN_MASK	ULL(0x3)
 
 /* SCR definitions */
 #define SCR_RES1_BITS		((U(1) << 4) | (U(1) << 5))
@@ -507,8 +542,10 @@
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
+#define SCR_PIEN_BIT		(UL(1) << 45)
 #define SCR_TCR2EN_BIT		(UL(1) << 43)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
+#define SCR_GCSEn_BIT		(UL(1) << 39)
 #define SCR_HXEn_BIT		(UL(1) << 38)
 #define SCR_ENTP2_SHIFT		U(41)
 #define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
@@ -565,16 +602,16 @@
 #define MDCR_TDOSA_BIT		(ULL(1) << 10)
 #define MDCR_TDA_BIT		(ULL(1) << 9)
 #define MDCR_TPM_BIT		(ULL(1) << 6)
-#define MDCR_EL3_RESET_VAL	ULL(0x0)
+#define MDCR_EL3_RESET_VAL	MDCR_MTPME_BIT
 
 /* MDCR_EL2 definitions */
 #define MDCR_EL2_MTPME		(U(1) << 28)
-#define MDCR_EL2_HLP		(U(1) << 26)
+#define MDCR_EL2_HLP_BIT	(U(1) << 26)
 #define MDCR_EL2_E2TB(x)	((x) << 24)
 #define MDCR_EL2_E2TB_EL1	U(0x3)
-#define MDCR_EL2_HCCD		(U(1) << 23)
+#define MDCR_EL2_HCCD_BIT	(U(1) << 23)
 #define MDCR_EL2_TTRF		(U(1) << 19)
-#define MDCR_EL2_HPMD		(U(1) << 17)
+#define MDCR_EL2_HPMD_BIT	(U(1) << 17)
 #define MDCR_EL2_TPMS		(U(1) << 14)
 #define MDCR_EL2_E2PB(x)	((x) << 12)
 #define MDCR_EL2_E2PB_EL1	U(0x3)
@@ -585,6 +622,7 @@
 #define MDCR_EL2_HPME_BIT	(U(1) << 7)
 #define MDCR_EL2_TPM_BIT	(U(1) << 6)
 #define MDCR_EL2_TPMCR_BIT	(U(1) << 5)
+#define MDCR_EL2_HPMN_MASK	U(0x1f)
 #define MDCR_EL2_RESET_VAL	U(0x0)
 
 /* HSTR_EL2 definitions */
@@ -727,7 +765,7 @@
 #define HI_VECTOR_BASE		U(0xFFFF0000)
 
 /*
- * TCR defintions
+ * TCR definitions
  */
 #define TCR_EL3_RES1		((ULL(1) << 31) | (ULL(1) << 23))
 #define TCR_EL2_RES1		((ULL(1) << 31) | (ULL(1) << 23))
@@ -1001,12 +1039,19 @@
 #define SMCR_EL3			S3_6_C1_C2_6
 
 /* ID_AA64SMFR0_EL1 definitions */
-#define ID_AA64SMFR0_EL1_FA64_BIT	(UL(1) << 63)
+#define ID_AA64SMFR0_EL1_SME_FA64_SHIFT		U(63)
+#define ID_AA64SMFR0_EL1_SME_FA64_MASK		U(0x1)
+#define ID_AA64SMFR0_EL1_SME_FA64_SUPPORTED	U(0x1)
+#define ID_AA64SMFR0_EL1_SME_VER_SHIFT		U(55)
+#define ID_AA64SMFR0_EL1_SME_VER_MASK		ULL(0xf)
+#define ID_AA64SMFR0_EL1_SME_INST_SUPPORTED	ULL(0x0)
+#define ID_AA64SMFR0_EL1_SME2_INST_SUPPORTED	ULL(0x1)
 
 /* SMCR_ELx definitions */
 #define SMCR_ELX_LEN_SHIFT		U(0)
-#define SMCR_ELX_LEN_MASK		U(0x1ff)
+#define SMCR_ELX_LEN_MAX		U(0x1ff)
 #define SMCR_ELX_FA64_BIT		(U(1) << 31)
+#define SMCR_ELX_EZT0_BIT		(U(1) << 30)
 
 /*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
@@ -1077,10 +1122,8 @@
 #define MPAMHCR_EL2		S3_4_C10_C4_0
 #define MPAM3_EL3		S3_6_C10_C5_0
 
-#define MPAMIDR_EL1_HAS_HCR_SHIFT	ULL(0x11)
-#define MPAMIDR_EL1_VPMR_MAX_SHIFT	ULL(0x12)
-#define MPAMIDR_EL1_VPMR_MAX_WIDTH	ULL(0x3)
-#define MPAMIDR_EL1_VPMR_MAX_POSSIBLE	ULL(0x7)
+#define MPAMIDR_EL1_VPMR_MAX_SHIFT	ULL(18)
+#define MPAMIDR_EL1_VPMR_MAX_MASK	ULL(0x7)
 /*******************************************************************************
  * Definitions for system register interface to AMU for FEAT_AMUv1
  ******************************************************************************/
@@ -1229,6 +1272,8 @@
 #define GPCCR_EL3			S3_6_C2_C1_6
 #define GPTBR_EL3			S3_6_C2_C1_4
 
+#define SCXTNUM_EL2			S3_4_C13_C0_7
+
 /*******************************************************************************
  * RAS system registers
  ******************************************************************************/
@@ -1302,11 +1347,19 @@
  * FEAT_HCX - Extended Hypervisor Configuration Register
  ******************************************************************************/
 #define HCRX_EL2		S3_4_C1_C2_2
+#define HCRX_EL2_MSCEn_BIT	(UL(1) << 11)
+#define HCRX_EL2_MCE2_BIT	(UL(1) << 10)
+#define HCRX_EL2_CMOW_BIT	(UL(1) << 9)
+#define HCRX_EL2_VFNMI_BIT	(UL(1) << 8)
+#define HCRX_EL2_VINMI_BIT	(UL(1) << 7)
+#define HCRX_EL2_TALLINT_BIT	(UL(1) << 6)
+#define HCRX_EL2_SMPME_BIT	(UL(1) << 5)
 #define HCRX_EL2_FGTnXS_BIT	(UL(1) << 4)
 #define HCRX_EL2_FnXS_BIT	(UL(1) << 3)
 #define HCRX_EL2_EnASR_BIT	(UL(1) << 2)
 #define HCRX_EL2_EnALS_BIT	(UL(1) << 1)
 #define HCRX_EL2_EnAS0_BIT	(UL(1) << 0)
+#define HCRX_EL2_INIT_VAL	ULL(0x0)
 
 /*******************************************************************************
  * FEAT_TCR2 - Extended Translation Control Register
@@ -1314,6 +1367,21 @@
 #define TCR2_EL2		S3_4_C2_C0_3
 
 /*******************************************************************************
+ * Permission indirection and overlay
+ ******************************************************************************/
+
+#define PIRE0_EL2		S3_4_C10_C2_2
+#define PIR_EL2			S3_4_C10_C2_3
+#define POR_EL2			S3_4_C10_C2_4
+#define S2PIR_EL2		S3_4_C10_C2_5
+
+/*******************************************************************************
+ * FEAT_GCS - Guarded Control Stack Registers
+ ******************************************************************************/
+#define GCSCR_EL2		S3_4_C2_C5_0
+#define GCSPR_EL2		S3_4_C2_C5_1
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
@@ -1335,4 +1403,7 @@
 #define CPUMPMMCR_EL3_MPMM_EN_SHIFT	UINT64_C(0)
 #define CPUMPMMCR_EL3_MPMM_EN_MASK	UINT64_C(0x1)
 
+/* alternative system register encoding for the "sb" speculation barrier */
+#define SYSREG_SB			S0_3_C3_C0_7
+
 #endif /* ARCH_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 582aed1..9d71987 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -21,16 +21,40 @@
 	return true;
 }
 
-static inline bool is_armv8_1_pan_present(void)
+static inline unsigned int read_feat_pan_id_field(void)
 {
-	return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_PAN_SHIFT) &
-		ID_AA64MMFR1_EL1_PAN_MASK) != 0U;
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN);
 }
 
-static inline bool is_armv8_1_vhe_present(void)
+static inline bool is_feat_pan_supported(void)
 {
-	return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_VHE_SHIFT) &
-		ID_AA64MMFR1_EL1_VHE_MASK) != 0U;
+	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;
+}
+
+static inline unsigned int read_feat_vhe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE);
+}
+
+static inline bool is_feat_vhe_supported(void)
+{
+	if (ENABLE_FEAT_VHE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_vhe_id_field() != 0U;
 }
 
 static inline bool is_armv8_2_ttcnp_present(void)
@@ -65,12 +89,6 @@
 		is_feat_pacqarma3_present());
 }
 
-static inline bool is_armv8_4_dit_present(void)
-{
-	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
-		ID_AA64PFR0_DIT_MASK) == 1U;
-}
-
 static inline bool is_armv8_4_ttst_present(void)
 {
 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
@@ -89,16 +107,40 @@
 		ID_AA64PFR1_EL1_MTE_MASK);
 }
 
-static inline bool is_armv8_4_sel2_present(void)
+static inline unsigned int read_feat_sel2_id_field(void)
 {
-	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
-		ID_AA64PFR0_SEL2_MASK) == 1ULL;
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2);
 }
 
-static inline bool is_armv8_6_twed_present(void)
+static inline bool is_feat_sel2_supported(void)
 {
-	return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) &
-		ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
+	if (ENABLE_FEAT_SEL2 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_sel2_id_field() != 0U;
+}
+
+static inline unsigned int read_feat_twed_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED);
+}
+
+static inline bool is_feat_twed_supported(void)
+{
+	if (ENABLE_FEAT_TWED == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_twed_id_field() != 0U;
 }
 
 static unsigned int read_feat_fgt_id_field(void)
@@ -119,18 +161,55 @@
 	return read_feat_fgt_id_field() != 0U;
 }
 
+static unsigned int read_feat_ecv_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
+}
+
+static inline bool is_feat_ecv_supported(void)
+{
+	if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_ecv_id_field() != 0U;
+}
+
-static inline unsigned long int get_armv8_6_ecv_support(void)
+static inline bool is_feat_ecv_v2_supported(void)
 {
-	return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
-		ID_AA64MMFR0_EL1_ECV_MASK);
+	if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH;
 }
 
-static inline bool is_armv8_5_rng_present(void)
+static unsigned int read_feat_rng_id_field(void)
 {
-	return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) &
-		ID_AA64ISAR0_RNDR_MASK);
+	return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR);
 }
 
+static inline bool is_feat_rng_supported(void)
+{
+	if (ENABLE_FEAT_RNG == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_rng_id_field() != 0U;
+}
+
 static unsigned int read_feat_tcrx_id_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
@@ -149,6 +228,106 @@
 	return read_feat_tcrx_id_field() != 0U;
 }
 
+static unsigned int read_feat_s2poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
+}
+
+static inline bool is_feat_s2poe_supported(void)
+{
+	if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s2poe_id_field() != 0U;
+}
+
+static unsigned int read_feat_s1poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
+}
+
+static inline bool is_feat_s1poe_supported(void)
+{
+	if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s1poe_id_field() != 0U;
+}
+
+static inline bool is_feat_sxpoe_supported(void)
+{
+	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
+}
+
+static unsigned int read_feat_s2pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
+}
+
+static inline bool is_feat_s2pie_supported(void)
+{
+	if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s2pie_id_field() != 0U;
+}
+
+static unsigned int read_feat_s1pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
+}
+
+static inline bool is_feat_s1pie_supported(void)
+{
+	if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s1pie_id_field() != 0U;
+}
+
+static inline bool is_feat_sxpie_supported(void)
+{
+	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
+}
+
+static unsigned int read_feat_gcs_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS);
+}
+
+static inline bool is_feat_gcs_supported(void)
+{
+	if (ENABLE_FEAT_GCS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_GCS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_gcs_id_field() != 0U;
+}
+
 /*******************************************************************************
  * Functions to identify the presence of the Activity Monitors Extension
  ******************************************************************************/
@@ -159,19 +338,27 @@
 
 static inline bool is_feat_amu_supported(void)
 {
-	if (ENABLE_FEAT_AMUv1 == FEAT_STATE_DISABLED) {
+	if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
 		return false;
 	}
 
-	if (ENABLE_FEAT_AMUv1 == FEAT_STATE_ALWAYS) {
+	if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
 		return true;
 	}
 
 	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
 }
 
-static inline bool is_armv8_6_feat_amuv1p1_present(void)
+static inline bool is_feat_amuv1p1_supported(void)
 {
+	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
 	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
 }
 
@@ -184,7 +371,7 @@
  * 0x11: v1.1 Armv8.4 or later
  *
  */
-static inline unsigned int get_mpam_version(void)
+static inline unsigned int read_feat_mpam_version(void)
 {
 	return (unsigned int)((((read_id_aa64pfr0_el1() >>
 		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
@@ -192,6 +379,19 @@
 		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
 }
 
+static inline bool is_feat_mpam_supported(void)
+{
+	if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_mpam_version() != 0U;
+}
+
 static inline unsigned int read_feat_hcx_id_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
@@ -231,58 +431,128 @@
 /*********************************************************************************
  * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
  ********************************************************************************/
-static inline bool is_armv8_0_feat_sb_present(void)
+static inline unsigned int read_feat_sb_id_field(void)
 {
-	return (((read_id_aa64isar1_el1() >> ID_AA64ISAR1_SB_SHIFT) &
-		ID_AA64ISAR1_SB_MASK) == ID_AA64ISAR1_SB_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB);
 }
 
 /*********************************************************************************
  * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
  ********************************************************************************/
-static inline bool is_armv8_0_feat_csv2_2_present(void)
+static inline unsigned int read_feat_csv2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
+}
+
+static inline bool is_feat_csv2_2_supported(void)
 {
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
-		ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
+	if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
 }
 
 /**********************************************************************************
  * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
  *********************************************************************************/
-static inline bool is_armv8_2_feat_spe_present(void)
+static inline unsigned int read_feat_spe_id_field(void)
 {
-	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
-		ID_AA64DFR0_PMS_MASK) != ID_AA64DFR0_SPE_NOT_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
 }
 
+static inline bool is_feat_spe_supported(void)
+{
+	if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_spe_id_field() != 0U;
+}
+
 /*******************************************************************************
  * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
  ******************************************************************************/
-static inline bool is_armv8_2_feat_sve_present(void)
+static inline unsigned int read_feat_sve_id_field(void)
 {
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
-		ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE);
 }
 
-/*******************************************************************************
- * Function to identify the presence of FEAT_RAS (Reliability,Availability,
- * and Serviceability Extension)
- ******************************************************************************/
-static inline bool is_armv8_2_feat_ras_present(void)
+static inline bool is_feat_sve_supported(void)
+{
+	if (ENABLE_SVE_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SVE_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_sve_id_field() >= ID_AA64PFR0_SVE_SUPPORTED;
+}
+
+static unsigned int read_feat_ras_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS);
+}
+
+static inline bool is_feat_ras_supported(void)
+{
+	if (ENABLE_FEAT_RAS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_ras_id_field() != 0U;
+}
+
+static unsigned int read_feat_dit_id_field(void)
 {
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
-		ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT);
 }
 
-/**************************************************************************
- * Function to identify the presence of FEAT_DIT (Data Independent Timing)
- *************************************************************************/
-static inline bool is_armv8_4_feat_dit_present(void)
+static inline bool is_feat_dit_supported(void)
 {
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
-		ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
+	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_dit_id_field() != 0U;
 }
 
+static inline unsigned int read_feat_tracever_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEVER);
+}
+
+static inline bool is_feat_sys_reg_trace_supported(void)
+{
+	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_tracever_id_field() != 0U;
+}
+
 /*************************************************************************
  * Function to identify the presence of FEAT_TRF (TraceLift)
  ************************************************************************/
@@ -308,12 +578,24 @@
  * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
  * Support)
  *******************************************************************************/
-static inline unsigned int get_armv8_4_feat_nv_support(void)
+static inline unsigned int read_feat_nv_id_field(void)
 {
-	return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
-		ID_AA64MMFR2_EL1_NV_MASK));
+	return ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV);
 }
 
+static inline bool is_feat_nv2_supported(void)
+{
+	if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_nv_id_field() >= ID_AA64MMFR2_EL1_NV2_SUPPORTED;
+}
+
 /*******************************************************************************
  * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
  * Extension)
@@ -356,5 +638,91 @@
 
 	return read_feat_trbe_id_field() != 0U;
 
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_SMEx (Scalar Matrix Extension)
+ ******************************************************************************/
+static inline unsigned int read_feat_sme_fa64_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64smfr0_el1(), ID_AA64SMFR0_EL1_SME_FA64);
+}
+
+static inline unsigned int read_feat_sme_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_SME);
 }
+
+static inline bool is_feat_sme_supported(void)
+{
+	if (ENABLE_SME_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SME_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME_SUPPORTED;
+}
+
+static inline bool is_feat_sme2_supported(void)
+{
+	if (ENABLE_SME2_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SME2_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
+}
+
+/*******************************************************************************
+ * Function to get hardware granularity support
+ ******************************************************************************/
+
+static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_TGRAN4);
+}
+
+static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN16);
+}
+
+static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN64);
+}
+
+static inline unsigned int read_feat_pmuv3_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER);
+}
+
+static inline unsigned int read_feat_mtpmu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU);
+}
+
+static inline bool is_feat_mtpmu_supported(void)
+{
+	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	unsigned int mtpmu = read_feat_mtpmu_id_field();
+
+	return (mtpmu != 0U) && (mtpmu != ID_AA64DFR0_MTPMU_DISABLED);
+}
+
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 81e0e06..5b3d4c2 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -522,11 +522,6 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
 
-DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
-DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
-DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
-DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)
-
 DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
 
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
@@ -545,9 +540,34 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
-/* Armv8.2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el2, SCXTNUM_EL2)
+
+/* Armv8.1 VHE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
+
+/* Armv8.2 ID Registers */
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
 
+/* Armv8.2 RAS Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(vdisr_el2, VDISR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(vsesr_el2, VSESR_EL2)
+
+/* Armv8.2 MPAM Registers */
+DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm0_el2, MPAMVPM0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm1_el2, MPAMVPM1_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm2_el2, MPAMVPM2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm3_el2, MPAMVPM3_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm4_el2, MPAMVPM4_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm5_el2, MPAMVPM5_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm6_el2, MPAMVPM6_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpm7_el2, MPAMVPM7_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamvpmv_el2, MPAMVPMV_EL2)
+
 /* Armv8.3 Pointer Authentication Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeylo_el1, APIAKeyLo_EL1)
@@ -557,6 +577,7 @@
 
 /* Armv8.4 FEAT_TRF Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(trfcr_el2, TRFCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(vncr_el2, VNCR_EL2)
 
 /* Armv8.5 MTE Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(tfsre0_el1, TFSRE0_EL1)
@@ -576,6 +597,9 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(hfgrtr_el2, HFGRTR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(hfgwtr_el2, HFGWTR_EL2)
 
+/* ARMv8.6 FEAT_ECV Register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(cntpoff_el2, CNTPOFF_EL2)
+
 /* FEAT_HCX Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
 
@@ -585,6 +609,18 @@
 /* FEAT_TCR2 Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
 
+/* FEAT_SxPIE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
+
+/* FEAT_SxPOE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
+
+/* FEAT_GCS Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el2, GCSCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el2, GCSPR_EL2)
+
 /* DynamIQ Shared Unit power management */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 66c39e5..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
 
@@ -186,11 +224,12 @@
 	.space	SPINLOCK_ASM_SIZE
 	.endm
 
-#if RAS_EXTENSION
+	/*
+	 * With RAS extension executes esb instruction, else NOP
+	 */
 	.macro esb
 	.inst	0xd503221f
 	.endm
-#endif
 
 	/*
 	 * Helper macro to read system register value into x0
@@ -215,12 +254,24 @@
 	.endm
 
 	/*
+	 * The "sb" instruction was introduced later into the architecture,
+	 * so not all toolchains understand it. Some deny its usage unless
+	 * a supported processor is specified on the build command line.
+	 * Use sb's system register encoding to work around this, we already
+	 * guard the sb execution with a feature flag.
+	 */
+
+	.macro sb_barrier_insn
+	msr	SYSREG_SB, xzr
+	.endm
+
+	/*
 	 * Macro for using speculation barrier instruction introduced by
 	 * FEAT_SB, if it's enabled.
 	 */
 	.macro speculation_barrier
 #if ENABLE_FEAT_SB
-	sb
+	sb_barrier_insn
 #else
 	dsb	sy
 	isb
@@ -234,7 +285,7 @@
 	.macro exception_return
 	eret
 #if ENABLE_FEAT_SB
-	sb
+	sb_barrier_insn
 #else
 	dsb	nsh
 	isb
diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S
index dcaea3d..9609c0d 100644
--- a/include/arch/aarch64/el2_common_macros.S
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -103,7 +103,7 @@
 	 */
 	mov_imm	x0, ((MDCR_EL2_RESET_VAL | \
 		      MDCR_SPD32(MDCR_SPD32_DISABLE)) \
-		      & ~(MDCR_EL2_HPMD | MDCR_TDOSA_BIT | \
+		      & ~(MDCR_EL2_HPMD_BIT | MDCR_TDOSA_BIT | \
 		      MDCR_TDA_BIT | MDCR_TPM_BIT))
 
 	msr	mdcr_el2, x0
@@ -244,10 +244,6 @@
 		isb
 	.endif /* _init_sctlr */
 
-#if DISABLE_MTPMU
-		bl	mtpmu_disable
-#endif
-
 	.if \_warm_boot_mailbox
 		/* -------------------------------------------------------------
 		 * This code will be executed for both warm and cold resets.
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 45a86c1..6360461 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -119,22 +119,6 @@
 	 * MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
 	 *  accesses to all Performance Monitors registers do not trap to EL3.
 	 *
-	 * MDCR_EL3.SCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
-	 *  prohibited in Secure state. This bit is RES0 in versions of the
-	 *  architecture with FEAT_PMUv3p5 not implemented, setting it to 1
-	 *  doesn't have any effect on them.
-	 *
-	 * MDCR_EL3.MCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
-	 *  prohibited in EL3. This bit is RES0 in versions of the
-	 *  architecture with FEAT_PMUv3p7 not implemented, setting it to 1
-	 *  doesn't have any effect on them.
-	 *
-	 * MDCR_EL3.SPME: Set to zero so that event counting by the programmable
-	 *  counters PMEVCNTR<n>_EL0 is prohibited in Secure state. If ARMv8.2
-	 *  Debug is not implemented this bit does not have any effect on the
-	 *  counters unless there is support for the implementation defined
-	 *  authentication interface ExternalSecureNoninvasiveDebugEnabled().
-	 *
 	 * MDCR_EL3.NSTB, MDCR_EL3.NSTBE: Set to zero so that Trace Buffer
 	 *  owning security state is Secure state. If FEAT_TRBE is implemented,
 	 *  accesses to Trace Buffer control registers at EL2 and EL1 in any
@@ -149,10 +133,9 @@
 	 * ---------------------------------------------------------------------
 	 */
 	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
-		      MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \
-		      MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \
-		      MDCR_TDA_BIT | MDCR_TPM_BIT | MDCR_NSTB(MDCR_NSTB_EL1) | \
-		      MDCR_NSTBE | MDCR_TTRF_BIT))
+		      MDCR_SPD32(MDCR_SPD32_DISABLE)) & \
+		    ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT | MDCR_TPM_BIT | \
+		      MDCR_NSTB(MDCR_NSTB_EL1) | MDCR_NSTBE | MDCR_TTRF_BIT))
 
 	mrs	x1, id_aa64dfr0_el1
 	ubfx	x1, x1, #ID_AA64DFR0_TRACEFILT_SHIFT, #ID_AA64DFR0_TRACEFILT_LENGTH
@@ -162,36 +145,6 @@
 	msr	mdcr_el3, x0
 
 	/* ---------------------------------------------------------------------
-	 * Initialise PMCR_EL0 setting all fields rather than relying
-	 * on hw. Some fields are architecturally UNKNOWN on reset.
-	 *
-	 * PMCR_EL0.LP: Set to one so that event counter overflow, that
-	 *  is recorded in PMOVSCLR_EL0[0-30], occurs on the increment
-	 *  that changes PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU
-	 *  is implemented. This bit is RES0 in versions of the architecture
-	 *  earlier than ARMv8.5, setting it to 1 doesn't have any effect
-	 *  on them.
-	 *
-	 * PMCR_EL0.LC: Set to one so that cycle counter overflow, that
-	 *  is recorded in PMOVSCLR_EL0[31], occurs on the increment
-	 *  that changes PMCCNTR_EL0[63] from 1 to 0.
-	 *
-	 * PMCR_EL0.DP: Set to one so that the cycle counter,
-	 *  PMCCNTR_EL0 does not count when event counting is prohibited.
-	 *
-	 * PMCR_EL0.X: Set to zero to disable export of events.
-	 *
-	 * PMCR_EL0.D: Set to zero so that, when enabled, PMCCNTR_EL0
-	 *  counts on every clock cycle.
-	 * ---------------------------------------------------------------------
-	 */
-	mov_imm	x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_LP_BIT | \
-		      PMCR_EL0_LC_BIT | PMCR_EL0_DP_BIT) & \
-		    ~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT))
-
-	msr	pmcr_el0, x0
-
-	/* ---------------------------------------------------------------------
 	 * Enable External Aborts and SError Interrupts now that the exception
 	 * vectors have been setup.
 	 * ---------------------------------------------------------------------
@@ -243,14 +196,20 @@
 	 * register value for DIT.
 	 */
 #if ENABLE_FEAT_DIT
-#if ENABLE_ASSERTIONS
+#if ENABLE_ASSERTIONS || ENABLE_FEAT_DIT > 1
 	mrs	x0, id_aa64pfr0_el1
 	ubfx	x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+#if ENABLE_FEAT_DIT > 1
+	cbz	x0, 1f
+#else
 	cmp	x0, #ID_AA64PFR0_DIT_SUPPORTED
 	ASM_ASSERT(eq)
+#endif
+
 #endif /* ENABLE_ASSERTIONS */
 	mov	x0, #DIT_BIT
 	msr	DIT, x0
+1:
 #endif
 	.endm
 
@@ -334,10 +293,6 @@
 		isb
 	.endif /* _init_sctlr */
 
-#if DISABLE_MTPMU
-		bl	mtpmu_disable
-#endif
-
 	.if \_warm_boot_mailbox
 		/* -------------------------------------------------------------
 		 * This code will be executed for both warm and cold resets.
diff --git a/include/bl31/ehf.h b/include/bl31/ehf.h
index c13d28c..63943a9 100644
--- a/include/bl31/ehf.h
+++ b/include/bl31/ehf.h
@@ -30,7 +30,7 @@
 		.ehf_handler = EHF_NO_HANDLER_, \
 	}
 
-/* Macro for platforms to regiter its exception priorities */
+/* Macro for platforms to register its exception priorities */
 #define EHF_REGISTER_PRIORITIES(priorities, num, bits) \
 	const ehf_priorities_t exception_data = { \
 		.num_priorities = (num), \
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
index e211575..1ac4f98 100644
--- a/include/bl31/sync_handle.h
+++ b/include/bl31/sync_handle.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +17,7 @@
 #define ISS_SYSREG_DIRECTION_MASK	0x000001UL
 
 #define ISS_SYSREG_OPCODE_RNDR		0x30c808U
+#define ISS_SYSREG_OPCODE_IMPDEF	0x303c00U
 #define ISS_SYSREG_OPCODE_RNDRRS	0x32c808U
 
 #define TRAP_RET_UNHANDLED		-1
@@ -54,6 +56,7 @@
 int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx);
 
 /* Prototypes for system register emulation handlers provided by platforms. */
+int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
 int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index b16510f..abbf976 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -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
  */
@@ -49,7 +49,7 @@
 
 static inline uint32_t fdt_blob_size(const void *dtb)
 {
-	const uint32_t *dtb_header = dtb;
+	const uint32_t *dtb_header = (const uint32_t *)dtb;
 
 	return fdt32_to_cpu(dtb_header[1]);
 }
@@ -60,7 +60,8 @@
 	const void *prop = fdt_getprop(fdt, node, "status", &len);
 
 	/* A non-existing status property means the device is enabled. */
-	return (prop == NULL) || (len == 5 && strcmp(prop, "okay") == 0);
+	return (prop == NULL) || (len == 5 && strcmp((const char *)prop,
+		"okay") == 0);
 }
 
 #define fdt_for_each_compatible_node(dtb, node, compatible_str)       \
diff --git a/include/common/uuid.h b/include/common/uuid.h
index c8dd681..6348804 100644
--- a/include/common/uuid.h
+++ b/include/common/uuid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,9 @@
 #ifndef UUID_COMMON_H
 #define UUID_COMMON_H
 
+#include <stdbool.h>
+#include <stdint.h>
+
 #define UUID_BYTES_LENGTH	16
 #define UUID_STRING_LENGTH	36
 
diff --git a/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h
index 8410024..f6d41d7 100644
--- a/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h
+++ b/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h
@@ -9,7 +9,7 @@
 */
 #ifndef _CC_PAL_TYPES_PLAT_H
 #define _CC_PAL_TYPES_PLAT_H
-/* Host specific types for standard (ISO-C99) compilant platforms */
+/* Host specific types for standard (ISO-C99) compliant platforms */
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h
index 9848472..0c102a0 100644
--- a/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h
+++ b/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h
@@ -9,7 +9,7 @@
 */
 #ifndef _CC_PAL_TYPES_PLAT_H
 #define _CC_PAL_TYPES_PLAT_H
-/* Host specific types for standard (ISO-C99) compilant platforms */
+/* Host specific types for standard (ISO-C99) compliant platforms */
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h
index dbaf16c..993dd12 100644
--- a/include/drivers/arm/ethosn.h
+++ b/include/drivers/arm/ethosn.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,16 @@
 #define ETHOSN_FNUM_IS_SEC		U(0x51)
 #define ETHOSN_FNUM_HARD_RESET		U(0x52)
 #define ETHOSN_FNUM_SOFT_RESET		U(0x53)
-/* 0x54-0x5F reserved for future use */
+#define ETHOSN_FNUM_IS_SLEEPING		U(0x54)
+#define ETHOSN_FNUM_GET_FW_PROP		U(0x55)
+#define ETHOSN_FNUM_BOOT_FW		U(0x56)
+/* 0x57-0x5F reserved for future use */
+
+/* Properties for ETHOSN_FNUM_TZMP_GET_FW_PROP */
+#define ETHOSN_FW_PROP_VERSION		U(0xF00)
+#define ETHOSN_FW_PROP_MEM_INFO		U(0xF01)
+#define ETHOSN_FW_PROP_OFFSETS		U(0xF02)
+#define ETHOSN_FW_PROP_VA_MAP		U(0xF03)
 
 /* SMC64 function IDs */
 #define ETHOSN_FID_64(func_num)		U(0xC2000000 | func_num)
@@ -38,22 +47,33 @@
 #define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE)
 
 /* Service version  */
-#define ETHOSN_VERSION_MAJOR U(2)
+#define ETHOSN_VERSION_MAJOR U(3)
 #define ETHOSN_VERSION_MINOR U(0)
 
 /* Return codes for function calls */
 #define ETHOSN_SUCCESS			 0
 #define ETHOSN_NOT_SUPPORTED		-1
 /* -2 Reserved for NOT_REQUIRED */
-/* -3 Reserved for INVALID_PARAMETER */
+#define ETHOSN_INVALID_PARAMETER	-3
 #define ETHOSN_FAILURE			-4
 #define ETHOSN_UNKNOWN_CORE_ADDRESS	-5
 #define ETHOSN_UNKNOWN_ALLOCATOR_IDX	-6
+#define ETHOSN_INVALID_CONFIGURATION    -7
+#define ETHOSN_INVALID_STATE		-8
+
+/*
+ * Argument types for soft and hard resets to indicate whether to reset
+ * and reconfigure the NPU or only halt it
+ */
+#define ETHOSN_RESET_TYPE_FULL		U(0)
+#define ETHOSN_RESET_TYPE_HALT		U(1)
+
+int ethosn_smc_setup(void);
 
 uintptr_t ethosn_smc_handler(uint32_t smc_fid,
 			     u_register_t core_addr,
 			     u_register_t asset_alloc_idx,
-			     u_register_t x3,
+			     u_register_t reset_type,
 			     u_register_t x4,
 			     void *cookie,
 			     void *handle,
diff --git a/include/drivers/arm/ethosn_cert.h b/include/drivers/arm/ethosn_cert.h
new file mode 100644
index 0000000..7aa887d
--- /dev/null
+++ b/include/drivers/arm/ethosn_cert.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ETHOSN_CERT_H
+#define ETHOSN_CERT_H
+
+#include "ethosn_oid.h"
+#include <tbbr/tbb_ext.h>
+#include <tbbr/tbb_key.h>
+
+/* Arm(R) Ethos(TM)-N NPU Certificates */
+#define ETHOSN_NPU_FW_KEY_CERT_DEF {							\
+	.id = ETHOSN_NPU_FW_KEY_CERT,							\
+	.opt = "npu-fw-key-cert",							\
+	.help_msg = "Arm(R) Ethos(TM)-N NPU Firmware Key Certificate (output file)",	\
+	.fn = NULL,									\
+	.cn = "NPU Firmware Key Certificate",						\
+	.key = NON_TRUSTED_WORLD_KEY,							\
+	.issuer = ETHOSN_NPU_FW_KEY_CERT,						\
+	.ext = {									\
+		NON_TRUSTED_FW_NVCOUNTER_EXT,						\
+		ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT,					\
+	},										\
+	.num_ext = 2 \
+}
+
+#define ETHOSN_NPU_FW_CONTENT_CERT_DEF {							\
+	.id = ETHOSN_NPU_FW_CONTENT_CERT,						\
+	.opt = "npu-fw-cert",								\
+	.help_msg = "Arm(R) Ethos(TM)-N NPU Firmware Content Certificate (output file)",\
+	.fn = NULL,									\
+	.cn = "NPU Firmware Content Certificate",					\
+	.key = ETHOSN_NPU_FW_CONTENT_CERT_KEY,						\
+	.issuer = ETHOSN_NPU_FW_CONTENT_CERT,						\
+	.ext = {									\
+		NON_TRUSTED_FW_NVCOUNTER_EXT,						\
+		ETHOSN_NPU_FW_HASH_EXT,							\
+	},										\
+	.num_ext = 2 \
+}
+
+/* NPU Extensions */
+#define ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT_DEF {						\
+	.oid = ETHOSN_NPU_FW_CONTENT_CERT_PK_OID,					\
+	.help_msg = "Arm(R) Ethos(TM)-N NPU Firmware content certificate public key",	\
+	.sn = "NPUFirmwareContentCertPK",						\
+	.ln = "NPU Firmware content cerificate public key",				\
+	.asn1_type = V_ASN1_OCTET_STRING,						\
+	.type = EXT_TYPE_PKEY,								\
+	.attr.key = ETHOSN_NPU_FW_CONTENT_CERT_KEY \
+}
+
+#define ETHOSN_NPU_FW_HASH_EXT_DEF {						\
+	.oid = ETHOSN_NPU_FW_BINARY_OID,					\
+	.opt = "npu-fw",							\
+	.help_msg = "Arm(R) Ethos(TM)-N NPU Firmware image file (input file)",	\
+	.sn = "NPUFirmwareHash",						\
+	.ln = "NPU Firmware Hash (SHA256)",					\
+	.asn1_type = V_ASN1_OCTET_STRING,					\
+	.type = EXT_TYPE_HASH \
+}
+
+/* NPU Keys */
+#define ETHOSN_NPU_FW_CONTENT_CERT_KEY_DEF {							  \
+	.id = ETHOSN_NPU_FW_CONTENT_CERT_KEY,							  \
+	.opt = "npu-fw-key",									  \
+	.help_msg = "Arm(R) Ethos(TM)-N NPU Firmware Content Certificate key (input/output file)",\
+	.desc = "NPU Firmware Content Certificate key"						  \
+}
+
+#endif  /* ETHOSN_CERT_H */
diff --git a/include/drivers/arm/ethosn_fip.h b/include/drivers/arm/ethosn_fip.h
new file mode 100644
index 0000000..f2c7f93
--- /dev/null
+++ b/include/drivers/arm/ethosn_fip.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ETHOSN_FIP_H
+#define ETHOSN_FIP_H
+
+#define UUID_ETHOSN_FW_KEY_CERTIFICATE					\
+	{ { 0x56, 0x66, 0xd0, 0x04 }, { 0xab, 0x98 }, { 0x40, 0xaa },	\
+	0x89, 0x88, { 0xb7, 0x2a, 0x3, 0xa2, 0x56, 0xe2 } }
+
+#define UUID_ETHOSN_FW_CONTENT_CERTIFICATE				\
+	{ { 0xa5, 0xc4, 0x18, 0xda }, { 0x43, 0x0f }, { 0x48, 0xb1 },	\
+	0x88, 0xcd, { 0x93, 0xf6, 0x78, 0x89, 0xd9, 0xed } }
+
+#define UUID_ETHOSN_FW							\
+	{ { 0xcf, 0xd4, 0x99, 0xb5 }, { 0xa3, 0xbc }, { 0x4a, 0x7e },	\
+	0x98, 0xcb, { 0x48, 0xa4, 0x1c, 0xb8, 0xda, 0xe1 } }
+
+#define ETHOSN_FW_KEY_CERTIFICATE_DEF				\
+	{ "Arm(R) Ethos(TM)-N NPU Firmware Key Certificate",	\
+	  UUID_ETHOSN_FW_KEY_CERTIFICATE,			\
+	  "npu-fw-key-cert" }
+
+#define ETHOSN_FW_CONTENT_CERTIFICATE_DEF			\
+	{ "Arm(R) Ethos(TM)-N NPU Firmware Content Certificate",\
+	  UUID_ETHOSN_FW_CONTENT_CERTIFICATE,			\
+	  "npu-fw-cert" }
+
+#define ETHOSN_FW_DEF						\
+	{ "Arm(R) Ethos(TM)-N NPU Firmware",			\
+	  UUID_ETHOSN_FW,					\
+	  "npu-fw" }
+
+#endif /* ETHOSN_FIP_H */
diff --git a/include/drivers/arm/ethosn_oid.h b/include/drivers/arm/ethosn_oid.h
new file mode 100644
index 0000000..a83cd09
--- /dev/null
+++ b/include/drivers/arm/ethosn_oid.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ETHOSN_OID_H
+#define ETHOSN_OID_H
+
+/* Arm(R) Ethos(TM)-N NPU Platform OID */
+#define ETHOSN_NPU_FW_CONTENT_CERT_PK_OID	"1.3.6.1.4.1.4128.2300.1"
+#define ETHOSN_NPU_FW_BINARY_OID		"1.3.6.1.4.1.4128.2300.2"
+
+#endif  /* ETHOSN_OID_H */
diff --git a/include/drivers/arm/gic600_multichip.h b/include/drivers/arm/gic600_multichip.h
index bda406b..978d735 100644
--- a/include/drivers/arm/gic600_multichip.h
+++ b/include/drivers/arm/gic600_multichip.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,8 +16,11 @@
  */
 #define GIC600_MAX_MULTICHIP	16
 
-/* SPI IDs array consist of min and max ids */
-#define GIC600_SPI_IDS_SIZE	2
+typedef struct multichip_spi_ids_desc {
+	uintptr_t gicd_base;
+	uint32_t spi_id_min;
+	uint32_t spi_id_max;
+} multichip_spi_ids_desc_t;
 
 /*******************************************************************************
  * GIC-600 multichip data structure describes platform specific attributes
@@ -37,19 +41,23 @@
  * The 'chip_addrs' field contains array of chip addresses. These addresses are
  * implementation specific values.
  *
- * The 'spi_ids' field contains array of minimum and maximum SPI interrupt ids
- * that each chip owns. Note that SPI interrupt ids can range from 32 to 960 and
- * it should be group of 32 (i.e., SPI minimum and (SPI maximum + 1) should be
- * a multiple of 32). If a chip doesn't own any SPI interrupts a value of {0, 0}
- * should be passed.
+ * The 'multichip_spi_ids_desc_t' field contains array of descriptors used to
+ * provide minimum and maximum SPI interrupt ids that each chip owns and the
+ * corresponding chip base address. Note that SPI interrupt ids can range from
+ * 32 to 960 and it should be group of 32 (i.e., SPI minimum and (SPI maximum +
+ * 1) should be a multiple of 32). If a chip doesn't own any SPI interrupts a
+ * value of {0, 0, 0} should be passed.
  ******************************************************************************/
 struct gic600_multichip_data {
 	uintptr_t rt_owner_base;
 	unsigned int rt_owner;
 	unsigned int chip_count;
 	uint64_t chip_addrs[GIC600_MAX_MULTICHIP];
-	unsigned int spi_ids[GIC600_MAX_MULTICHIP][GIC600_SPI_IDS_SIZE];
+	multichip_spi_ids_desc_t spi_ids[GIC600_MAX_MULTICHIP];
 };
 
+uintptr_t gic600_multichip_gicd_base_for_spi(uint32_t spi_id);
 void gic600_multichip_init(struct gic600_multichip_data *multichip_data);
+bool gic600_multichip_is_initialized(void);
+
 #endif /* GIC600_MULTICHIP_H */
diff --git a/include/drivers/arm/gic600ae_fmu.h b/include/drivers/arm/gic600ae_fmu.h
index 88b87b9..d2a92dd 100644
--- a/include/drivers/arm/gic600ae_fmu.h
+++ b/include/drivers/arm/gic600ae_fmu.h
@@ -85,7 +85,7 @@
 #define FMU_BLK_PPI31		U(43)
 #define FMU_BLK_PRESENT_MASK	U(0xFFFFFFFFFFF)
 
-/* Safety Mechamism limit */
+/* Safety Mechanism limit */
 #define FMU_SMID_GICD_MAX	U(33)
 #define FMU_SMID_PPI_MAX	U(12)
 #define FMU_SMID_ITS_MAX	U(14)
diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h
index 9403634..4ca7194 100644
--- a/include/drivers/arm/sbsa.h
+++ b/include/drivers/arm/sbsa.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,12 @@
 
 #include <stdint.h>
 
-/* Register Offsets */
+/* SBSA Secure Watchdog Register Offsets */
+/* Refresh frame */
+#define SBSA_WDOG_WRR_OFFSET		UL(0x000)
+#define SBSA_WDOG_WRR_REFRESH		UL(0x1)
+
+/* Control and status frame */
 #define SBSA_WDOG_WCS_OFFSET		UL(0x000)
 #define SBSA_WDOG_WOR_LOW_OFFSET	UL(0x008)
 #define SBSA_WDOG_WOR_HIGH_OFFSET	UL(0x00C)
@@ -20,5 +25,6 @@
 
 void sbsa_wdog_start(uintptr_t base, uint64_t ms);
 void sbsa_wdog_stop(uintptr_t base);
+void sbsa_wdog_refresh(uintptr_t refresh_base);
 
 #endif /* SBSA_H */
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index 3a23df4..bec19da 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.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
  */
@@ -46,14 +46,12 @@
 	const char *name;
 
 	/* Initialize library. This function is not expected to fail. All errors
-	 * must be handled inside the function, asserting or panicing in case of
+	 * must be handled inside the function, asserting or panicking in case of
 	 * a non-recoverable error */
 	void (*init)(void);
 
 	/* Verify a digital signature. Return one of the
 	 * 'enum crypto_ret_value' options */
-#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	int (*verify_signature)(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
 				void *sig_alg, unsigned int sig_alg_len,
@@ -62,17 +60,15 @@
 	/* Verify a hash. Return one of the 'enum crypto_ret_value' options */
 	int (*verify_hash)(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
-#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
-#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	/* Calculate a hash. Return hash value */
 	int (*calc_hash)(enum crypto_md_algo md_alg, void *data_ptr,
 			 unsigned int data_len,
 			 unsigned char output[CRYPTO_MD_MAX_SIZE]);
-#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+
+	/* Convert Public key (optional) */
+	int (*convert_pk)(void *full_pk_ptr, unsigned int full_pk_len,
+			  void **hashed_pk_ptr, unsigned int *hashed_pk_len);
 
 	/*
 	 * Authenticated decryption. Return one of the
@@ -94,16 +90,16 @@
 }
 #endif /* CRYPTO_SUPPORT */
 
-#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+#if (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY) || \
+    (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC)
 int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
 				void *sig_alg_ptr, unsigned int sig_alg_len,
 				void *pk_ptr, unsigned int pk_len);
 int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
-#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+#endif /* (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY) || \
+	  (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC) */
 
 int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
 			    size_t len, const void *key, unsigned int key_len,
@@ -111,44 +107,29 @@
 			    unsigned int iv_len, const void *tag,
 			    unsigned int tag_len);
 
-#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+#if (CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY) || \
+    (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC)
 int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
 			 unsigned int data_len,
 			 unsigned char output[CRYPTO_MD_MAX_SIZE]);
-#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+#endif /* (CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY) || \
+	  (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC) */
+
+int crypto_mod_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			  void **hashed_pk_ptr, unsigned int *hashed_pk_len);
 
-#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /* Macro to register a cryptographic library */
 #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
-			    _calc_hash, _auth_decrypt) \
-	const crypto_lib_desc_t crypto_lib_desc = { \
-		.name = _name, \
-		.init = _init, \
-		.verify_signature = _verify_signature, \
-		.verify_hash = _verify_hash, \
-		.calc_hash = _calc_hash, \
-		.auth_decrypt = _auth_decrypt \
-	}
-#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
-#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
-			    _auth_decrypt) \
+			    _calc_hash, _auth_decrypt, _convert_pk) \
 	const crypto_lib_desc_t crypto_lib_desc = { \
 		.name = _name, \
 		.init = _init, \
 		.verify_signature = _verify_signature, \
 		.verify_hash = _verify_hash, \
-		.auth_decrypt = _auth_decrypt \
-	}
-#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
-#define REGISTER_CRYPTO_LIB(_name, _init, _calc_hash) \
-	const crypto_lib_desc_t crypto_lib_desc = { \
-		.name = _name, \
-		.init = _init, \
 		.calc_hash = _calc_hash, \
+		.auth_decrypt = _auth_decrypt, \
+		.convert_pk = _convert_pk \
 	}
-#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 extern const crypto_lib_desc_t crypto_lib_desc;
 
diff --git a/include/drivers/brcm/emmc/emmc_csl_sdprot.h b/include/drivers/brcm/emmc/emmc_csl_sdprot.h
index 597e1e0..5801940 100644
--- a/include/drivers/brcm/emmc/emmc_csl_sdprot.h
+++ b/include/drivers/brcm/emmc/emmc_csl_sdprot.h
@@ -139,7 +139,7 @@
  * The Common I/O area shall be implemented on all SDIO cards and
  * is accessed the the host via I/O reads and writes to function 0,
  * the registers within the CIA are provided to enable/disable
- * the operationo fthe i/o funciton.
+ * the operationo fthe i/o function.
  */
 
 /* cccr_sdio_rev */
@@ -303,7 +303,7 @@
 #define SBSDIO_CIS_BASE_COMMON		0x1000
 /* function 0(common) cis size in bytes */
 #define SBSDIO_CIS_FUNC0_LIMIT		0x020
-/* funciton 1 cis size in bytes */
+/* function 1 cis size in bytes */
 #define SBSDIO_CIS_SIZE_LIMIT		0x200
 /* cis offset addr is < 17 bits */
 #define SBSDIO_CIS_OFT_ADDR_MASK	0x1FFFF
@@ -313,7 +313,7 @@
 /* indirect cis access (in sprom) */
 /* 8 control bytes first, CIS starts from 8th uint8_t */
 #define SBSDIO_SPROM_CIS_OFFSET		0x8
-/* sdio uint8_t mode: maximum length of one data comamnd */
+/* sdio uint8_t mode: maximum length of one data command */
 #define SBSDIO_BYTEMODE_DATALEN_MAX	64
 /* 4317 supports less */
 #define SBSDIO_BYTEMODE_DATALEN_MAX_4317	52
diff --git a/include/drivers/brcm/i2c/i2c.h b/include/drivers/brcm/i2c/i2c.h
index 24d42e2..2cc81d5 100644
--- a/include/drivers/brcm/i2c/i2c.h
+++ b/include/drivers/brcm/i2c/i2c.h
@@ -78,7 +78,7 @@
  *
  * Description:
  *	This function reads I2C data from a device without specifying
- *	a command regsiter.
+ *	a command register.
  *
  * Parameters:
  *	bus_id  - I2C bus ID
@@ -95,7 +95,7 @@
  *
  * Description:
  *	This function send I2C data to a device without specifying
- *	a command regsiter.
+ *	a command register.
  *
  * Parameters:
  *	bus_id  - I2C bus ID
diff --git a/include/drivers/cadence/cdns_combo_phy.h b/include/drivers/cadence/cdns_combo_phy.h
new file mode 100644
index 0000000..f5dabda
--- /dev/null
+++ b/include/drivers/cadence/cdns_combo_phy.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDN_COMBOPHY_H
+#define CDN_COMBOPHY_H
+
+/* SRS */
+#define SDMMC_CDN_SRS02			0x8
+#define SDMMC_CDN_SRS03			0xC
+#define SDMMC_CDN_SRS04			0x10
+#define SDMMC_CDN_SRS05			0x14
+#define SDMMC_CDN_SRS06			0x18
+#define SDMMC_CDN_SRS07			0x1C
+#define SDMMC_CDN_SRS09			0x24
+#define SDMMC_CDN_SRS10			0x28
+#define SDMMC_CDN_SRS11			0x2C
+#define SDMMC_CDN_SRS12			0x30
+#define SDMMC_CDN_SRS13			0x34
+#define SDMMC_CDN_SRS14			0x38
+
+/* SRS03 */
+/* Response Type Select
+ * Defines the expected response length.
+ */
+#define SDMMC_CDN_RTS				16
+
+/* Command CRC Check Enable
+ * When set to 1, the host checks if the CRC field of the response is valid.
+ * When 0, the CRC check is disabled and the CRC field of the response is ignored.
+ */
+#define SDMMC_CDN_CRCCE				19
+
+/* Command Index
+ * This field contains a command number (index) of the command to be sent.
+ */
+#define SDMMC_CDN_CIDX				24
+
+/* SRS09 */
+/* Card Inserted
+ * Indicates if the card is inserted inside the slot.
+ */
+#define SDMMC_CDN_CI				16
+
+/* SRS10 */
+/* Data Transfer Width
+ * Bit used to configure DAT bus width to 1 or 4.
+ */
+#define SDMMC_CDN_DTW				1
+
+/* Extended Data Transfer Width
+ * This bit is to enable/disable 8-bit DAT bus width mode.
+ */
+#define SDMMC_CDN_EDTW				5
+
+/* SD Bus Power for VDD1
+ * When set to 1, the VDD1 voltage is supplied to card/device.
+ */
+#define SDMMC_CDN_BP				8
+
+/* SD Bus Voltage Select
+ * This field is used to configure VDD1 voltage level.
+ */
+#define SDMMC_CDN_BVS				9
+
+/* SRS11 */
+/* Internal Clock Enable
+ * This field is designated to controls (enable/disable) external clock generator.
+ */
+#define SDMMC_CDN_ICE				0
+
+/* Internal Clock Stable
+ * When 1, indicates that the clock on sdmclk pin of the host is stable.
+ * When 0, indicates that the clock is not stable .
+ */
+#define SDMMC_CDN_ICS				1
+
+/* SD Clock Enable
+ * When set, SDCLK clock is enabled.
+ * When clear, SDCLK clock is stopped.
+ */
+#define SDMMC_CDN_SDCE				2
+
+/* USDCLK Frequency Select
+ * This is used to calculate frequency of USDCLK clock.
+ */
+#define SDMMC_CDN_USDCLKFS			6
+
+/* SDCLK Frequency Select
+ * This is used to calculate frequency of SDCLK clock.
+ */
+#define SDMMC_CDN_SDCLKFS				8
+
+/* Data Timeout Counter Value
+ * This value determines the interval by which DAT line timeouts are detected
+ */
+#define SDMMC_CDN_DTCV				16
+
+/* SRS12 */
+/* Command Complete
+ * Generated when the end bit of the response is received.
+ */
+#define SDMMC_CDN_CC				0
+
+/* Transfer Complete
+ * Generated when the transfer which uses the DAT line is complete.
+ */
+#define SDMMC_CDN_TC				1
+
+/* Error Interrupt
+ * The software can check for an error by reading this single bit first.
+ */
+#define SDMMC_CDN_EINT				15
+
+/* SRS14 */
+/* Command Complete Interrupt Enable */
+#define SDMMC_CDN_CC_IE				0
+
+/* Transfer Complete Interrupt Enable */
+#define SDMMC_CDN_TC_IE				1
+
+/* DMA Interrupt Enable */
+#define SDMMC_CDN_DMAINT_IE			3
+
+/* Combo PHY DLL registers */
+#define CP_DLL_REG_BASE			(0x10B92000)
+#define CP_DLL_DQ_TIMING_REG		(0x00)
+#define CP_DLL_DQS_TIMING_REG		(0x04)
+#define CP_DLL_GATE_LPBK_CTRL_REG	(0x08)
+#define CP_DLL_MASTER_CTRL_REG		(0x0C)
+#define CP_DLL_SLAVE_CTRL_REG		(0x10)
+#define CP_DLL_IE_TIMING_REG		(0x14)
+
+#define CP_DQ_TIMING_REG_SDR		(0x00000002)
+#define CP_DQS_TIMING_REG_SDR		(0x00100004)
+#define CP_GATE_LPBK_CTRL_REG_SDR	(0x00D80000)
+#define CP_DLL_MASTER_CTRL_REG_SDR	(0x00800000)
+#define CP_DLL_SLAVE_CTRL_REG_SDR	(0x00000000)
+
+#define CP_DLL(_reg)			(CP_DLL_REG_BASE \
+					+ (CP_DLL_##_reg))
+
+/* Control Timing Block registers */
+#define CP_CTB_REG_BASE			(0x10B92080)
+#define CP_CTB_CTRL_REG			(0x00)
+#define CP_CTB_TSEL_REG			(0x04)
+#define CP_CTB_GPIO_CTRL0		(0x08)
+#define CP_CTB_GPIO_CTRL1		(0x0C)
+#define CP_CTB_GPIO_STATUS0		(0x10)
+#define CP_CTB_GPIO_STATUS1		(0x14)
+
+#define CP_CTRL_REG_SDR			(0x00004040)
+#define CP_TSEL_REG_SDR			(0x00000000)
+
+#define CP_CTB(_reg)			(CP_CTB_REG_BASE \
+					+ (CP_CTB_##_reg))
+
+/* Combo PHY */
+#define SDMMC_CDN_REG_BASE		0x10808200
+#define PHY_DQ_TIMING_REG		0x2000
+#define PHY_DQS_TIMING_REG		0x2004
+#define PHY_GATE_LPBK_CTRL_REG		0x2008
+#define PHY_DLL_MASTER_CTRL_REG		0x200C
+#define PHY_DLL_SLAVE_CTRL_REG		0x2010
+#define PHY_CTRL_REG			0x2080
+#define PHY_REG_ADDR_MASK		0xFFFF
+#define PHY_REG_DATA_MASK		0xFFFFFFFF
+
+/* PHY_DQS_TIMING_REG */
+#define CP_USE_EXT_LPBK_DQS(x)		((x) << 22) //0x1
+#define CP_USE_LPBK_DQS(x)		((x) << 21) //0x1
+#define CP_USE_PHONY_DQS(x)		((x) << 20) //0x1
+#define CP_USE_PHONY_DQS_CMD(x)		((x) << 19) //0x1
+
+/* PHY_GATE_LPBK_CTRL_REG */
+#define CP_SYNC_METHOD(x)		((x) << 31) //0x1
+#define CP_SW_HALF_CYCLE_SHIFT(x)	((x) << 28) //0x1
+#define CP_RD_DEL_SEL(x)		((x) << 19) //0x3f
+#define CP_UNDERRUN_SUPPRESS(x)		((x) << 18) //0x1
+#define CP_GATE_CFG_ALWAYS_ON(x)	((x) << 6) //0x1
+
+/* PHY_DLL_MASTER_CTRL_REG */
+#define CP_DLL_BYPASS_MODE(x)		((x) << 23) //0x1
+#define CP_DLL_START_POINT(x)		((x) << 0) //0xff
+
+/* PHY_DLL_SLAVE_CTRL_REG */
+#define CP_READ_DQS_CMD_DELAY(x)	((x) << 24) //0xff
+#define CP_CLK_WRDQS_DELAY(x)		((x) << 16) //0xff
+#define CP_CLK_WR_DELAY(x)		((x) << 8) //0xff
+#define CP_READ_DQS_DELAY(x)		((x) << 0) //0xff
+
+/* PHY_DQ_TIMING_REG */
+#define CP_IO_MASK_ALWAYS_ON(x)		((x) << 31) //0x1
+#define CP_IO_MASK_END(x)		((x) << 27) //0x7
+#define CP_IO_MASK_START(x)		((x) << 24) //0x7
+#define CP_DATA_SELECT_OE_END(x)	((x) << 0) //0x7
+
+/* PHY_CTRL_REG */
+#define CP_PHONY_DQS_TIMING_MASK	0x3F
+#define CP_PHONY_DQS_TIMING_SHIFT	4
+
+/* Shared Macros */
+#define SDMMC_CDN(_reg)			(SDMMC_CDN_REG_BASE + \
+					(SDMMC_CDN_##_reg))
+
+struct cdns_sdmmc_combo_phy {
+	uint32_t	cp_clk_wr_delay;
+	uint32_t	cp_clk_wrdqs_delay;
+	uint32_t	cp_data_select_oe_end;
+	uint32_t	cp_dll_bypass_mode;
+	uint32_t	cp_dll_locked_mode;
+	uint32_t	cp_dll_start_point;
+	uint32_t	cp_gate_cfg_always_on;
+	uint32_t	cp_io_mask_always_on;
+	uint32_t	cp_io_mask_end;
+	uint32_t	cp_io_mask_start;
+	uint32_t	cp_rd_del_sel;
+	uint32_t	cp_read_dqs_cmd_delay;
+	uint32_t	cp_read_dqs_delay;
+	uint32_t	cp_sw_half_cycle_shift;
+	uint32_t	cp_sync_method;
+	uint32_t	cp_underrun_suppress;
+	uint32_t	cp_use_ext_lpbk_dqs;
+	uint32_t	cp_use_lpbk_dqs;
+	uint32_t	cp_use_phony_dqs;
+	uint32_t	cp_use_phony_dqs_cmd;
+};
+
+/* Function Prototype */
+
+int cdns_sdmmc_write_phy_reg(uint32_t phy_reg_addr, uint32_t phy_reg_addr_value,
+			uint32_t phy_reg_data, uint32_t phy_reg_data_value);
+int cdns_sd_card_detect(void);
+int cdns_emmc_card_reset(void);
+
+#endif
diff --git a/include/drivers/cadence/cdns_nand.h b/include/drivers/cadence/cdns_nand.h
new file mode 100644
index 0000000..64ba267
--- /dev/null
+++ b/include/drivers/cadence/cdns_nand.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDN_NAND_H
+#define CDN_NAND_H
+
+#include <drivers/cadence/cdns_combo_phy.h>
+
+/* NAND flash device information */
+typedef struct cnf_dev_info {
+	uint8_t type;
+	uint8_t nluns;
+	uint8_t sector_cnt;
+	uint16_t npages_per_block;
+	uint16_t sector_size;
+	uint16_t last_sector_size;
+	uint16_t page_size;
+	uint16_t spare_size;
+	uint32_t nblocks_per_lun;
+	uint32_t block_size;
+	unsigned long long total_size;
+} cnf_dev_info_t;
+
+/* Shared Macros */
+
+/* Default values */
+#define CNF_DEF_VOL_ID					0
+#define CNF_DEF_DEVICE					0
+#define CNF_DEF_TRD					0
+#define CNF_READ_SINGLE_PAGE				1
+#define CNF_DEF_DELAY_US				500
+#define CNF_READ_INT_DELAY_US				10
+
+/* Work modes */
+#define CNF_WORK_MODE_CDMA				0
+#define CNF_WORK_MODE_PIO				1
+
+/* Command types */
+#define CNF_CT_SET_FEATURE				0x0100
+#define CNF_CT_RESET_ASYNC				0x1100
+#define CNF_CT_RESET_SYNC				0x1101
+#define CNF_CT_RESET_LUN				0x1102
+#define CNF_CT_ERASE					0x1000
+#define CNF_CT_PAGE_PROGRAM				0x2100
+#define CNF_CT_PAGE_READ				0x2200
+
+/* Interrupts enable or disable */
+#define CNF_INT_EN					1
+#define CNF_INT_DIS					0
+
+/* Device types */
+#define CNF_DT_UNKNOWN					0x00
+#define CNF_DT_ONFI					0x01
+#define CNF_DT_JEDEC					0x02
+#define CNF_DT_LEGACY					0x03
+
+/* Command and status registers */
+#define CNF_CMDREG_REG_BASE				SOCFPGA_NAND_REG_BASE
+
+/* DMA maximum burst size 0-127*/
+#define CNF_DMA_BURST_SIZE_MAX				127
+
+/* DMA settings register field offsets */
+#define CNF_DMA_SETTINGS_BURST				0
+#define CNF_DMA_SETTINGS_OTE				16
+#define CNF_DMA_SETTINGS_SDMA_ERR			17
+
+#define CNF_DMA_MASTER_SEL				1
+#define CNF_DMA_SLAVE_SEL				0
+
+/* DMA FIFO trigger level register field offsets */
+#define CNF_FIFO_TLEVEL_POS				0
+#define CNF_FIFO_TLEVEL_DMA_SIZE			16
+#define CNF_DMA_PREFETCH_SIZE				(1024 / 8)
+
+#define CNF_GET_CTRL_BUSY(x)				(x & (1 << 8))
+#define CNF_GET_INIT_COMP(x)				(x & (1 << 9))
+
+/* Command register0 field offsets */
+#define CNF_CMDREG0_CT					30
+#define CNF_CMDREG0_TRD					24
+#define CNF_CMDREG0_INTR				20
+#define CNF_CMDREG0_DMA					21
+#define CNF_CMDREG0_VOL					16
+#define CNF_CMDREG0_CMD					0
+#define CNF_CMDREG4_MEM					24
+
+/* Command status register field offsets */
+#define CNF_ECMD					BIT(0)
+#define CNF_EECC					BIT(1)
+#define CNF_EMAX					BIT(2)
+#define CNF_EDEV					BIT(12)
+#define CNF_EDQS					BIT(13)
+#define CNF_EFAIL					BIT(14)
+#define CNF_CMPLT					BIT(15)
+#define CNF_EBUS					BIT(16)
+#define CNF_EDI						BIT(17)
+#define CNF_EPAR					BIT(18)
+#define CNF_ECTX					BIT(19)
+#define CNF_EPRO					BIT(20)
+#define CNF_EIDX					BIT(24)
+
+#define CNF_CMDREG_CMD_REG0				0x00
+#define CNF_CMDREG_CMD_REG1				0x04
+#define CNF_CMDREG_CMD_REG2				0x08
+#define CNF_CMDREG_CMD_REG3				0x0C
+#define CNF_CMDREG_CMD_STAT_PTR				0x10
+#define CNF_CMDREG_CMD_STAT				0x14
+#define CNF_CMDREG_CMD_REG4				0x20
+#define CNF_CMDREG_CTRL_STATUS				0x118
+#define CNF_CMDREG_TRD_STATUS				0x120
+
+#define CNF_CMDREG(_reg)				(CNF_CMDREG_REG_BASE \
+							+ (CNF_CMDREG_##_reg))
+
+/* Controller configuration registers */
+#define CNF_LSB16_MASK					0xFFFF
+#define CNF_GET_NPAGES_PER_BLOCK(x)			(x & CNF_LSB16_MASK)
+
+#define CNF_GET_SCTR_SIZE(x)				(x & CNF_LSB16_MASK)
+#define CNF_GET_LAST_SCTR_SIZE(x)			((x >> 16) & CNF_LSB16_MASK)
+
+#define CNF_GET_PAGE_SIZE(x)				(x & CNF_LSB16_MASK)
+#define CNF_GET_SPARE_SIZE(x)				((x >> 16) & CNF_LSB16_MASK)
+
+#define CNF_CTRLCFG_REG_BASE				0x10B80400
+#define CNF_CTRLCFG_TRANS_CFG0				0x00
+#define CNF_CTRLCFG_TRANS_CFG1				0x04
+#define CNF_CTRLCFG_LONG_POLL				0x08
+#define CNF_CTRLCFG_SHORT_POLL				0x0C
+#define CNF_CTRLCFG_DEV_STAT				0x10
+#define CNF_CTRLCFG_DEV_LAYOUT				0x24
+#define CNF_CTRLCFG_ECC_CFG0				0x28
+#define CNF_CTRLCFG_ECC_CFG1				0x2C
+#define CNF_CTRLCFG_MULTIPLANE_CFG			0x34
+#define CNF_CTRLCFG_CACHE_CFG				0x38
+#define CNF_CTRLCFG_DMA_SETTINGS			0x3C
+#define CNF_CTRLCFG_FIFO_TLEVEL				0x54
+
+#define CNF_CTRLCFG(_reg)				(CNF_CTRLCFG_REG_BASE \
+							+ (CNF_CTRLCFG_##_reg))
+
+/* Data integrity registers */
+#define CNF_DI_PAR_EN					0
+#define CNF_DI_CRC_EN					1
+
+#define CNF_DI_REG_BASE					0x10B80700
+#define CNF_DI_CONTROL					0x00
+#define CNF_DI_INJECT0					0x04
+#define CNF_DI_INJECT1					0x08
+#define CNF_DI_ERR_REG_ADDR				0x0C
+#define CNF_DI_INJECT2					0x10
+
+#define CNF_DI(_reg)					(CNF_DI_REG_BASE \
+							+ (CNF_DI_##_reg))
+
+/* Controller parameter registers */
+#define CNF_NTHREADS_MASK				0x07
+#define CNF_GET_NLUNS(x)				(x & 0xFF)
+#define CNF_GET_DEV_TYPE(x)				((x >> 30) & 0x03)
+#define CNF_GET_NTHREADS(x)				(1 << (x & CNF_NTHREADS_MASK))
+
+#define CNF_CTRLPARAM_REG_BASE				0x10B80800
+#define CNF_CTRLPARAM_VERSION				0x00
+#define CNF_CTRLPARAM_FEATURE				0x04
+#define CNF_CTRLPARAM_MFR_ID				0x08
+#define CNF_CTRLPARAM_DEV_AREA				0x0C
+#define CNF_CTRLPARAM_DEV_PARAMS0			0x10
+#define CNF_CTRLPARAM_DEV_PARAMS1			0x14
+#define CNF_CTRLPARAM_DEV_FEATUERS			0x18
+#define CNF_CTRLPARAM_DEV_BLOCKS_PLUN			0x1C
+
+#define CNF_CTRLPARAM(_reg)				(CNF_CTRLPARAM_REG_BASE \
+							+ (CNF_CTRLPARAM_##_reg))
+
+/* Protection mechanism registers */
+#define CNF_PROT_REG_BASE				0x10B80900
+#define CNF_PROT_CTRL0					0x00
+#define CNF_PROT_DOWN0					0x04
+#define CNF_PROT_UP0					0x08
+#define CNF_PROT_CTRL1					0x10
+#define CNF_PROT_DOWN1					0x14
+#define CNF_PROT_UP1					0x18
+
+#define CNF_PROT(_reg)					(CNF_PROT_REG_BASE \
+							+ (CNF_PROT_##_reg))
+
+/* Mini controller registers */
+#define CNF_MINICTRL_REG_BASE				0x10B81000
+
+/* Operation work modes */
+#define CNF_OPR_WORK_MODE_SDR				0
+#define CNF_OPR_WORK_MODE_NVDDR				1
+#define CNF_OPR_WORK_MODE_TOGGLE_NVDDR2_3		2
+#define CNF_OPR_WORK_MODE_RES				3
+
+/* Mini controller common settings register field offsets */
+#define CNF_CMN_SETTINGS_WR_WUP				20
+#define CNF_CMN_SETTINGS_RD_WUP				16
+#define CNF_CMN_SETTINGS_DEV16				8
+#define CNF_CMN_SETTINGS_OPR				0
+
+/* Async mode register field offsets */
+#define CNF_ASYNC_TIMINGS_TRH				24
+#define CNF_ASYNC_TIMINGS_TRP				16
+#define CNF_ASYNC_TIMINGS_TWH				8
+#define CNF_ASYNC_TIMINGS_TWP				0
+
+/* Mini controller DLL PHY controller register field offsets */
+#define CNF_DLL_PHY_RST_N				24
+#define CNF_DLL_PHY_EXT_WR_MODE				17
+#define CNF_DLL_PHY_EXT_RD_MODE				16
+
+#define CNF_MINICTRL_WP_SETTINGS			0x00
+#define CNF_MINICTRL_RBN_SETTINGS			0x04
+#define CNF_MINICTRL_CMN_SETTINGS			0x08
+#define CNF_MINICTRL_SKIP_BYTES_CFG			0x0C
+#define CNF_MINICTRL_SKIP_BYTES_OFFSET			0x10
+#define CNF_MINICTRL_TOGGLE_TIMINGS0			0x14
+#define CNF_MINICTRL_TOGGLE_TIMINGS1			0x18
+#define CNF_MINICTRL_ASYNC_TOGGLE_TIMINGS		0x1C
+#define CNF_MINICTRL_SYNC_TIMINGS			0x20
+#define CNF_MINICTRL_DLL_PHY_CTRL			0x34
+
+#define CNF_MINICTRL(_reg)				(CNF_MINICTRL_REG_BASE \
+							+ (CNF_MINICTRL_##_reg))
+
+/*
+ * @brief Nand IO MTD initialization routine
+ *
+ * @total_size: [out] Total size of the NAND flash device
+ * @erase_size: [out] Minimum erase size of the NAND flash device
+ * Return: 0 on success, a negative errno on failure
+ */
+int cdns_nand_init_mtd(unsigned long long *total_size,
+						unsigned int *erase_size);
+
+/*
+ * @brief Read bytes from the NAND flash device
+ *
+ * @offset: Byte offset to read from in device
+ * @buffer: [out] Bytes read from device
+ * @length: Number of bytes to read
+ * @out_length: [out] Number of bytes read from device
+ * Return: 0 on success, a negative errno on failure
+ */
+int cdns_nand_read(unsigned int offset, uintptr_t buffer,
+					size_t length, size_t *out_length);
+
+/* NAND Flash Controller/Host initialization */
+int cdns_nand_host_init(void);
+
+#endif
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
new file mode 100644
index 0000000..6452725
--- /dev/null
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDN_MMC_H
+#define CDN_MMC_H
+
+#include <drivers/cadence/cdns_combo_phy.h>
+#include <drivers/mmc.h>
+#include "socfpga_plat_def.h"
+
+#if MMC_DEVICE_TYPE == 0
+#define CONFIG_DMA_ADDR_T_64BIT		0
+#endif
+
+#define MMC_REG_BASE			SOCFPGA_MMC_REG_BASE
+#define COMBO_PHY_REG		0x0
+#define SDHC_EXTENDED_WR_MODE_MASK	0xFFFFFFF7
+#define SDHC_DLL_RESET_MASK	0x00000001
+/* HRS09 */
+#define SDHC_PHY_SW_RESET			BIT(0)
+#define SDHC_PHY_INIT_COMPLETE		BIT(1)
+#define SDHC_EXTENDED_RD_MODE(x)	((x) << 2)
+#define EXTENDED_WR_MODE			3
+#define SDHC_EXTENDED_WR_MODE(x)	((x) << 3)
+#define RDCMD_EN					15
+#define SDHC_RDCMD_EN(x)			((x) << 15)
+#define SDHC_RDDATA_EN(x)			((x) << 16)
+
+/* CMD_DATA_OUTPUT */
+#define SDHC_CDNS_HRS16				0x40
+
+/* This value determines the interval by which DAT line timeouts are detected */
+/* The interval can be computed as below: */
+/* • 1111b - Reserved */
+/* • 1110b - t_sdmclk*2(27+2) */
+/* • 1101b - t_sdmclk*2(26+2) */
+#define READ_CLK					0xa << 16
+#define WRITE_CLK					0xe << 16
+#define DTC_VAL						0xE
+
+/* SRS00 */
+/* System Address / Argument 2 / 32-bit block count
+ * This field is used as:
+ * • 32-bit Block Count register
+ * • SDMA system memory address
+ * • Auto CMD23 Argument
+ */
+#define SAAR						(1)
+
+/* SRS01 */
+/* Transfer Block Size
+ * This field defines block size for block data transfers
+ */
+#define BLOCK_SIZE					0
+
+/* SDMA Buffer Boundary
+ * System address boundary can be set for SDMA engine.
+ */
+#define SDMA_BUF					7 << 12
+
+/* Block Count For Current Transfer
+ * To set the number of data blocks can be defined for next transfer
+ */
+#define BLK_COUNT_CT				16
+
+/* SRS03 */
+#define CMD_START					(U(1) << 31)
+#define CMD_USE_HOLD_REG			(1 << 29)
+#define CMD_UPDATE_CLK_ONLY			(1 << 21)
+#define CMD_SEND_INIT				(1 << 15)
+#define CMD_STOP_ABORT_CMD			(4 << 22)
+#define CMD_RESUME_CMD				(2 << 22)
+#define CMD_SUSPEND_CMD				(1 << 22)
+#define DATA_PRESENT				(1 << 21)
+#define CMD_IDX_CHK_ENABLE			(1 << 20)
+#define CMD_WRITE					(0 << 4)
+#define CMD_READ					(1 << 4)
+#define	MULTI_BLK_READ				(1 << 5)
+#define RESP_ERR					(1 << 7)
+#define CMD_CHECK_RESP_CRC			(1 << 19)
+#define RES_TYPE_SEL_48				(2 << 16)
+#define RES_TYPE_SEL_136			(1 << 16)
+#define RES_TYPE_SEL_48_B			(3 << 16)
+#define RES_TYPE_SEL_NO				(0 << 16)
+#define DMA_ENABLED					(1 << 0)
+#define BLK_CNT_EN					(1 << 1)
+#define AUTO_CMD_EN					(2 << 2)
+#define COM_IDX						24
+#define ERROR_INT					(1 << 15)
+#define INT_SBE						(1 << 13)
+#define INT_HLE						(1 << 12)
+#define INT_FRUN					(1 << 11)
+#define INT_DRT						(1 << 9)
+#define INT_RTO						(1 << 8)
+#define INT_DCRC					(1 << 7)
+#define INT_RCRC					(1 << 6)
+#define INT_RXDR					(1 << 5)
+#define INT_TXDR					(1 << 4)
+#define INT_DTO						(1 << 3)
+#define INT_CMD_DONE				(1 << 0)
+#define TRAN_COMP					(1 << 1)
+
+/* SRS09 */
+#define STATUS_DATA_BUSY			BIT(2)
+
+/* SRS10 */
+/* LED Control
+ * State of this bit directly drives led port of the host
+ * in order to control the external LED diode
+ * Default value 0 << 1
+ */
+#define LEDC						BIT(0)
+#define LEDC_OFF					0 << 1
+
+/* Data Transfer Width
+ * Bit used to configure DAT bus width to 1 or 4
+ * Default value 1 << 1
+ */
+#define DT_WIDTH					BIT(1)
+#define DTW_4BIT					1 << 1
+
+/* Extended Data Transfer Width
+ * This bit is to enable/disable 8-bit DAT bus width mode
+ * Default value 1 << 5
+ */
+#define EDTW_8BIT					1 << 5
+
+/* High Speed Enable
+ * Selects operating mode to Default Speed (HSE=0) or High Speed (HSE=1)
+ */
+#define HS_EN						BIT(2)
+
+/* here 0 defines the 64 Kb size */
+#define MAX_64KB_PAGE				0
+#define EMMC_DESC_SIZE		(1<<20)
+
+/* SRS11 */
+/* Software Reset For All
+ * When set to 1, the entire slot is reset
+ * After completing the reset operation, SRFA bit is automatically cleared
+ */
+#define SRFA						BIT(24)
+
+/* Software Reset For CMD Line
+ * When set to 1, resets the logic related to the command generation and response checking
+ */
+#define SRCMD						BIT(25)
+
+/* Software Reset For DAT Line
+ * When set to 1, resets the logic related to the data path,
+ * including data buffers and the DMA logic
+ */
+#define SRDAT						BIT(26)
+
+/* SRS15 */
+/* UHS Mode Select
+ * Used to select one of UHS-I modes.
+ * • 000b - SDR12
+ * • 001b - SDR25
+ * • 010b - SDR50
+ * • 011b - SDR104
+ * • 100b - DDR50
+ */
+#define SDR12_MODE					0 << 16
+#define SDR25_MODE					1 << 16
+#define SDR50_MODE					2 << 16
+#define SDR104_MODE					3 << 16
+#define DDR50_MODE					4 << 16
+/* 1.8V Signaling Enable
+ * • 0 - for Default Speed, High Speed mode
+ * • 1 - for UHS-I mode
+ */
+#define V18SE						BIT(19)
+
+/* CMD23 Enable
+ * In result of Card Identification process,
+ * Host Driver set this bit to 1 if Card supports CMD23
+ */
+#define CMD23_EN					BIT(27)
+
+/* Host Version 4.00 Enable
+ * • 0 - Version 3.00
+ * • 1 - Version 4.00
+ */
+#define HV4E						BIT(28)
+/* Conf depends on SRS15.HV4E */
+#define SDMA						0 << 3
+#define ADMA2_32					2 << 3
+#define ADMA2_64					3 << 3
+
+/* Preset Value Enable
+ * Setting this bit to 1 triggers an automatically update of SRS11
+ */
+#define PVE							BIT(31)
+
+#define BIT_AD_32					0 << 29
+#define BIT_AD_64					1 << 29
+
+/* SW RESET REG*/
+#define SDHC_CDNS_HRS00				(0x00)
+#define SDHC_CDNS_HRS00_SWR			BIT(0)
+
+/* PHY access port */
+#define SDHC_CDNS_HRS04				0x10
+#define SDHC_CDNS_HRS04_ADDR		GENMASK(5, 0)
+
+/* PHY data access port */
+#define SDHC_CDNS_HRS05				0x14
+
+/* eMMC control registers */
+#define SDHC_CDNS_HRS06				0x18
+
+/* SRS */
+#define SDHC_CDNS_SRS_BASE			0x200
+#define SDHC_CDNS_SRS00				0x200
+#define SDHC_CDNS_SRS01				0x204
+#define SDHC_CDNS_SRS02				0x208
+#define SDHC_CDNS_SRS03				0x20c
+#define SDHC_CDNS_SRS04				0x210
+#define SDHC_CDNS_SRS05				0x214
+#define SDHC_CDNS_SRS06				0x218
+#define SDHC_CDNS_SRS07				0x21C
+#define SDHC_CDNS_SRS08				0x220
+#define SDHC_CDNS_SRS09				0x224
+#define SDHC_CDNS_SRS09_CI			BIT(16)
+#define SDHC_CDNS_SRS10				0x228
+#define SDHC_CDNS_SRS11				0x22C
+#define SDHC_CDNS_SRS12				0x230
+#define SDHC_CDNS_SRS13				0x234
+#define SDHC_CDNS_SRS14				0x238
+#define SDHC_CDNS_SRS15				0x23c
+#define SDHC_CDNS_SRS21				0x254
+#define SDHC_CDNS_SRS22				0x258
+#define SDHC_CDNS_SRS23				0x25c
+
+/* HRS07 */
+#define SDHC_CDNS_HRS07				0x1c
+#define SDHC_IDELAY_VAL(x)			((x) << 0)
+#define SDHC_RW_COMPENSATE(x)		((x) << 16)
+
+/* PHY reset port */
+#define SDHC_CDNS_HRS09				0x24
+
+/* HRS10 */
+/* PHY reset port */
+#define SDHC_CDNS_HRS10				0x28
+
+/* HCSDCLKADJ DATA; DDR Mode */
+#define SDHC_HCSDCLKADJ(x)			((x) << 16)
+
+/* Pinmux headers will reomove after ATF driver implementation */
+#define PINMUX_SDMMC_SEL			0x0
+#define PIN0SEL						0x00
+#define PIN1SEL						0x04
+#define PIN2SEL						0x08
+#define PIN3SEL						0x0C
+#define PIN4SEL						0x10
+#define PIN5SEL						0x14
+#define PIN6SEL						0x18
+#define PIN7SEL						0x1C
+#define PIN8SEL						0x20
+#define PIN9SEL						0x24
+#define PIN10SEL					0x28
+
+/* HRS16 */
+#define SDHC_WRCMD0_DLY(x)			((x) << 0)
+#define SDHC_WRCMD1_DLY(x)			((x) << 4)
+#define SDHC_WRDATA0_DLY(x)			((x) << 8)
+#define SDHC_WRDATA1_DLY(x)			((x) << 12)
+#define SDHC_WRCMD0_SDCLK_DLY(x)	((x) << 16)
+#define SDHC_WRCMD1_SDCLK_DLY(x)	((x) << 20)
+#define SDHC_WRDATA0_SDCLK_DLY(x)	((x) << 24)
+#define SDHC_WRDATA1_SDCLK_DLY(x)	((x) << 28)
+
+/* Shared Macros */
+#define SDMMC_CDN(_reg)				(SDMMC_CDN_REG_BASE + \
+								(SDMMC_CDN_##_reg))
+
+/* Refer to atf/tools/cert_create/include/debug.h */
+#define BIT_32(nr)					(U(1) << (nr))
+
+/* MMC Peripheral Definition */
+#define SOCFPGA_MMC_BLOCK_SIZE		U(8192)
+#define SOCFPGA_MMC_BLOCK_MASK		(SOCFPGA_MMC_BLOCK_SIZE - U(1))
+#define SOCFPGA_MMC_BOOT_CLK_RATE	(400 * 1000)
+#define MMC_RESPONSE_NONE			0
+#define SDHC_CDNS_SRS03_VALUE		0x01020013
+
+/* Value randomly chosen for eMMC RCA, it should be > 1 */
+#define MMC_FIX_RCA					6
+#define RCA_SHIFT_OFFSET			16
+
+#define CMD_EXTCSD_PARTITION_CONFIG	179
+#define CMD_EXTCSD_BUS_WIDTH		183
+#define CMD_EXTCSD_HS_TIMING		185
+#define CMD_EXTCSD_SEC_CNT			212
+
+#define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
+#define PART_CFG_PARTITION1_ACCESS	(U(1) << 0)
+
+/* Values in EXT CSD register */
+#define MMC_BUS_WIDTH_1				U(0)
+#define MMC_BUS_WIDTH_4				U(1)
+#define MMC_BUS_WIDTH_8				U(2)
+#define MMC_BUS_WIDTH_DDR_4			U(5)
+#define MMC_BUS_WIDTH_DDR_8			U(6)
+#define MMC_BOOT_MODE_BACKWARD		(U(0) << 3)
+#define MMC_BOOT_MODE_HS_TIMING		(U(1) << 3)
+#define MMC_BOOT_MODE_DDR			(U(2) << 3)
+
+#define EXTCSD_SET_CMD				(U(0) << 24)
+#define EXTCSD_SET_BITS				(U(1) << 24)
+#define EXTCSD_CLR_BITS				(U(2) << 24)
+#define EXTCSD_WRITE_BYTES			(U(3) << 24)
+#define EXTCSD_CMD(x)				(((x) & 0xff) << 16)
+#define EXTCSD_VALUE(x)				(((x) & 0xff) << 8)
+#define EXTCSD_CMD_SET_NORMAL		U(1)
+
+#define CSD_TRAN_SPEED_UNIT_MASK	GENMASK(2, 0)
+#define CSD_TRAN_SPEED_MULT_MASK	GENMASK(6, 3)
+#define CSD_TRAN_SPEED_MULT_SHIFT	3
+
+#define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
+#define STATUS_READY_FOR_DATA		BIT(8)
+#define STATUS_SWITCH_ERROR			BIT(7)
+#define MMC_GET_STATE(x)			(((x) >> 9) & 0xf)
+#define MMC_STATE_IDLE				0
+#define MMC_STATE_READY				1
+#define MMC_STATE_IDENT				2
+#define MMC_STATE_STBY				3
+#define MMC_STATE_TRAN				4
+#define MMC_STATE_DATA				5
+#define MMC_STATE_RCV				6
+#define MMC_STATE_PRG				7
+#define MMC_STATE_DIS				8
+#define MMC_STATE_BTST				9
+#define MMC_STATE_SLP				10
+
+#define MMC_FLAG_CMD23				(U(1) << 0)
+
+#define CMD8_CHECK_PATTERN			U(0xAA)
+#define VHS_2_7_3_6_V				BIT(8)
+
+/*ADMA table component*/
+#define ADMA_DESC_ATTR_VALID		BIT(0)
+#define ADMA_DESC_ATTR_END			BIT(1)
+#define ADMA_DESC_ATTR_INT			BIT(2)
+#define ADMA_DESC_ATTR_ACT1			BIT(4)
+#define ADMA_DESC_ATTR_ACT2			BIT(5)
+#define ADMA_DESC_TRANSFER_DATA		ADMA_DESC_ATTR_ACT2
+
+enum sd_opcode {
+	SD_GO_IDLE_STATE = 0,
+	SD_ALL_SEND_CID = 2,
+	SD_SEND_RELATIVE_ADDR = 3,
+	SDIO_SEND_OP_COND = 5, /* SDIO cards only */
+	SD_SWITCH = 6,
+	SD_SELECT_CARD = 7,
+	SD_SEND_IF_COND = 8,
+	SD_SEND_CSD = 9,
+	SD_SEND_CID = 10,
+	SD_VOL_SWITCH = 11,
+	SD_STOP_TRANSMISSION = 12,
+	SD_SEND_STATUS = 13,
+	SD_GO_INACTIVE_STATE = 15,
+	SD_SET_BLOCK_SIZE = 16,
+	SD_READ_SINGLE_BLOCK = 17,
+	SD_READ_MULTIPLE_BLOCK = 18,
+	SD_SEND_TUNING_BLOCK = 19,
+	SD_SET_BLOCK_COUNT = 23,
+	SD_WRITE_SINGLE_BLOCK = 24,
+	SD_WRITE_MULTIPLE_BLOCK = 25,
+	SD_ERASE_BLOCK_START = 32,
+	SD_ERASE_BLOCK_END = 33,
+	SD_ERASE_BLOCK_OPERATION = 38,
+	SD_APP_CMD = 55,
+	SD_SPI_READ_OCR = 58, /* SPI mode only */
+	SD_SPI_CRC_ON_OFF = 59, /* SPI mode only */
+};
+
+enum sd_app_cmd {
+	SD_APP_SET_BUS_WIDTH = 6,
+	SD_APP_SEND_STATUS = 13,
+	SD_APP_SEND_NUM_WRITTEN_BLK = 22,
+	SD_APP_SET_WRITE_BLK_ERASE_CNT = 23,
+	SD_APP_SEND_OP_COND = 41,
+	SD_APP_CLEAR_CARD_DETECT = 42,
+	SD_APP_SEND_SCR = 51,
+};
+
+struct cdns_sdmmc_sdhc {
+	uint32_t	sdhc_extended_rd_mode;
+	uint32_t	sdhc_extended_wr_mode;
+	uint32_t	sdhc_hcsdclkadj;
+	uint32_t	sdhc_idelay_val;
+	uint32_t	sdhc_rdcmd_en;
+	uint32_t	sdhc_rddata_en;
+	uint32_t	sdhc_rw_compensate;
+	uint32_t	sdhc_sdcfsh;
+	uint32_t	sdhc_sdcfsl;
+	uint32_t	sdhc_wrcmd0_dly;
+	uint32_t	sdhc_wrcmd0_sdclk_dly;
+	uint32_t	sdhc_wrcmd1_dly;
+	uint32_t	sdhc_wrcmd1_sdclk_dly;
+	uint32_t	sdhc_wrdata0_dly;
+	uint32_t	sdhc_wrdata0_sdclk_dly;
+	uint32_t	sdhc_wrdata1_dly;
+	uint32_t	sdhc_wrdata1_sdclk_dly;
+};
+
+enum sdmmc_device_mode {
+	SD_DS_ID, /* Identification */
+	SD_DS, /* Default speed */
+	SD_HS, /* High speed */
+	SD_UHS_SDR12, /* Ultra high speed SDR12 */
+	SD_UHS_SDR25, /* Ultra high speed SDR25 */
+	SD_UHS_SDR50, /* Ultra high speed SDR`50 */
+	SD_UHS_SDR104, /* Ultra high speed SDR104 */
+	SD_UHS_DDR50, /* Ultra high speed DDR50 */
+	EMMC_SDR_BC, /* SDR backward compatible */
+	EMMC_SDR, /* SDR */
+	EMMC_DDR, /* DDR */
+	EMMC_HS200, /* High speed 200Mhz in SDR */
+	EMMC_HS400, /* High speed 200Mhz in DDR */
+	EMMC_HS400es, /* High speed 200Mhz in SDR with enhanced strobe*/
+};
+
+struct cdns_sdmmc_params {
+	uintptr_t	reg_base;
+	uintptr_t	reg_pinmux;
+	uintptr_t	reg_phy;
+	uintptr_t	desc_base;
+	size_t		desc_size;
+	int		clk_rate;
+	int		bus_width;
+	unsigned int	flags;
+	enum sdmmc_device_mode	cdn_sdmmc_dev_mode;
+	enum mmc_device_type	cdn_sdmmc_dev_type;
+	uint32_t	combophy;
+};
+
+/* read and write API */
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
+
+struct cdns_idmac_desc {
+	/*8 bit attribute*/
+	uint8_t attr;
+	/*reserved bits in desc*/
+	uint8_t reserved;
+	/*page length for the descriptor*/
+	uint16_t len;
+	/*lower 32 bits for buffer (64 bit addressing)*/
+	uint32_t addr_lo;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+	/*higher 32 bits for buffer (64 bit addressing)*/
+	uint32_t addr_hi;
+} __aligned(8);
+#else
+} __packed;
+#endif
+
+
+
+/* Function Prototype */
+int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
+struct cdns_sdmmc_sdhc *mmc_sdhc_reg);
+void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+struct cdns_sdmmc_sdhc *sdhc_reg);
+#endif
diff --git a/include/drivers/io/io_dummy.h b/include/drivers/io/io_dummy.h
deleted file mode 100644
index edfc699..0000000
--- a/include/drivers/io/io_dummy.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef IO_DUMMY_H
-#define IO_DUMMY_H
-
-int register_io_dev_dummy(const struct io_dev_connector **dev_con);
-
-#endif /* IO_DUMMY_H */
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 8f30ed0..3179383 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -19,7 +19,6 @@
 	IO_TYPE_INVALID,
 	IO_TYPE_SEMIHOSTING,
 	IO_TYPE_MEMMAP,
-	IO_TYPE_DUMMY,
 	IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
 	IO_TYPE_BLOCK,
 	IO_TYPE_MTD,
diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h
index fe88576..76affd8 100644
--- a/include/drivers/measured_boot/rss/rss_measured_boot.h
+++ b/include/drivers/measured_boot/rss/rss_measured_boot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,12 +44,14 @@
 };
 
 /* Functions' declarations */
-void rss_measured_boot_init(void);
-struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void);
-int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
+void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr);
+int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
+				 uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id);
 
 /* TODO: These metadata are currently not available during TF-A boot */
-int rss_mboot_set_signer_id(unsigned int img_id, const void *pk_ptr, size_t pk_len);
+int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+			    unsigned int img_id, const void *pk_ptr,
+			    size_t pk_len);
 
 #endif /* RSS_MEASURED_BOOT_H */
diff --git a/include/drivers/nxp/crypto/caam/sec_hw_specific.h b/include/drivers/nxp/crypto/caam/sec_hw_specific.h
index 9800793..bc11aca 100644
--- a/include/drivers/nxp/crypto/caam/sec_hw_specific.h
+++ b/include/drivers/nxp/crypto/caam/sec_hw_specific.h
@@ -221,7 +221,7 @@
  /*  Lists the possible states for a job ring. */
 typedef enum sec_job_ring_state_e {
 	SEC_JOB_RING_STATE_STARTED,	/* Job ring is initialized */
-	SEC_JOB_RING_STATE_RESET,	/* Job ring reset is in progres */
+	SEC_JOB_RING_STATE_RESET,	/* Job ring reset is in progress */
 } sec_job_ring_state_t;
 
 struct sec_job_ring_t {
diff --git a/include/drivers/nxp/crypto/caam/sec_jr_driver.h b/include/drivers/nxp/crypto/caam/sec_jr_driver.h
index 57e0fa0..a6570d8 100644
--- a/include/drivers/nxp/crypto/caam/sec_jr_driver.h
+++ b/include/drivers/nxp/crypto/caam/sec_jr_driver.h
@@ -57,7 +57,7 @@
 /*
  * Structure encompassing a job descriptor which is to be processed
  * by SEC. User should also initialise this structure with the callback
- * function pointer which will be called by driver after recieving proccessed
+ * function pointer which will be called by driver after receiving proccessed
  * descriptor from SEC. User data is also passed in this data structure which
  * will be sent as an argument to the user callback function.
  */
diff --git a/include/drivers/nxp/dcfg/dcfg_lsch2.h b/include/drivers/nxp/dcfg/dcfg_lsch2.h
index 882ba5a..bdef6de 100644
--- a/include/drivers/nxp/dcfg/dcfg_lsch2.h
+++ b/include/drivers/nxp/dcfg/dcfg_lsch2.h
@@ -55,7 +55,7 @@
 #define DISR5_DDRC1_MASK		0x1
 #define DISR5_OCRAM_MASK		0x40
 
-/* DCFG regsiters bit masks */
+/* DCFG registers bit masks */
 #define RCWSR0_SYS_PLL_RAT_SHIFT	25
 #define RCWSR0_SYS_PLL_RAT_MASK		0x1f
 #define RCWSR0_MEM_PLL_RAT_SHIFT	16
diff --git a/include/drivers/nxp/trdc/imx_trdc.h b/include/drivers/nxp/trdc/imx_trdc.h
new file mode 100644
index 0000000..0b41fcf
--- /dev/null
+++ b/include/drivers/nxp/trdc/imx_trdc.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_TRDC_H
+#define IMX_XRDC_H
+
+#define MBC_BLK_ALL	U(255)
+#define MRC_REG_ALL	U(16)
+#define GLBAC_NUM	U(8)
+
+#define DID_NUM		U(16)
+#define MBC_MAX_NUM	U(4)
+#define MRC_MAX_NUM	U(2)
+#define MBC_NUM(HWCFG)	(((HWCFG) >> 16) & 0xF)
+#define MRC_NUM(HWCFG)	(((HWCFG) >> 24) & 0x1F)
+
+#define MBC_BLK_NUM(GLBCFG)	((GLBCFG) & 0x3FF)
+#define MRC_RGN_NUM(GLBCFG)	((GLBCFG) & 0x1F)
+
+#define MDAC_W_X(m, r)	(0x800 + (m) * 0x20 + (r) * 0x4)
+
+/* CPU/non-CPU domain common bits */
+#define MDA_VLD		BIT(31)
+#define MDA_LK1		BIT(30)
+#define MDA_DFMT	BIT(29)
+
+/* CPU domain bits */
+#define MDA_DFMT0_DID(x)	((x) & 0xF)
+#define MDA_DFMT0_DIDS(x)	(((x) & 0x3) << 4)
+#define MDA_DFMT0_PE(x)		(((x) & 0x3) << 6)
+#define MDA_DFMT0_PIDM(x)	(((x) & 0x3F) << 8)
+#define MDA_DFMT0_SA(x)		(((x) & 0x3) << 14)
+#define MDA_DFMT0_PID(x)	(((x) & 0x3F) << 16)
+
+/* non-CPU domain bits */
+#define MDA_DFMT1_DID(x)	((x) & 0xF)
+#define MDA_DFMT1_PA(x)		(((x) & 0x3) << 4)
+#define MDA_DFMT1_SA(x)		(((x) & 0x3) << 6)
+#define MDA_DFMT1_DIDB(x)	((x) << 8)
+
+#define SP(X)	((X) << 12)
+#define SU(X)	((X) << 8)
+#define NP(X)	((X) << 4)
+#define NU(X)	((X) << 0)
+
+#define RWX	U(7)
+#define RW	U(6)
+#define RX	U(5)
+#define R	U(4)
+#define X	U(1)
+
+struct mbc_mem_dom {
+	uint32_t mem_glbcfg[4];
+	uint32_t nse_blk_index;
+	uint32_t nse_blk_set;
+	uint32_t nse_blk_clr;
+	uint32_t nsr_blk_clr_all;
+	uint32_t memn_glbac[8];
+	/* The upper only existed in the beginning of each MBC */
+	uint32_t mem0_blk_cfg_w[64];
+	uint32_t mem0_blk_nse_w[16];
+	uint32_t mem1_blk_cfg_w[8];
+	uint32_t mem1_blk_nse_w[2];
+	uint32_t mem2_blk_cfg_w[8];
+	uint32_t mem2_blk_nse_w[2];
+	uint32_t mem3_blk_cfg_w[8];
+	uint32_t mem3_blk_nse_w[2]; /*0x1F0, 0x1F4 */
+	uint32_t reserved[2];
+};
+
+struct mrc_rgn_dom {
+	uint32_t mrc_glbcfg[4];
+	uint32_t nse_rgn_indirect;
+	uint32_t nse_rgn_set;
+	uint32_t nse_rgn_clr;
+	uint32_t nse_rgn_clr_all;
+	uint32_t memn_glbac[8];
+	/* The upper only existed in the beginning of each MRC */
+	uint32_t rgn_desc_words[16][2]; /* 16 regions at max, 2 words per region */
+	uint32_t rgn_nse;
+	uint32_t reserved2[15];
+};
+
+struct mda_inst {
+	uint32_t mda_w[8];
+};
+
+struct trdc_mgr {
+	uint32_t trdc_cr;
+	uint32_t res0[59];
+	uint32_t trdc_hwcfg0;
+	uint32_t trdc_hwcfg1;
+	uint32_t res1[450];
+	struct mda_inst mda[128];
+};
+
+struct trdc_mbc {
+	struct mbc_mem_dom mem_dom[DID_NUM];
+};
+
+struct trdc_mrc {
+	struct mrc_rgn_dom mrc_dom[DID_NUM];
+};
+
+/***************************************************************
+ * Below structs used fro provding the TRDC configuration info
+ * that will be used to init the TRDC based on use case.
+ ***************************************************************/
+struct trdc_glbac_config {
+	uint8_t mbc_mrc_id;
+	uint8_t glbac_id;
+	uint32_t glbac_val;
+};
+
+struct trdc_mbc_config {
+	uint8_t mbc_id;
+	uint8_t dom_id;
+	uint8_t mem_id;
+	uint8_t blk_id;
+	uint8_t glbac_id;
+	bool secure;
+};
+
+struct trdc_mrc_config {
+	uint8_t mrc_id;
+	uint8_t dom_id;
+	uint8_t region_id;
+	uint32_t region_start;
+	uint32_t region_size;
+	uint8_t glbac_id;
+	bool secure;
+};
+
+struct trdc_mgr_info {
+	uintptr_t trdc_base;
+	uint8_t mbc_id;
+	uint8_t mbc_mem_id;
+	uint8_t blk_mgr;
+	uint8_t blk_mc;
+};
+
+struct trdc_config_info {
+	uintptr_t trdc_base;
+	struct trdc_glbac_config *mbc_glbac;
+	uint32_t num_mbc_glbac;
+	struct trdc_mbc_config *mbc_cfg;
+	uint32_t num_mbc_cfg;
+	struct trdc_glbac_config *mrc_glbac;
+	uint32_t num_mrc_glbac;
+	struct trdc_mrc_config *mrc_cfg;
+	uint32_t num_mrc_cfg;
+};
+
+extern struct trdc_mgr_info trdc_mgr_blks[];
+extern unsigned int trdc_mgr_num;
+/* APIs to apply and enable TRDC */
+int trdc_mda_set_cpu(uintptr_t trdc_base, uint32_t mda_inst,
+		     uint32_t mda_reg, uint8_t sa, uint8_t dids,
+		     uint8_t did, uint8_t pe, uint8_t pidm, uint8_t pid);
+
+int trdc_mda_set_noncpu(uintptr_t trdc_base, uint32_t mda_inst,
+			bool did_bypass, uint8_t sa, uint8_t pa,
+			uint8_t did);
+
+void trdc_mgr_mbc_setup(struct trdc_mgr_info *mgr);
+void trdc_setup(struct trdc_config_info *cfg);
+void trdc_config(void);
+
+#endif /* IMX_TRDC_H */
diff --git a/include/drivers/rpi3/sdhost/rpi3_sdhost.h b/include/drivers/rpi3/sdhost/rpi3_sdhost.h
index 1653240..f4f6ec8 100644
--- a/include/drivers/rpi3/sdhost/rpi3_sdhost.h
+++ b/include/drivers/rpi3/sdhost/rpi3_sdhost.h
@@ -15,6 +15,7 @@
 struct rpi3_sdhost_params {
 	uintptr_t	reg_base;
 	uint32_t	clk_rate;
+	uint32_t	clk_rate_initial;
 	uint32_t	bus_width;
 	uint32_t        flags;
 	uint32_t	current_cmd;
@@ -57,6 +58,8 @@
 #define HC_CMD_READ			0x0040
 #define HC_CMD_COMMAND_MASK		0x003f
 
+#define RPI3_SDHOST_MAX_CLOCK		250000000	// technically, we should obtain this number from the mailbox
+
 #define HC_CLOCKDIVISOR_MAXVAL		0x07ff
 #define HC_CLOCKDIVISOR_PREFERVAL	0x027b
 #define HC_CLOCKDIVISOR_SLOWVAL		0x0148
diff --git a/include/drivers/scmi-msg.h b/include/drivers/scmi-msg.h
index a9a99cf..eb90859 100644
--- a/include/drivers/scmi-msg.h
+++ b/include/drivers/scmi-msg.h
@@ -22,7 +22,7 @@
  *
  * @shm_addr: Address of the shared memory for the SCMI channel
  * @shm_size: Byte size of the shared memory for the SCMI channel
- * @busy: True when channel is busy, flase when channel is free
+ * @busy: True when channel is busy, false when channel is free
  * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL
  */
 struct scmi_msg_channel {
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/drivers/st/stm32_pka.h b/include/drivers/st/stm32_pka.h
index ad4690a..34b3f6b 100644
--- a/include/drivers/st/stm32_pka.h
+++ b/include/drivers/st/stm32_pka.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,24 +9,11 @@
 
 #include <stdint.h>
 
-#if !PKA_USE_NIST_P256 && !PKA_USE_BRAINPOOL_P256R1 && !PKA_USE_BRAINPOOL_P256T1 && \
-	!PKA_USE_NIST_P521
-#error "At least one ECDSA curve needs to be selected"
-#endif
-
 enum stm32_pka_ecdsa_curve_id {
-#if PKA_USE_NIST_P256
 	PKA_NIST_P256,
-#endif
-#if PKA_USE_BRAINPOOL_P256R1
 	PKA_BRAINPOOL_P256R1,
-#endif
-#if PKA_USE_BRAINPOOL_P256T1
 	PKA_BRAINPOOL_P256T1,
-#endif
-#if PKA_USE_NIST_P521
 	PKA_NIST_P521,
-#endif
 };
 
 struct stm32_pka_platdata {
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/bl_aux_params/bl_aux_params.h b/include/lib/bl_aux_params/bl_aux_params.h
index f6ce802..072a29d 100644
--- a/include/lib/bl_aux_params/bl_aux_params.h
+++ b/include/lib/bl_aux_params/bl_aux_params.h
@@ -13,7 +13,7 @@
 
 /*
  * Handler function that handles an individual aux parameter. Return true if
- * the parameter was handled, and flase if bl_aux_params_parse() should make its
+ * the parameter was handled, and false if bl_aux_params_parse() should make its
  * own attempt at handling it (for generic parameters).
  */
 typedef bool (*bl_aux_param_handler_t)(struct bl_aux_param_header *param);
diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h
index 0aa6579..42d4149 100644
--- a/include/lib/coreboot.h
+++ b/include/lib/coreboot.h
@@ -41,5 +41,6 @@
 
 coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size);
 void coreboot_table_setup(void *base);
+void coreboot_get_table_location(uint64_t *address, uint32_t *size);
 
 #endif /* COREBOOT_H */
diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S
index ab2f2c6..096e0b1 100644
--- a/include/lib/cpus/aarch32/cpu_macros.S
+++ b/include/lib/cpus/aarch32/cpu_macros.S
@@ -1,82 +1,13 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #ifndef CPU_MACROS_S
 #define CPU_MACROS_S
 
-#include <arch.h>
-#include <lib/cpus/errata_report.h>
-
-#if defined(IMAGE_BL1) || defined(IMAGE_BL32)  \
-	|| (defined(IMAGE_BL2) && RESET_TO_BL2)
-#define IMAGE_AT_EL3
-#endif
-
-#define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
-				(MIDR_PN_MASK << MIDR_PN_SHIFT)
-
-/* The number of CPU operations allowed */
-#define CPU_MAX_PWR_DWN_OPS		2
-
-/* Special constant to specify that CPU has no reset function */
-#define CPU_NO_RESET_FUNC		0
-
-/* Word size for 32-bit CPUs */
-#define CPU_WORD_SIZE			4
-
-/*
- * Whether errata status needs reporting. Errata status is printed in debug
- * builds for both BL1 and BL32 images.
- */
-#if (defined(IMAGE_BL1) || defined(IMAGE_BL32)) && DEBUG
-# define REPORT_ERRATA	1
-#else
-# define REPORT_ERRATA	0
-#endif
-
-
-	.equ	CPU_MIDR_SIZE, CPU_WORD_SIZE
-	.equ	CPU_RESET_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_PWR_DWN_OPS_SIZE, CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
-	.equ	CPU_ERRATA_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_ERRATA_LOCK_SIZE, CPU_WORD_SIZE
-	.equ	CPU_ERRATA_PRINTED_SIZE, CPU_WORD_SIZE
-
-#ifndef IMAGE_AT_EL3
-	.equ	CPU_RESET_FUNC_SIZE, 0
-#endif
-
-/* The power down core and cluster is needed only in BL32 */
-#ifndef IMAGE_BL32
-	.equ	CPU_PWR_DWN_OPS_SIZE, 0
-#endif
-
-/* Fields required to print errata status  */
-#if !REPORT_ERRATA
-	.equ	CPU_ERRATA_FUNC_SIZE, 0
-#endif
-
-/* Only BL32 requires mutual exclusion and printed flag. */
-#if !(REPORT_ERRATA && defined(IMAGE_BL32))
-	.equ	CPU_ERRATA_LOCK_SIZE, 0
-	.equ	CPU_ERRATA_PRINTED_SIZE, 0
-#endif
-
-
-/*
- * Define the offsets to the fields in cpu_ops structure.
- * Every offset is defined based on the offset and size of the previous
- * field.
- */
-	.equ	CPU_MIDR, 0
-	.equ	CPU_RESET_FUNC, CPU_MIDR + CPU_MIDR_SIZE
-	.equ	CPU_PWR_DWN_OPS, CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
-	.equ	CPU_ERRATA_FUNC, CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
-	.equ	CPU_ERRATA_LOCK, CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
-	.equ	CPU_ERRATA_PRINTED, CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
-	.equ	CPU_OPS_SIZE, CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 
 	/*
 	 * Write given expressions as words
@@ -142,6 +73,29 @@
 	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
 #endif
 
+	/*
+	 * It is possible (although unlikely) that a cpu may have no errata in
+	 * code. In that case the start label will not be defined. The list is
+	 * inteded to be used in a loop, so define it as zero-length for
+	 * predictable behaviour. Since this macro is always called at the end
+	 * of the cpu file (after all errata have been parsed) we can be sure
+	 * that we are at the end of the list. Some cpus call the macro twice,
+	 * so only do this once.
+	 */
+	.pushsection .rodata.errata_entries
+	.ifndef \_name\()_errata_list_start
+		\_name\()_errata_list_start:
+	.endif
+	/* some call this multiple times, so only do this once */
+	.ifndef \_name\()_errata_list_end
+		\_name\()_errata_list_end:
+	.endif
+	.popsection
+
+	/* and now put them in cpu_ops */
+	.word \_name\()_errata_list_start
+	.word \_name\()_errata_list_end
+
 #if REPORT_ERRATA
 	.ifndef \_name\()_cpu_str
 	  /*
@@ -166,6 +120,7 @@
 	 * this class.
 	 */
 	.word \_name\()_errata_report
+	.word \_name\()_cpu_str
 
 #ifdef IMAGE_BL32
 	/* Pointers to errata lock and reported flag */
@@ -228,4 +183,77 @@
 	beq	\_label
 	.endm
 
+/*
+ * NOTE an erratum and CVE id could clash. However, both numbers are very large
+ * and the probablity is minuscule. Working around this makes code very
+ * complicated and extremely difficult to read so it is not considered. In the
+ * unlikely event that this does happen, prepending the CVE id with a 0 should
+ * resolve the conflict
+ */
+
+/*
+ * Add an entry for this erratum to the errata framework
+ *
+ * _cpu:
+ *	Name of cpu as given to declare_cpu_ops
+ *
+ * _cve:
+ *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
+ *
+ * _id:
+ *	Erratum or CVE number. Please combine with the previous field with the
+ *	ERRATUM or CVE macros
+ *
+ * _chosen:
+ *	Compile time flag on whether the erratum is included
+ *
+ * _special:
+ *	The special non-standard name of an erratum
+ */
+.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special
+	.pushsection .rodata.errata_entries
+		.align	2
+		.ifndef \_cpu\()_errata_list_start
+		\_cpu\()_errata_list_start:
+		.endif
+
+		/* unused on AArch32, maintain for portability */
+		.word	0
+		/* TODO(errata ABI): this prevents all checker functions from
+		 * being optimised away. Can be done away with unless the ABI
+		 * needs them */
+		.ifnb \_special
+			.word	check_errata_\_special
+		.elseif \_cve
+			.word	check_errata_cve_\_cve\()_\_id
+		.else
+			.word	check_errata_\_id
+		.endif
+		/* Will fit CVEs with up to 10 character in the ID field */
+		.word	\_id
+		.hword	\_cve
+		.byte	\_chosen
+		/* TODO(errata ABI): mitigated field for known but unmitigated
+		 * errata*/
+		.byte	0x1
+	.popsection
+.endm
+
+/*
+ * Maintain compatibility with the old scheme of "each cpu has its own reporter".
+ * TODO remove entirely once all cpus have been converted. This includes the
+ * cpu_ops entry, as print_errata_status can call this directly for all cpus
+ */
+.macro errata_report_shim _cpu:req
+	#if REPORT_ERRATA
+	func \_cpu\()_errata_report
+		push	{r12, lr}
+
+		bl generic_errata_report
+
+		pop	{r12, lr}
+		bx	lr
+	endfunc \_cpu\()_errata_report
+	#endif
+.endm
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/cpus/aarch64/cortex_a520.h b/include/lib/cpus/aarch64/cortex_a520.h
new file mode 100644
index 0000000..4176981
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a520.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A520_H
+#define CORTEX_A520_H
+
+#define CORTEX_A520_MIDR					U(0x410FD800)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A520_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A520_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A520_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A520_H */
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
new file mode 100644
index 0000000..950d02f
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A715_H
+#define CORTEX_A715_H
+
+#define CORTEX_A715_MIDR					U(0x410FD4D0)
+
+/* Cortex-A715 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A715_BHB_LOOP_COUNT				U(38)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A715_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A715_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A715_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A715_H */
diff --git a/include/lib/cpus/aarch64/cortex_a720.h b/include/lib/cpus/aarch64/cortex_a720.h
new file mode 100644
index 0000000..47bbbc0
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a720.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A720_H
+#define CORTEX_A720_H
+
+#define CORTEX_A720_MIDR					U(0x410FD810)
+
+/* Cortex A720 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A720_BHB_LOOP_COUNT				U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A720_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A720_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A720_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A720_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index 18cba2c..301be69 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -26,6 +26,7 @@
 #define CORTEX_A78C_CPUECTLR_EL1		        S3_0_C15_C1_4
 #define CORTEX_A78C_CPUECTLR_EL1_BIT_6		        (ULL(1) << 6)
 #define CORTEX_A78C_CPUECTLR_EL1_BIT_7		        (ULL(1) << 7)
+#define CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN		(ULL(1) << 53)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
diff --git a/include/lib/cpus/aarch64/cortex_blackhawk.h b/include/lib/cpus/aarch64/cortex_blackhawk.h
new file mode 100644
index 0000000..bfb3039
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_blackhawk.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_BLACKHAWK_H
+#define CORTEX_BLACKHAWK_H
+
+#define CORTEX_BLACKHAWK_MIDR					U(0x410FD850)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_BLACKHAWK_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_BLACKHAWK_H */
diff --git a/include/lib/cpus/aarch64/cortex_chaberton.h b/include/lib/cpus/aarch64/cortex_chaberton.h
new file mode 100644
index 0000000..8f10b68
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_chaberton.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_CHABERTON_H
+#define CORTEX_CHABERTON_H
+
+#define CORTEX_CHABERTON_MIDR					U(0x410FD870)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_CHABERTON_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_CHABERTON_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_CHABERTON_H */
diff --git a/include/lib/cpus/aarch64/cortex_hayes.h b/include/lib/cpus/aarch64/cortex_hayes.h
deleted file mode 100644
index 82022e9..0000000
--- a/include/lib/cpus/aarch64/cortex_hayes.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_HAYES_H
-#define CORTEX_HAYES_H
-
-#define CORTEX_HAYES_MIDR					U(0x410FD800)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_HAYES_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_HAYES_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_HAYES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_HAYES_H */
diff --git a/include/lib/cpus/aarch64/cortex_hunter.h b/include/lib/cpus/aarch64/cortex_hunter.h
deleted file mode 100644
index 24bd217..0000000
--- a/include/lib/cpus/aarch64/cortex_hunter.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_HUNTER_H
-#define CORTEX_HUNTER_H
-
-#define CORTEX_HUNTER_MIDR					U(0x410FD810)
-
-/* Cortex Hunter loop count for CVE-2022-23960 mitigation */
-#define CORTEX_HUNTER_BHB_LOOP_COUNT				U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_HUNTER_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_HUNTER_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_HUNTER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_HUNTER_H */
diff --git a/include/lib/cpus/aarch64/cortex_hunter_elp_arm.h b/include/lib/cpus/aarch64/cortex_hunter_elp_arm.h
deleted file mode 100644
index f9bb0f3..0000000
--- a/include/lib/cpus/aarch64/cortex_hunter_elp_arm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_HUNTER_ELP_ARM_H
-#define CORTEX_HUNTER_ELP_ARM_H
-
-#define CORTEX_HUNTER_ELP_ARM_MIDR					U(0x410FD821)
-
-/* Cortex Hunter ELP loop count for CVE-2022-23960 mitigation */
-#define CORTEX_HUNTER_ELP_ARM_BHB_LOOP_COUNT				U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_HUNTER_ELP_ARM_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_HUNTER_ELP_ARM_H */
diff --git a/include/lib/cpus/aarch64/cortex_makalu.h b/include/lib/cpus/aarch64/cortex_makalu.h
deleted file mode 100644
index ee59657..0000000
--- a/include/lib/cpus/aarch64/cortex_makalu.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_MAKALU_H
-#define CORTEX_MAKALU_H
-
-#define CORTEX_MAKALU_MIDR					U(0x410FD4D0)
-
-/* Cortex Makalu loop count for CVE-2022-23960 mitigation */
-#define CORTEX_MAKALU_BHB_LOOP_COUNT				U(38)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MAKALU_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MAKALU_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_MAKALU_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_MAKALU_H */
diff --git a/include/lib/cpus/aarch64/cortex_x4.h b/include/lib/cpus/aarch64/cortex_x4.h
new file mode 100644
index 0000000..17d07c8
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x4.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X4_H
+#define CORTEX_X4_H
+
+#define CORTEX_X4_MIDR					U(0x410FD821)
+
+/* Cortex X4 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_X4_BHB_LOOP_COUNT			U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_X4_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 041be51..404b7f9 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -1,95 +1,14 @@
 /*
- * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #ifndef CPU_MACROS_S
 #define CPU_MACROS_S
 
-#include <arch.h>
 #include <assert_macros.S>
-#include <lib/cpus/errata_report.h>
-
-#define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
-				(MIDR_PN_MASK << MIDR_PN_SHIFT)
-
-/* The number of CPU operations allowed */
-#define CPU_MAX_PWR_DWN_OPS		2
-
-/* Special constant to specify that CPU has no reset function */
-#define CPU_NO_RESET_FUNC		0
-
-#define CPU_NO_EXTRA1_FUNC		0
-#define CPU_NO_EXTRA2_FUNC		0
-#define CPU_NO_EXTRA3_FUNC		0
-
-/* Word size for 64-bit CPUs */
-#define CPU_WORD_SIZE			8
-
-/*
- * Whether errata status needs reporting. Errata status is printed in debug
- * builds for both BL1 and BL31 images.
- */
-#if (defined(IMAGE_BL1) || defined(IMAGE_BL31)) && DEBUG
-# define REPORT_ERRATA	1
-#else
-# define REPORT_ERRATA	0
-#endif
-
-
-	.equ	CPU_MIDR_SIZE, CPU_WORD_SIZE
-	.equ	CPU_EXTRA1_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_EXTRA2_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_EXTRA3_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_E_HANDLER_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_RESET_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_PWR_DWN_OPS_SIZE, CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
-	.equ	CPU_ERRATA_FUNC_SIZE, CPU_WORD_SIZE
-	.equ	CPU_ERRATA_LOCK_SIZE, CPU_WORD_SIZE
-	.equ	CPU_ERRATA_PRINTED_SIZE, CPU_WORD_SIZE
-	.equ	CPU_REG_DUMP_SIZE, CPU_WORD_SIZE
-
-#ifndef IMAGE_AT_EL3
-	.equ	CPU_RESET_FUNC_SIZE, 0
-#endif
-
-/* The power down core and cluster is needed only in BL31 */
-#ifndef IMAGE_BL31
-	.equ	CPU_PWR_DWN_OPS_SIZE, 0
-#endif
-
-/* Fields required to print errata status. */
-#if !REPORT_ERRATA
-	.equ	CPU_ERRATA_FUNC_SIZE, 0
-#endif
-
-/* Only BL31 requieres mutual exclusion and printed flag.  */
-#if !(REPORT_ERRATA && defined(IMAGE_BL31))
-	.equ	CPU_ERRATA_LOCK_SIZE, 0
-	.equ	CPU_ERRATA_PRINTED_SIZE, 0
-#endif
-
-#if !defined(IMAGE_BL31) || !CRASH_REPORTING
-	.equ	CPU_REG_DUMP_SIZE, 0
-#endif
-
-/*
- * Define the offsets to the fields in cpu_ops structure.
- * Every offset is defined based in the offset and size of the previous
- * field.
- */
-	.equ	CPU_MIDR, 0
-	.equ	CPU_RESET_FUNC, CPU_MIDR + CPU_MIDR_SIZE
-	.equ	CPU_EXTRA1_FUNC, CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
-	.equ	CPU_EXTRA2_FUNC, CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE
-	.equ	CPU_EXTRA3_FUNC, CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE
-	.equ	CPU_E_HANDLER_FUNC, CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE
-	.equ	CPU_PWR_DWN_OPS, CPU_E_HANDLER_FUNC + CPU_E_HANDLER_FUNC_SIZE
-	.equ	CPU_ERRATA_FUNC, CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
-	.equ	CPU_ERRATA_LOCK, CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
-	.equ	CPU_ERRATA_PRINTED, CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
-	.equ	CPU_REG_DUMP, CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
-	.equ	CPU_OPS_SIZE, CPU_REG_DUMP + CPU_REG_DUMP_SIZE
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 
 	/*
 	 * Write given expressions as quad words
@@ -172,6 +91,27 @@
 	/* Insert list of functions */
 	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
 #endif
+	/*
+	 * It is possible (although unlikely) that a cpu may have no errata in
+	 * code. In that case the start label will not be defined. The list is
+	 * intended to be used in a loop, so define it as zero-length for
+	 * predictable behaviour. Since this macro is always called at the end
+	 * of the cpu file (after all errata have been parsed) we can be sure
+	 * that we are at the end of the list. Some cpus call declare_cpu_ops
+	 * twice, so only do this once.
+	 */
+	.pushsection .rodata.errata_entries
+	.ifndef \_name\()_errata_list_start
+		\_name\()_errata_list_start:
+	.endif
+	.ifndef \_name\()_errata_list_end
+		\_name\()_errata_list_end:
+	.endif
+	.popsection
+
+	/* and now put them in cpu_ops */
+	.quad \_name\()_errata_list_start
+	.quad \_name\()_errata_list_end
 
 #if REPORT_ERRATA
 	.ifndef \_name\()_cpu_str
@@ -192,18 +132,20 @@
 	  .popsection
 	.endif
 
+
 	/*
 	 * Mandatory errata status printing function for CPUs of
 	 * this class.
 	 */
 	.quad \_name\()_errata_report
+	.quad \_name\()_cpu_str
 
 #ifdef IMAGE_BL31
 	/* Pointers to errata lock and reported flag */
 	.quad \_name\()_errata_lock
 	.quad \_name\()_errata_reported
-#endif
-#endif
+#endif /* IMAGE_BL31 */
+#endif /* REPORT_ERRATA */
 
 #if defined(IMAGE_BL31) && CRASH_REPORTING
 	.quad \_name\()_cpu_reg_dump
@@ -229,6 +171,7 @@
 			\_extra1, \_extra2, \_extra3, 0, \_power_down_ops
 	.endm
 
+/* TODO can be deleted once all CPUs have been converted */
 #if REPORT_ERRATA
 	/*
 	 * Print status of a CPU errata
@@ -311,4 +254,360 @@
 	b.eq	\_label
 	.endm
 
+
+/*
+ * Workaround wrappers for errata that apply at reset or runtime. Reset errata
+ * will be applied automatically
+ *
+ * _cpu:
+ *	Name of cpu as given to declare_cpu_ops
+ *
+ * _cve:
+ *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
+ *
+ * _id:
+ *	Erratum or CVE number. Please combine with previous field with ERRATUM
+ *	or CVE macros
+ *
+ * _chosen:
+ *	Compile time flag on whether the erratum is included
+ *
+ * _apply_at_reset:
+ *	Whether the erratum should be automatically applied at reset
+ */
+.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _apply_at_reset:req
+	.pushsection .rodata.errata_entries
+		.align	3
+		.ifndef \_cpu\()_errata_list_start
+		\_cpu\()_errata_list_start:
+		.endif
+
+		/* check if unused and compile out if no references */
+		.if \_apply_at_reset && \_chosen
+			.quad	erratum_\_cpu\()_\_id\()_wa
+		.else
+			.quad	0
+		.endif
+		/* TODO(errata ABI): this prevents all checker functions from
+		 * being optimised away. Can be done away with unless the ABI
+		 * needs them */
+		.quad	check_erratum_\_cpu\()_\_id
+		/* Will fit CVEs with up to 10 character in the ID field */
+		.word	\_id
+		.hword	\_cve
+		.byte	\_chosen
+		/* TODO(errata ABI): mitigated field for known but unmitigated
+		 * errata */
+		.byte	0x1
+	.popsection
+.endm
+
+.macro _workaround_start _cpu:req, _cve:req, _id:req, _chosen:req, _apply_at_reset:req
+	add_erratum_entry \_cpu, \_cve, \_id, \_chosen, \_apply_at_reset
+
+	func erratum_\_cpu\()_\_id\()_wa
+		mov	x8, x30
+
+		/* save rev_var for workarounds that might need it but don't
+		 * restore to x0 because few will care */
+		mov	x7, x0
+		bl	check_erratum_\_cpu\()_\_id
+		cbz	x0, erratum_\_cpu\()_\_id\()_skip
+.endm
+
+.macro _workaround_end _cpu:req, _id:req
+	erratum_\_cpu\()_\_id\()_skip:
+		ret	x8
+	endfunc erratum_\_cpu\()_\_id\()_wa
+.endm
+
+/*******************************************************************************
+ * Errata workaround wrappers
+ ******************************************************************************/
+/*
+ * Workaround wrappers for errata that apply at reset or runtime. Reset errata
+ * will be applied automatically
+ *
+ * _cpu:
+ *	Name of cpu as given to declare_cpu_ops
+ *
+ * _cve:
+ *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
+ *
+ * _id:
+ *	Erratum or CVE number. Please combine with previous field with ERRATUM
+ *	or CVE macros
+ *
+ * _chosen:
+ *	Compile time flag on whether the erratum is included
+ *
+ * in body:
+ *	clobber x0 to x7 (please only use those)
+ *	argument x7 - cpu_rev_var
+ *
+ * _wa clobbers: x0-x8 (PCS compliant)
+ */
+.macro workaround_reset_start _cpu:req, _cve:req, _id:req, _chosen:req
+	_workaround_start \_cpu, \_cve, \_id, \_chosen, 1
+.endm
+
+/*
+ * See `workaround_reset_start` for usage info. Additional arguments:
+ *
+ * _midr:
+ *	Check if CPU's MIDR matches the CPU it's meant for. Must be specified
+ *	for errata applied in generic code
+ */
+.macro workaround_runtime_start _cpu:req, _cve:req, _id:req, _chosen:req, _midr
+	/*
+	 * Let errata specify if they need MIDR checking. Sadly, storing the
+	 * MIDR in an .equ to retrieve automatically blows up as it stores some
+	 * brackets in the symbol
+	 */
+	.ifnb \_midr
+		jump_if_cpu_midr \_midr, 1f
+		b	erratum_\_cpu\()_\_id\()_skip
+
+		1:
+	.endif
+	_workaround_start \_cpu, \_cve, \_id, \_chosen, 0
+.endm
+
+/*
+ * Usage and arguments identical to `workaround_reset_start`. The _cve argument
+ * is kept here so the same #define can be used as that macro
+ */
+.macro workaround_reset_end _cpu:req, _cve:req, _id:req
+	_workaround_end \_cpu, \_id
+.endm
+
+/*
+ * See `workaround_reset_start` for usage info. The _cve argument is kept here
+ * so the same #define can be used as that macro. Additional arguments:
+ *
+ * _no_isb:
+ *	Optionally do not include the trailing isb. Please disable with the
+ *	NO_ISB macro
+ */
+.macro workaround_runtime_end _cpu:req, _cve:req, _id:req, _no_isb
+	/*
+	 * Runtime errata do not have a reset function to call the isb for them
+	 * and missing the isb could be very problematic. It is also likely as
+	 * they tend to be scattered in generic code.
+	 */
+	.ifb \_no_isb
+		isb
+	.endif
+	_workaround_end \_cpu, \_id
+.endm
+
+/*******************************************************************************
+ * Errata workaround helpers
+ ******************************************************************************/
+/*
+ * Set a bit in a system register. Can set multiple bits but is limited by the
+ *  way the ORR instruction encodes them.
+ *
+ * _reg:
+ *	Register to write to
+ *
+ * _bit:
+ *	Bit to set. Please use a descriptive #define
+ *
+ * _assert:
+ *	Optionally whether to read back and assert that the bit has been
+ *	written. Please disable with NO_ASSERT macro
+ *
+ * clobbers: x1
+ */
+.macro sysreg_bit_set _reg:req, _bit:req, _assert=1
+	mrs	x1, \_reg
+	orr	x1, x1, #\_bit
+	msr	\_reg, x1
+.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:
+ *	Name of cpu as given to declare_cpu_ops
+ *
+ * _cve:
+ *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
+ *
+ * _id:
+ *	Erratum or CVE number. Please combine with previous field with ERRATUM
+ *	or CVE macros
+ *
+ * _chosen:
+ *	Compile time flag on whether the erratum is included
+ *
+ * clobbers: x0-x9 (PCS compliant)
+ */
+.macro apply_erratum _cpu:req, _cve:req, _id:req, _chosen:req
+	.if \_chosen
+		mov	x9, x30
+		bl	cpu_get_rev_var
+		bl	erratum_\_cpu\()_\_id\()_wa
+		mov	x30, x9
+
+	.endif
+.endm
+
+/*
+ * Helpers to select which revisions errata apply to. Don't leave a link
+ * register as the cpu_rev_var_*** will call the ret and we can save on one.
+ *
+ * _cpu:
+ *	Name of cpu as given to declare_cpu_ops
+ *
+ * _cve:
+ *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
+ *
+ * _id:
+ *	Erratum or CVE number. Please combine with previous field with ERRATUM
+ *	or CVE macros
+ *
+ * _rev_num:
+ *	Revision to apply to
+ *
+ * in body:
+ *	clobber: x0 to x4
+ *	argument: x0 - cpu_rev_var
+ */
+.macro check_erratum_ls _cpu:req, _cve:req, _id:req, _rev_num:req
+	func check_erratum_\_cpu\()_\_id
+		mov	x1, #\_rev_num
+		b	cpu_rev_var_ls
+	endfunc check_erratum_\_cpu\()_\_id
+.endm
+
+.macro check_erratum_hs _cpu:req, _cve:req, _id:req, _rev_num:req
+	func check_erratum_\_cpu\()_\_id
+		mov	x1, #\_rev_num
+		b	cpu_rev_var_hs
+	endfunc check_erratum_\_cpu\()_\_id
+.endm
+
+.macro check_erratum_range _cpu:req, _cve:req, _id:req, _rev_num_lo:req, _rev_num_hi:req
+	func check_erratum_\_cpu\()_\_id
+		mov	x1, #\_rev_num_lo
+		mov	x2, #\_rev_num_hi
+		b	cpu_rev_var_range
+	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
+ ******************************************************************************/
+
+/*
+ * Wrapper to automatically apply all reset-time errata. Will end with an isb.
+ *
+ * _cpu:
+ *	Name of cpu as given to declare_cpu_ops
+ *
+ * in body:
+ *	clobber x8 to x14
+ *	argument x14 - cpu_rev_var
+ */
+.macro cpu_reset_func_start _cpu:req
+	func \_cpu\()_reset_func
+		mov	x15, x30
+		bl	cpu_get_rev_var
+		mov	x14, x0
+
+		/* short circuit the location to avoid searching the list */
+		adrp	x12, \_cpu\()_errata_list_start
+		add	x12, x12, :lo12:\_cpu\()_errata_list_start
+		adrp	x13, \_cpu\()_errata_list_end
+		add	x13, x13, :lo12:\_cpu\()_errata_list_end
+
+	errata_begin:
+		/* if head catches up with end of list, exit */
+		cmp	x12, x13
+		b.eq	errata_end
+
+		ldr	x10, [x12, #ERRATUM_WA_FUNC]
+		/* TODO(errata ABI): check mitigated and checker function fields
+		 * for 0 */
+		ldrb	w11, [x12, #ERRATUM_CHOSEN]
+
+		/* skip if not chosen */
+		cbz	x11, 1f
+		/* skip if runtime erratum */
+		cbz	x10, 1f
+
+		/* put cpu revision in x0 and call workaround */
+		mov	x0, x14
+		blr	x10
+	1:
+		add	x12, x12, #ERRATUM_ENTRY_SIZE
+		b	errata_begin
+	errata_end:
+.endm
+
+.macro cpu_reset_func_end _cpu:req
+		isb
+		ret	x15
+	endfunc \_cpu\()_reset_func
+.endm
+
+/*
+ * Maintain compatibility with the old scheme of each cpu has its own reporting.
+ * TODO remove entirely once all cpus have been converted. This includes the
+ * cpu_ops entry, as print_errata_status can call this directly for all cpus
+ */
+.macro errata_report_shim _cpu:req
+	#if REPORT_ERRATA
+	func \_cpu\()_errata_report
+		/* normal stack frame for pretty debugging */
+		stp	x29, x30, [sp, #-16]!
+		mov	x29, sp
+
+		bl	generic_errata_report
+
+		ldp	x29, x30, [sp], #16
+		ret
+	endfunc \_cpu\()_errata_report
+	#endif
+.endm
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/cpus/aarch64/generic.h b/include/lib/cpus/aarch64/generic.h
index 53df587..dd71554 100644
--- a/include/lib/cpus/aarch64/generic.h
+++ b/include/lib/cpus/aarch64/generic.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserverd.
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/neoverse_hermes.h b/include/lib/cpus/aarch64/neoverse_hermes.h
new file mode 100644
index 0000000..22492c3
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_hermes.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_HERMES_H
+#define NEOVERSE_HERMES_H
+
+#define NEOVERSE_HERMES_MIDR				U(0x410FD8E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_HERMES_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_HERMES_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* NEOVERSE_HERMES_H */
diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h
new file mode 100644
index 0000000..8b36ff1
--- /dev/null
+++ b/include/lib/cpus/cpu_ops.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CPU_OPS_H
+#define CPU_OPS_H
+
+#include <arch.h>
+
+#define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
+				(MIDR_PN_MASK << MIDR_PN_SHIFT)
+
+/* Hardcode to keep compatible with assembly. sizeof(uintptr_t) */
+#if __aarch64__
+#define CPU_WORD_SIZE			8
+#else
+#define CPU_WORD_SIZE			4
+#endif /* __aarch64__ */
+
+/* The number of CPU operations allowed */
+#define CPU_MAX_PWR_DWN_OPS		2
+/* Special constant to specify that CPU has no reset function */
+#define CPU_NO_RESET_FUNC		0
+
+#if __aarch64__
+#define CPU_NO_EXTRA1_FUNC		0
+#define CPU_NO_EXTRA2_FUNC		0
+#define CPU_NO_EXTRA3_FUNC		0
+#endif /* __aarch64__ */
+
+
+/*
+ * Define the sizes of the fields in the cpu_ops structure. Word size is set per
+ * Aarch so keep these definitions the same and each can include whatever it
+ * needs.
+ */
+#define CPU_MIDR_SIZE		CPU_WORD_SIZE
+#ifdef IMAGE_AT_EL3
+#define CPU_RESET_FUNC_SIZE	CPU_WORD_SIZE
+#else
+#define CPU_RESET_FUNC_SIZE	0
+#endif /* IMAGE_AT_EL3 */
+#define CPU_EXTRA1_FUNC_SIZE	CPU_WORD_SIZE
+#define CPU_EXTRA2_FUNC_SIZE	CPU_WORD_SIZE
+#define CPU_EXTRA3_FUNC_SIZE	CPU_WORD_SIZE
+#define CPU_E_HANDLER_FUNC_SIZE CPU_WORD_SIZE
+/* The power down core and cluster is needed only in BL31 and BL32 */
+#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
+#define CPU_PWR_DWN_OPS_SIZE	CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
+#else
+#define CPU_PWR_DWN_OPS_SIZE	0
+#endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
+
+#define CPU_ERRATA_LIST_START_SIZE	CPU_WORD_SIZE
+#define CPU_ERRATA_LIST_END_SIZE	CPU_WORD_SIZE
+/* Fields required to print errata status  */
+#if REPORT_ERRATA
+#define CPU_ERRATA_FUNC_SIZE	CPU_WORD_SIZE
+#define CPU_CPU_STR_SIZE	CPU_WORD_SIZE
+/* BL1 doesn't require mutual exclusion and printed flag. */
+#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
+#define CPU_ERRATA_LOCK_SIZE	CPU_WORD_SIZE
+#define CPU_ERRATA_PRINTED_SIZE	CPU_WORD_SIZE
+#else
+#define CPU_ERRATA_LOCK_SIZE	0
+#define CPU_ERRATA_PRINTED_SIZE	0
+#endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
+#else
+#define CPU_ERRATA_FUNC_SIZE	0
+#define CPU_CPU_STR_SIZE	0
+#define CPU_ERRATA_LOCK_SIZE	0
+#define CPU_ERRATA_PRINTED_SIZE	0
+#endif /* REPORT_ERRATA */
+
+#if defined(IMAGE_BL31) && CRASH_REPORTING
+#define CPU_REG_DUMP_SIZE	CPU_WORD_SIZE
+#else
+#define CPU_REG_DUMP_SIZE	0
+#endif /* defined(IMAGE_BL31) && CRASH_REPORTING */
+
+
+/*
+ * Define the offsets to the fields in cpu_ops structure. Every offset is
+ * defined based on the offset and size of the previous field.
+ */
+#define CPU_MIDR		0
+#define CPU_RESET_FUNC		CPU_MIDR + CPU_MIDR_SIZE
+#if __aarch64__
+#define CPU_EXTRA1_FUNC		CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
+#define CPU_EXTRA2_FUNC		CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE
+#define CPU_EXTRA3_FUNC		CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE
+#define CPU_E_HANDLER_FUNC	CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE
+#define CPU_PWR_DWN_OPS		CPU_E_HANDLER_FUNC + CPU_E_HANDLER_FUNC_SIZE
+#else
+#define CPU_PWR_DWN_OPS		CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
+#endif /* __aarch64__ */
+#define CPU_ERRATA_LIST_START	CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
+#define CPU_ERRATA_LIST_END	CPU_ERRATA_LIST_START + CPU_ERRATA_LIST_START_SIZE
+#define CPU_ERRATA_FUNC		CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE
+#define CPU_CPU_STR		CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
+#define CPU_ERRATA_LOCK		CPU_CPU_STR + CPU_CPU_STR_SIZE
+#define CPU_ERRATA_PRINTED	CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
+#if __aarch64__
+#define CPU_REG_DUMP		CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
+#define CPU_OPS_SIZE		CPU_REG_DUMP + CPU_REG_DUMP_SIZE
+#else
+#define CPU_OPS_SIZE		CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
+#endif /* __aarch64__ */
+
+#ifndef __ASSEMBLER__
+#include <lib/cassert.h>
+#include <lib/spinlock.h>
+
+struct cpu_ops {
+	unsigned long midr;
+#ifdef IMAGE_AT_EL3
+	void (*reset_func)(void);
+#endif /* IMAGE_AT_EL3 */
+#if __aarch64__
+	void (*extra1_func)(void);
+	void (*extra2_func)(void);
+	void (*extra3_func)(void);
+	void (*e_handler_func)(long es);
+#endif /* __aarch64__ */
+#if (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS
+	void (*pwr_dwn_ops[CPU_MAX_PWR_DWN_OPS])(void);
+#endif /* (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS */
+	void *errata_list_start;
+	void *errata_list_end;
+#if REPORT_ERRATA
+	void (*errata_func)(void);
+	char *cpu_str;
+#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
+	spinlock_t *errata_lock;
+	unsigned int *errata_reported;
+#endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
+#endif /* REPORT_ERRATA */
+#if defined(IMAGE_BL31) && CRASH_REPORTING
+	void (*reg_dump)(void);
+#endif /* defined(IMAGE_BL31) && CRASH_REPORTING */
+} __packed;
+
+CASSERT(sizeof(struct cpu_ops) == CPU_OPS_SIZE,
+	assert_cpu_ops_asm_c_different_sizes);
+
+long cpu_get_rev_var(void);
+void *get_cpu_ops_ptr(void);
+
+#endif /* __ASSEMBLER__ */
+#endif /* CPU_OPS_H */
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
new file mode 100644
index 0000000..b280435
--- /dev/null
+++ b/include/lib/cpus/errata.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ERRATA_REPORT_H
+#define ERRATA_REPORT_H
+
+#include <lib/cpus/cpu_ops.h>
+
+
+#define ERRATUM_WA_FUNC_SIZE	CPU_WORD_SIZE
+#define ERRATUM_CHECK_FUNC_SIZE	CPU_WORD_SIZE
+#define ERRATUM_ID_SIZE		4
+#define ERRATUM_CVE_SIZE	2
+#define ERRATUM_CHOSEN_SIZE	1
+#define ERRATUM_MITIGATED_SIZE	1
+
+#define ERRATUM_WA_FUNC		0
+#define ERRATUM_CHECK_FUNC	ERRATUM_WA_FUNC + ERRATUM_WA_FUNC_SIZE
+#define ERRATUM_ID		ERRATUM_CHECK_FUNC + ERRATUM_CHECK_FUNC_SIZE
+#define ERRATUM_CVE		ERRATUM_ID + ERRATUM_ID_SIZE
+#define ERRATUM_CHOSEN		ERRATUM_CVE + ERRATUM_CVE_SIZE
+#define ERRATUM_MITIGATED	ERRATUM_CHOSEN + ERRATUM_CHOSEN_SIZE
+#define ERRATUM_ENTRY_SIZE	ERRATUM_MITIGATED + ERRATUM_MITIGATED_SIZE
+
+#ifndef __ASSEMBLER__
+#include <lib/cassert.h>
+
+void print_errata_status(void);
+void errata_print_msg(unsigned int status, const char *cpu, const char *id);
+
+/*
+ * NOTE that this structure will be different on AArch32 and AArch64. The
+ * uintptr_t will reflect the change and the alignment will be correct in both.
+ */
+struct erratum_entry {
+	uintptr_t (*wa_func)(uint64_t cpu_rev);
+	uintptr_t (*check_func)(uint64_t cpu_rev);
+	/* Will fit CVEs with up to 10 character in the ID field */
+	uint32_t id;
+	/* Denote CVEs with their year or errata with 0 */
+	uint16_t cve;
+	uint8_t chosen;
+	/* TODO(errata ABI): placeholder for the mitigated field */
+	uint8_t _mitigated;
+} __packed;
+
+CASSERT(sizeof(struct erratum_entry) == ERRATUM_ENTRY_SIZE,
+	assert_erratum_entry_asm_c_different_sizes);
+#else
+
+/*
+ * errata framework macro helpers
+ *
+ * NOTE an erratum and CVE id could clash. However, both numbers are very large
+ * and the probablity is minuscule. Working around this makes code very
+ * complicated and extremely difficult to read so it is not considered. In the
+ * unlikely event that this does happen, prepending the CVE id with a 0 should
+ * resolve the conflict
+ */
+#define ERRATUM(id)		0, id
+#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__ */
+
+/* Errata status */
+#define ERRATA_NOT_APPLIES	0
+#define ERRATA_APPLIES		1
+#define ERRATA_MISSING		2
+
+/* Macro to get CPU revision code for checking errata version compatibility. */
+#define CPU_REV(r, p)		((r << 4) | p)
+
+#endif /* ERRATA_REPORT_H */
diff --git a/include/lib/cpus/errata_report.h b/include/lib/cpus/errata_report.h
deleted file mode 100644
index efdedf0..0000000
--- a/include/lib/cpus/errata_report.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ERRATA_REPORT_H
-#define ERRATA_REPORT_H
-
-#ifndef __ASSEMBLER__
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <lib/spinlock.h>
-#include <lib/utils_def.h>
-
-#if DEBUG
-void print_errata_status(void);
-#else
-static inline void print_errata_status(void) {}
-#endif
-
-void errata_print_msg(unsigned int status, const char *cpu, const char *id);
-int errata_needs_reporting(spinlock_t *lock, uint32_t *reported);
-
-#endif /* __ASSEMBLER__ */
-
-/* Errata status */
-#define ERRATA_NOT_APPLIES	0
-#define ERRATA_APPLIES		1
-#define ERRATA_MISSING		2
-
-/* Macro to get CPU revision code for checking errata version compatibility. */
-#define CPU_REV(r, p)		((r << 4) | p)
-
-#endif /* ERRATA_REPORT_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 31d8f07..e6af43e 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -193,7 +193,6 @@
 // Only if MTE registers in use
 #define CTX_TFSR_EL2		U(0x100)
 
-// Only if ENABLE_MPAM_FOR_LOWER_ELS==1
 #define CTX_MPAM2_EL2		U(0x108)
 #define CTX_MPAMHCR_EL2		U(0x110)
 #define CTX_MPAMVPM0_EL2	U(0x118)
@@ -231,9 +230,15 @@
 
 // Starting with Armv8.9
 #define CTX_TCR2_EL2            U(0x1d8)
+#define CTX_POR_EL2             U(0x1e0)
+#define CTX_PIRE0_EL2           U(0x1e8)
+#define CTX_PIR_EL2             U(0x1f0)
+#define CTX_S2PIR_EL2		U(0x1f8)
+#define CTX_GCSCR_EL2           U(0x200)
+#define CTX_GCSPR_EL2           U(0x208)
 
 /* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END	U(0x1e0)
+#define CTX_EL2_SYSREGS_END	U(0x210)
 
 #endif /* CTX_INCLUDE_EL2_REGS */
 
@@ -514,38 +519,10 @@
 #if CTX_INCLUDE_EL2_REGS
 void el2_sysregs_context_save_common(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_common(el2_sysregs_t *regs);
-#if ENABLE_SPE_FOR_LOWER_ELS
-void el2_sysregs_context_save_spe(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_spe(el2_sysregs_t *regs);
-#endif /* ENABLE_SPE_FOR_LOWER_ELS */
 #if CTX_INCLUDE_MTE_REGS
 void el2_sysregs_context_save_mte(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_mte(el2_sysregs_t *regs);
 #endif /* CTX_INCLUDE_MTE_REGS */
-#if ENABLE_MPAM_FOR_LOWER_ELS
-void el2_sysregs_context_save_mpam(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs);
-#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-#if ENABLE_FEAT_ECV
-void el2_sysregs_context_save_ecv(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_ecv(el2_sysregs_t *regs);
-#endif /* ENABLE_FEAT_ECV */
-#if ENABLE_FEAT_VHE
-void el2_sysregs_context_save_vhe(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_vhe(el2_sysregs_t *regs);
-#endif /* ENABLE_FEAT_VHE */
-#if RAS_EXTENSION
-void el2_sysregs_context_save_ras(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_ras(el2_sysregs_t *regs);
-#endif /* RAS_EXTENSION */
-#if CTX_INCLUDE_NEVE_REGS
-void el2_sysregs_context_save_nv2(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_nv2(el2_sysregs_t *regs);
-#endif /* CTX_INCLUDE_NEVE_REGS */
-#if ENABLE_FEAT_CSV2_2
-void el2_sysregs_context_save_csv2(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_csv2(el2_sysregs_t *regs);
-#endif /* ENABLE_FEAT_CSV2_2 */
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 #if CTX_INCLUDE_FPREGS
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 1a76d8e..aa76f3b 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -37,6 +37,9 @@
 void cm_prepare_el3_exit_ns(void);
 
 #ifdef __aarch64__
+#if IMAGE_BL31
+void cm_manage_extensions_el3(void);
+#endif
 #if CTX_INCLUDE_EL2_REGS
 void cm_el2_sysregs_context_save(uint32_t security_state);
 void cm_el2_sysregs_context_restore(uint32_t security_state);
@@ -84,6 +87,7 @@
 #else
 void *cm_get_next_context(void);
 void cm_set_next_context(void *context);
+static inline void cm_manage_extensions_el3(void) {}
 #endif /* __aarch64__ */
 
 #endif /* CONTEXT_MGMT_H */
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
index 6452f7e..de476e4 100644
--- a/include/lib/extensions/amu.h
+++ b/include/lib/extensions/amu.h
@@ -14,11 +14,23 @@
 
 #include <platform_def.h>
 
+#if ENABLE_FEAT_AMU
 #if __aarch64__
 void amu_enable(bool el2_unused, cpu_context_t *ctx);
 #else
 void amu_enable(bool el2_unused);
 #endif
+#else
+#if __aarch64__
+static inline void amu_enable(bool el2_unused, cpu_context_t *ctx)
+{
+}
+#else
+static inline void amu_enable(bool el2_unused)
+{
+}
+#endif
+#endif
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
 /*
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
index aee208d..9ee2444 100644
--- a/include/lib/extensions/brbe.h
+++ b/include/lib/extensions/brbe.h
@@ -10,7 +10,7 @@
 #if ENABLE_BRBE_FOR_NS
 void brbe_enable(void);
 #else
-void brbe_enable(void)
+static inline void brbe_enable(void)
 {
 }
 #endif /* ENABLE_BRBE_FOR_NS */
diff --git a/include/lib/extensions/mpam.h b/include/lib/extensions/mpam.h
index 414adcb..4327278 100644
--- a/include/lib/extensions/mpam.h
+++ b/include/lib/extensions/mpam.h
@@ -9,6 +9,12 @@
 
 #include <stdbool.h>
 
+#if ENABLE_MPAM_FOR_LOWER_ELS
 void mpam_enable(bool el2_unused);
+#else
+static inline void mpam_enable(bool el2_unused)
+{
+}
+#endif
 
 #endif /* MPAM_H */
diff --git a/include/lib/extensions/pmuv3.h b/include/lib/extensions/pmuv3.h
new file mode 100644
index 0000000..5d5d055
--- /dev/null
+++ b/include/lib/extensions/pmuv3.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMUV3_H
+#define PMUV3_H
+
+#include <context.h>
+
+void pmuv3_disable_el3(void);
+
+#ifdef __aarch64__
+void pmuv3_enable(cpu_context_t *ctx);
+void pmuv3_init_el2_unused(void);
+#endif /* __aarch64__ */
+
+#endif /* PMUV3_H */
diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h
index 893f9f2..0e9c4b9 100644
--- a/include/lib/extensions/sme.h
+++ b/include/lib/extensions/sme.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,6 @@
 #define SME_H
 
 #include <stdbool.h>
-
 #include <context.h>
 
 /*
@@ -21,7 +20,16 @@
  */
 #define SME_SMCR_LEN_MAX	U(0x1FF)
 
+#if ENABLE_SME_FOR_NS
 void sme_enable(cpu_context_t *context);
 void sme_disable(cpu_context_t *context);
+#else
+static inline void sme_enable(cpu_context_t *context)
+{
+}
+static inline void sme_disable(cpu_context_t *context)
+{
+}
+#endif /* ENABLE_SME_FOR_NS */
 
 #endif /* SME_H */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index d4b925f..02fccae 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -9,8 +9,16 @@
 
 #include <stdbool.h>
 
-bool spe_supported(void);
+#if ENABLE_SPE_FOR_NS
 void spe_enable(bool el2_unused);
 void spe_disable(void);
+#else
+static inline void spe_enable(bool el2_unused)
+{
+}
+static inline void spe_disable(void)
+{
+}
+#endif
 
 #endif /* SPE_H */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 4b66cdb..1faed2d 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,16 @@
 
 #include <context.h>
 
+#if (ENABLE_SME_FOR_NS || ENABLE_SVE_FOR_NS)
 void sve_enable(cpu_context_t *context);
 void sve_disable(cpu_context_t *context);
+#else
+static inline void sve_enable(cpu_context_t *context)
+{
+}
+static inline void sve_disable(cpu_context_t *context)
+{
+}
+#endif /* ( ENABLE_SME_FOR_NS | ENABLE_SVE_FOR_NS ) */
 
 #endif /* SVE_H */
diff --git a/include/lib/extensions/sys_reg_trace.h b/include/lib/extensions/sys_reg_trace.h
index 74470fe..5915c55 100644
--- a/include/lib/extensions/sys_reg_trace.h
+++ b/include/lib/extensions/sys_reg_trace.h
@@ -9,10 +9,24 @@
 
 #include <context.h>
 
+#if ENABLE_SYS_REG_TRACE_FOR_NS
 #if __aarch64__
 void sys_reg_trace_enable(cpu_context_t *context);
 #else
 void sys_reg_trace_enable(void);
 #endif /* __aarch64__ */
 
+#else /* !ENABLE_SYS_REG_TRACE_FOR_NS */
+
+#if __aarch64__
+static inline void sys_reg_trace_enable(cpu_context_t *context)
+{
+}
+#else
+static inline void sys_reg_trace_enable(void)
+{
+}
+#endif /* __aarch64__ */
+#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+
 #endif /* SYS_REG_TRACE_H */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
index 0eff7c4..861a4ad 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -10,7 +10,7 @@
 #if ENABLE_TRBE_FOR_NS
 void trbe_enable(void);
 #else
-void trbe_enable(void)
+static inline void trbe_enable(void)
 {
 }
 #endif /* ENABLE_TRBE_FOR_NS */
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
index a440abd..91a9615 100644
--- a/include/lib/extensions/trf.h
+++ b/include/lib/extensions/trf.h
@@ -10,7 +10,7 @@
 #if ENABLE_TRF_FOR_NS
 void trf_enable(void);
 #else
-void trf_enable(void)
+static inline void trf_enable(void)
 {
 }
 #endif /* ENABLE_TRF_FOR_NS */
diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h
index 423f0db..2423f38 100644
--- a/include/lib/libc/cdefs.h
+++ b/include/lib/libc/cdefs.h
@@ -15,6 +15,7 @@
 #define __maybe_unused	__attribute__((__unused__))
 #define __aligned(x)	__attribute__((__aligned__(x)))
 #define __section(x)	__attribute__((__section__(x)))
+#define __fallthrough	__attribute__((__fallthrough__))
 #if RECLAIM_INIT_CODE
 /*
  * Add each function to a section that is unique so the functions can still
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/psa/measured_boot.h b/include/lib/psa/measured_boot.h
index 231da2c..af624a6 100644
--- a/include/lib/psa/measured_boot.h
+++ b/include/lib/psa/measured_boot.h
@@ -36,10 +36,10 @@
  * signer_id			Pointer to signer_id buffer.
  * signer_id_size		Size of the signer_id in bytes.
  * version			Pointer to version buffer.
- * version_size			Size of the version string in bytes (with \0).
+ * version_size			Size of the version string in bytes.
  * measurement_algo		Algorithm identifier used for measurement.
  * sw_type			Pointer to sw_type buffer.
- * sw_type_size			Size of the sw_type string in bytes (with \0).
+ * sw_type_size			Size of the sw_type string in bytes.
  * measurement_value		Pointer to measurement_value buffer.
  * measurement_value_size	Size of the measurement_value in bytes.
  * lock_measurement		Boolean flag requesting whether the measurement
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index b56e98b..01dc3cb 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,6 +60,7 @@
 #define PSCI_NODE_HW_STATE_AARCH64	U(0xc400000d)
 #define PSCI_SYSTEM_SUSPEND_AARCH32	U(0x8400000E)
 #define PSCI_SYSTEM_SUSPEND_AARCH64	U(0xc400000E)
+#define PSCI_SET_SUSPEND_MODE		U(0x8400000F)
 #define PSCI_STAT_RESIDENCY_AARCH32	U(0x84000010)
 #define PSCI_STAT_RESIDENCY_AARCH64	U(0xc4000010)
 #define PSCI_STAT_COUNT_AARCH32		U(0x84000011)
@@ -73,9 +75,17 @@
  * Number of PSCI calls (above) implemented
  */
 #if ENABLE_PSCI_STAT
-#define PSCI_NUM_CALLS			U(22)
+#if PSCI_OS_INIT_MODE
+#define PSCI_NUM_CALLS			U(30)
 #else
-#define PSCI_NUM_CALLS			U(18)
+#define PSCI_NUM_CALLS			U(29)
+#endif
+#else
+#if PSCI_OS_INIT_MODE
+#define PSCI_NUM_CALLS			U(26)
+#else
+#define PSCI_NUM_CALLS			U(25)
+#endif
 #endif
 
 /* The macros below are used to identify PSCI calls from the SMC function ID */
@@ -134,7 +144,11 @@
 
 /* Features flags for CPU SUSPEND OS Initiated mode support. Bits [0:0] */
 #define FF_MODE_SUPPORT_SHIFT		U(0)
+#if PSCI_OS_INIT_MODE
 #define FF_SUPPORTS_OS_INIT_MODE	U(1)
+#else
+#define FF_SUPPORTS_OS_INIT_MODE	U(0)
+#endif
 
 /*******************************************************************************
  * PSCI version
@@ -268,6 +282,13 @@
 	 * for the CPU.
 	 */
 	plat_local_state_t pwr_domain_state[PLAT_MAX_PWR_LVL + U(1)];
+#if PSCI_OS_INIT_MODE
+	/*
+	 * The highest power level at which the current CPU is the last running
+	 * CPU.
+	 */
+	unsigned int last_at_pwrlvl;
+#endif
 } psci_power_state_t;
 
 /*******************************************************************************
@@ -297,6 +318,11 @@
 	void (*cpu_standby)(plat_local_state_t cpu_state);
 	int (*pwr_domain_on)(u_register_t mpidr);
 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
+	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);
 	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
@@ -347,6 +373,9 @@
 int psci_node_hw_state(u_register_t target_cpu,
 		       unsigned int power_level);
 int psci_features(unsigned int psci_fid);
+#if PSCI_OS_INIT_MODE
+int psci_set_suspend_mode(unsigned int mode);
+#endif
 void __dead2 psci_power_down_wfi(void);
 void psci_arch_setup(void);
 
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 3edc50b..4b244ec 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -92,6 +92,7 @@
 int psci_stop_other_cores(unsigned int wait_ms,
 			  void (*stop_func)(u_register_t mpidr));
 bool psci_is_last_on_cpu_safe(void);
+bool psci_are_all_cpus_on_safe(void);
 void psci_pwrdown_cpu(unsigned int power_level);
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index cce91af..fb2b3a2 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -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
@@ -37,9 +37,13 @@
 #define FUNCID_OEN_MASK			U(0x3f)
 #define FUNCID_OEN_WIDTH		U(6)
 
-#define FUNCID_SVE_HINT_SHIFT          U(16)
-#define FUNCID_SVE_HINT_MASK           U(1)
-#define FUNCID_SVE_HINT_WIDTH          U(1)
+#define FUNCID_FC_RESERVED_SHIFT	U(17)
+#define FUNCID_FC_RESERVED_MASK		U(0x7f)
+#define FUNCID_FC_RESERVED_WIDTH	U(7)
+
+#define FUNCID_SVE_HINT_SHIFT		U(16)
+#define FUNCID_SVE_HINT_MASK		U(1)
+#define FUNCID_SVE_HINT_WIDTH		U(1)
 
 #define FUNCID_NUM_SHIFT		U(0)
 #define FUNCID_NUM_MASK			U(0xffff)
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 925ff21..bf1f93a 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_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
  */
@@ -539,7 +539,8 @@
  * Define limit of firmware configuration memory:
  * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
  */
-#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
+#define ARM_FW_CONFIGS_SIZE		(PAGE_SIZE * 2)
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
 
 #if ENABLE_RME
 /*
@@ -731,7 +732,7 @@
 #  define TSP_SEC_MEM_SIZE		PLAT_ARM_TRUSTED_DRAM_SIZE
 #  define BL32_BASE			PLAT_ARM_TRUSTED_DRAM_BASE
 #  define BL32_LIMIT			(PLAT_ARM_TRUSTED_DRAM_BASE	\
-						+ (UL(1) << 21))
+						+ SZ_4M)
 # elif ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
 #  define TSP_SEC_MEM_BASE		ARM_AP_TZC_DRAM1_BASE
 #  define TSP_SEC_MEM_SIZE		ARM_AP_TZC_DRAM1_SIZE
@@ -775,7 +776,9 @@
 #define PLAT_PERCPU_BAKERY_LOCK_SIZE		(1 * CACHE_WRITEBACK_GRANULE)
 
 /* Priority levels for ARM platforms */
+#if RAS_FFH_SUPPORT
 #define PLAT_RAS_PRI			0x10
+#endif
 #define PLAT_SDEI_CRITICAL_PRI		0x60
 #define PLAT_SDEI_NORMAL_PRI		0x70
 
diff --git a/include/plat/arm/common/fconf_ethosn_getter.h b/include/plat/arm/common/fconf_ethosn_getter.h
index 5b9a7ed..cafbc3e 100644
--- a/include/plat/arm/common/fconf_ethosn_getter.h
+++ b/include/plat/arm/common/fconf_ethosn_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,6 +45,7 @@
 
 struct ethosn_device_t {
 	bool has_reserved_memory;
+	uint64_t reserved_memory_addr;
 	uint32_t num_cores;
 	struct ethosn_core_t cores[ETHOSN_DEV_CORE_NUM_MAX];
 	uint32_t num_allocators;
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 494e470..e8461f5 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.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
  */
@@ -125,6 +125,12 @@
 #define ARM_LOCAL_PSTATE_WIDTH		4
 #define ARM_LOCAL_PSTATE_MASK		((1 << ARM_LOCAL_PSTATE_WIDTH) - 1)
 
+#if PSCI_OS_INIT_MODE
+#define ARM_LAST_AT_PLVL_MASK		(ARM_LOCAL_PSTATE_MASK <<	\
+					 (ARM_LOCAL_PSTATE_WIDTH *	\
+					  (PLAT_MAX_PWR_LVL + 1)))
+#endif /* __PSCI_OS_INIT_MODE__ */
+
 /* Macros to construct the composite power state */
 
 /* Make composite power state parameter till power level 0 */
@@ -261,8 +267,10 @@
 			uintptr_t log_addr,
 #endif
 			size_t log_size, uintptr_t *ns_log_addr);
-int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size);
-int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size);
+int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size,
+		       size_t log_max_size);
+int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
+		       size_t *log_max_size);
 #endif /* MEASURED_BOOT */
 
 /*
@@ -356,6 +364,7 @@
 /* secure watchdog */
 void plat_arm_secure_wdt_start(void);
 void plat_arm_secure_wdt_stop(void);
+void plat_arm_secure_wdt_refresh(void);
 
 /* Get SOC-ID of ARM platform */
 uint32_t plat_arm_get_soc_id(void);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index dde174c..f87f857 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,18 +52,21 @@
  * terminology. On a GICv2 system or mode, the interrupts will be treated as
  * Group 0 interrupts.
  */
-#define CSS_G1S_IRQ_PROPS(grp) \
+#define CSS_G1S_INT_PROPS(grp) \
 	INTR_PROP_DESC(CSS_IRQ_MHU, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_TZC, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
+#define CSS_G1S_IRQ_PROPS(grp) \
+	CSS_G1S_INT_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
 #if CSS_USE_SCMI_SDS_DRIVER
 /* Memory region for shared data storage */
 #define PLAT_ARM_SDS_MEM_BASE		ARM_SHARED_RAM_BASE
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index a14d775..d146a29 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -44,10 +44,17 @@
  * plat_get_rotpk_info() flags
  ******************************************************************************/
 #define ROTPK_IS_HASH			(1 << 0)
+
 /* Flag used to skip verification of the certificate ROTPK while the platform
    ROTPK is not deployed */
 #define ROTPK_NOT_DEPLOYED		(1 << 1)
 
+static inline bool is_rotpk_flags_valid(unsigned int flags)
+{
+	unsigned int valid_flags = ROTPK_IS_HASH;
+	return (flags == ROTPK_NOT_DEPLOYED) || ((flags & ~valid_flags) == 0);
+}
+
 /*******************************************************************************
  * plat_get_enc_key_info() flags
  ******************************************************************************/
@@ -345,8 +352,6 @@
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
 int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc,
 		unsigned int nv_ctr);
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hash_pk_len);
 int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size);
 int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
 			  size_t *key_len, unsigned int *flags,
diff --git a/include/services/el3_spmc_ffa_memory.h b/include/services/el3_spmc_ffa_memory.h
index 2037eca..5d3af5d 100644
--- a/include/services/el3_spmc_ffa_memory.h
+++ b/include/services/el3_spmc_ffa_memory.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
  */
@@ -217,6 +217,8 @@
 	struct ffa_emad_v1_0 emad[];
 };
 CASSERT(sizeof(struct ffa_mtd_v1_0) == 32, assert_ffa_mtd_size_v1_0_mismatch);
+CASSERT(offsetof(struct ffa_mtd_v1_0, emad) == 32,
+	assert_ffa_mtd_size_v1_0_mismatch_2);
 
 /**
  * struct ffa_mtd - Memory transaction descriptor for FF-A v1.1.
@@ -254,5 +256,8 @@
 	uint64_t reserved_40_47;
 };
 CASSERT(sizeof(struct ffa_mtd) == 48, assert_ffa_mtd_size_mismatch);
+CASSERT(offsetof(struct ffa_mtd, emad_count) ==
+	offsetof(struct ffa_mtd_v1_0, emad_count),
+	assert_ffa_mtd_emad_count_offset_mismatch);
 
 #endif /* EL3_SPMC_FFA_MEM_H */
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/include/services/errata_abi_svc.h b/include/services/errata_abi_svc.h
new file mode 100644
index 0000000..1250066
--- /dev/null
+++ b/include/services/errata_abi_svc.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ERRATA_ABI_SVC_H
+#define ERRATA_ABI_SVC_H
+
+#include <lib/smccc.h>
+
+#define ARM_EM_VERSION			U(0x840000F0)
+#define ARM_EM_FEATURES			U(0x840000F1)
+#define ARM_EM_CPU_ERRATUM_FEATURES	U(0x840000F2)
+
+/* EM version numbers */
+#define EM_VERSION_MAJOR		(0x1)
+#define EM_VERSION_MINOR		(0x0)
+
+/* EM CPU_ERRATUM_FEATURES return codes */
+#define EM_HIGHER_EL_MITIGATION		(3)
+#define EM_NOT_AFFECTED			(2)
+#define EM_AFFECTED			(1)
+#define EM_SUCCESS			(0)
+#define EM_NOT_SUPPORTED		(-1)
+#define EM_INVALID_PARAMETERS		(-2)
+#define EM_UNKNOWN_ERRATUM		(-3)
+
+#if ERRATA_ABI_SUPPORT
+bool is_errata_fid(uint32_t smc_fid);
+#else
+static inline bool is_errata_fid(uint32_t smc_fid)
+{
+	return false;
+}
+#endif /* ERRATA_ABI_SUPPORT */
+uintptr_t errata_abi_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
+);
+#endif /* ERRATA_ABI_SVC_H */
+
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 8bc911a..64af437 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE	U(0x60)
-#define FFA_FNUM_MAX_VALUE	U(0x8B)
+#define FFA_FNUM_MAX_VALUE	U(0x8C)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -118,6 +118,7 @@
 #define FFA_FNUM_MSG_SEND2			U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER		U(0x87)
 #define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
+#define FFA_FNUM_EL3_INTR_HANDLE		U(0x8C)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -163,6 +164,7 @@
 #define FFA_MEM_FRAG_TX	FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_TX)
 #define FFA_SPM_ID_GET		FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
 #define FFA_NORMAL_WORLD_RESUME	FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
+#define FFA_EL3_INTR_HANDLE	FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
 
 /* FFA SMC64 FIDs */
 #define FFA_ERROR_SMC64		FFA_FID(SMC_64, FFA_FNUM_ERROR)
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index de7181c..55d778e 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -152,7 +152,7 @@
  * Increase this when a bug is fixed, or a feature is added without
  * breaking compatibility.
  */
-#define RMM_EL3_IFC_VERSION_MINOR	(U(1))
+#define RMM_EL3_IFC_VERSION_MINOR	(U(2))
 
 #define RMM_EL3_INTERFACE_VERSION				\
 	(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) |	\
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
index e586b8c..2ca12c9 100644
--- a/include/tools_share/cca_oid.h
+++ b/include/tools_share/cca_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,4 +25,7 @@
 /* Realm Monitor Manager (RMM) Hash */
 #define RMM_HASH_OID				"1.3.6.1.4.1.4128.2100.1106"
 
+/* CCAFirmwareNVCounter - Non-volatile counter extension */
+#define CCA_FW_NVCOUNTER_OID			"1.3.6.1.4.1.4128.2100.3"
+
 #endif /* CCA_OID_H */
diff --git a/include/tools_share/uuid.h b/include/tools_share/uuid.h
index 2ced3a3..3445f20 100644
--- a/include/tools_share/uuid.h
+++ b/include/tools_share/uuid.h
@@ -27,13 +27,15 @@
  */
 
 /*
- * Portions copyright (c) 2014-2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2014-2023, Arm Limited and Contributors.
  * All rights reserved.
  */
 
 #ifndef UUID_H
 #define UUID_H
 
+#include <stdint.h>
+
 /* Length of a node address (an IEEE 802 address). */
 #define	_UUID_NODE_LEN		6
 
diff --git a/lib/compiler-rt/builtins/assembly.h b/lib/compiler-rt/builtins/assembly.h
index 69a3d86..169d496 100644
--- a/lib/compiler-rt/builtins/assembly.h
+++ b/lib/compiler-rt/builtins/assembly.h
@@ -267,7 +267,7 @@
 #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target)                         \
   .globl SYMBOL_NAME(name) SEPARATOR                                           \
   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
-  DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR                       \
+  DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR                                    \
   .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR
 
 #if defined(__ARM_EABI__)
diff --git a/lib/compiler-rt/builtins/int_types.h b/lib/compiler-rt/builtins/int_types.h
index 7a72de4..e94d315 100644
--- a/lib/compiler-rt/builtins/int_types.h
+++ b/lib/compiler-rt/builtins/int_types.h
@@ -64,7 +64,7 @@
 } udwords;
 
 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) ||             \
-    defined(__riscv) || defined(_WIN64)
+    defined(__SIZEOF_INT128__) || defined(_WIN64)
 #define CRT_HAS_128BIT
 #endif
 
diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c
index fb31ef1..43e9835 100644
--- a/lib/coreboot/coreboot_table.c
+++ b/lib/coreboot/coreboot_table.c
@@ -46,6 +46,8 @@
 
 coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES];
 coreboot_serial_t coreboot_serial;
+uint64_t coreboot_table_addr;
+uint32_t coreboot_table_size;
 
 /*
  * The coreboot table is parsed before the MMU is enabled (i.e. with strongly
@@ -108,6 +110,12 @@
 	return CB_MEM_NONE;
 }
 
+void coreboot_get_table_location(uint64_t *address, uint32_t *size)
+{
+	*address = coreboot_table_addr;
+	*size = coreboot_table_size;
+}
+
 void coreboot_table_setup(void *base)
 {
 	cb_header_t *header = base;
@@ -118,6 +126,8 @@
 		ERROR("coreboot table signature corrupt!\n");
 		return;
 	}
+	coreboot_table_addr = (uint64_t) base;
+	coreboot_table_size = header->header_bytes + header->table_bytes;
 
 	ptr = base + header->header_bytes;
 	for (i = 0; i < header->table_entries; i++) {
diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S
index c262276..dfa159f 100644
--- a/lib/cpus/aarch32/cortex_a32.S
+++ b/lib/cpus/aarch32/cortex_a32.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -117,14 +117,7 @@
 	b	cortex_a32_disable_smp
 endfunc cortex_a32_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A32. Must follow AAPCS.
- */
-func cortex_a32_errata_report
-	bx	lr
-endfunc cortex_a32_errata_report
-#endif
+errata_report_shim cortex_a32
 
 declare_cpu_ops cortex_a32, CORTEX_A32_MIDR, \
 	cortex_a32_reset_func, \
diff --git a/lib/cpus/aarch32/cortex_a72.S b/lib/cpus/aarch32/cortex_a72.S
index 03914b2..77cf84d 100644
--- a/lib/cpus/aarch32/cortex_a72.S
+++ b/lib/cpus/aarch32/cortex_a72.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -87,11 +87,15 @@
 	b		cpu_rev_var_ls
 endfunc check_errata_859971
 
+add_erratum_entry cortex_a72, ERRATUM(859971), ERRATA_A72_859971
+
 func check_errata_cve_2017_5715
 	mov	r0, #ERRATA_MISSING
 	bx	lr
 endfunc check_errata_cve_2017_5715
 
+add_erratum_entry cortex_a72, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+
 func check_errata_cve_2018_3639
 #if WORKAROUND_CVE_2018_3639
 	mov	r0, #ERRATA_APPLIES
@@ -101,11 +105,15 @@
 	bx	lr
 endfunc check_errata_cve_2018_3639
 
+add_erratum_entry cortex_a72, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+
 func check_errata_cve_2022_23960
 	mov	r0, #ERRATA_MISSING
 	bx	lr
 endfunc check_errata_cve_2022_23960
 
+add_erratum_entry cortex_a72, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A72.
 	 * -------------------------------------------------
@@ -248,29 +256,7 @@
 	b	cortex_a72_disable_ext_debug
 endfunc cortex_a72_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A72. Must follow AAPCS.
- */
-func cortex_a72_errata_report
-	push	{r12, lr}
-
-	bl	cpu_get_rev_var
-	mov	r4, r0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A72_859971, cortex_a72, 859971
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a72, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a72, cve_2018_3639
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a72, cve_2022_23960
-
-	pop	{r12, lr}
-	bx	lr
-endfunc cortex_a72_errata_report
-#endif
+errata_report_shim cortex_a72
 
 declare_cpu_ops cortex_a72, CORTEX_A72_MIDR, \
 	cortex_a72_reset_func, \
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index e25ce2a..05bc5d9 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -9,6 +9,7 @@
 #include <assert_macros.S>
 #include <cpu_macros.S>
 #include <common/bl_common.h>
+#include <lib/cpus/cpu_ops.h>
 #include <lib/el3_runtime/cpu_data.h>
 
 #if defined(IMAGE_BL1) || defined(IMAGE_BL32) || \
@@ -204,62 +205,3 @@
 	movlt	r0, #ERRATA_NOT_APPLIES
 	bx	lr
 endfunc cpu_rev_var_hs
-
-#if REPORT_ERRATA
-/*
- * void print_errata_status(void);
- *
- * Function to print errata status for CPUs of its class. Must be called only:
- *
- *   - with MMU and data caches are enabled;
- *   - after cpu_ops have been initialized in per-CPU data.
- */
-	.globl print_errata_status
-func print_errata_status
-	/* r12 is pushed only for the sake of 8-byte stack alignment */
-	push	{r4, r5, r12, lr}
-#ifdef IMAGE_BL1
-	/*
-	 * BL1 doesn't have per-CPU data. So retrieve the CPU operations
-	 * directly.
-	 */
-	bl	get_cpu_ops_ptr
-	ldr	r0, [r0, #CPU_ERRATA_FUNC]
-	cmp	r0, #0
-	blxne	r0
-#else
-	/*
-	 * Retrieve pointer to cpu_ops, and further, the errata printing
-	 * function. If it's non-NULL, jump to the function in turn.
-	 */
-	bl	_cpu_data
-#if ENABLE_ASSERTIONS
-	cmp	r0, #0
-	ASM_ASSERT(ne)
-#endif
-	ldr	r1, [r0, #CPU_DATA_CPU_OPS_PTR]
-#if ENABLE_ASSERTIONS
-	cmp	r1, #0
-	ASM_ASSERT(ne)
-#endif
-	ldr	r0, [r1, #CPU_ERRATA_FUNC]
-	cmp	r0, #0
-	beq	1f
-
-	mov	r4, r0
-
-	/*
-	 * Load pointers to errata lock and printed flag. Call
-	 * errata_needs_reporting to check whether this CPU needs to report
-	 * errata status pertaining to its class.
-	 */
-	ldr	r0, [r1, #CPU_ERRATA_LOCK]
-	ldr	r1, [r1, #CPU_ERRATA_PRINTED]
-	bl	errata_needs_reporting
-	cmp	r0, #0
-	blxne	r4
-1:
-#endif
-	pop	{r4, r5, r12, pc}
-endfunc print_errata_status
-#endif
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index 886e1f3..e10ebb0 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -382,7 +382,11 @@
 	bl	check_errata_2684597
 	cbz	x0, 2f
 
-	tsb	csync
+	/*
+	 * Many assemblers do not yet understand the "tsb csync" mnemonic,
+	 * so use the equivalent hint instruction.
+	 */
+	hint	#18			/* tsb csync */
 2:
 	ret	x17
 endfunc errata_cortex_a510_2684597_wa
diff --git a/lib/cpus/aarch64/cortex_a520.S b/lib/cpus/aarch64/cortex_a520.S
new file mode 100644
index 0000000..5bbe862
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a520.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a520.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex A520 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex A520 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a520_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A520_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A520_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_A520_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a520_core_pwr_dwn
+
+	/*
+	 * Errata printing function for Cortex A520. Must follow AAPCS.
+	 */
+#if REPORT_ERRATA
+func cortex_a520_errata_report
+	ret
+endfunc cortex_a520_errata_report
+#endif
+
+func cortex_a520_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_a520_reset_func
+
+	/* ---------------------------------------------
+	 * This function provides Cortex A520 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a520_regs, "aS"
+cortex_a520_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a520_cpu_reg_dump
+	adr	x6, cortex_a520_regs
+	mrs	x8, CORTEX_A520_CPUECTLR_EL1
+	ret
+endfunc cortex_a520_cpu_reg_dump
+
+declare_cpu_ops cortex_a520, CORTEX_A520_MIDR, \
+	cortex_a520_reset_func, \
+	cortex_a520_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index df11d86..ecaf422 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -9,8 +9,8 @@
 #include <common/debug.h>
 #include <cortex_a53.h>
 #include <cpu_macros.S>
-#include <lib/cpus/errata_report.h>
 #include <plat_macros.S>
+#include <lib/cpus/errata.h>
 
 #if A53_DISABLE_NON_TEMPORAL_HINT
 #undef ERRATA_A53_836870
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index 7603210..12d969f 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,23 +7,23 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <cortex_makalu.h>
+#include <cortex_a715.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
 #include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Makalu must be compiled with HW_ASSISTED_COHERENCY enabled"
+#error "Cortex-A715 must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
 /* 64-bit only core */
 #if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Makalu supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#error "Cortex-A715 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
 #if WORKAROUND_CVE_2022_23960
-	wa_cve_2022_23960_bhb_vector_table CORTEX_MAKALU_BHB_LOOP_COUNT, cortex_makalu
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A715_BHB_LOOP_COUNT, cortex_a715
 #endif /* WORKAROUND_CVE_2022_23960 */
 
 func check_errata_cve_2022_23960
@@ -35,44 +35,44 @@
 	ret
 endfunc check_errata_cve_2022_23960
 
-func cortex_makalu_reset_func
+func cortex_a715_reset_func
 	/* Disable speculative loads */
 	msr	SSBS, xzr
 
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
-	 * The Cortex Makalu generic vectors are overridden to apply errata
+	 * The Cortex-A715 generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-        adr	x0, wa_cve_vbar_cortex_makalu
+        adr	x0, wa_cve_vbar_cortex_a715
         msr	vbar_el3, x0
 #endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 
 	isb
 	ret
-endfunc cortex_makalu_reset_func
+endfunc cortex_a715_reset_func
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
-func cortex_makalu_core_pwr_dwn
+func cortex_a715_core_pwr_dwn
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_MAKALU_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_MAKALU_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_MAKALU_CPUPWRCTLR_EL1, x0
+	mrs	x0, CORTEX_A715_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A715_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_A715_CPUPWRCTLR_EL1, x0
 	isb
 	ret
-endfunc cortex_makalu_core_pwr_dwn
+endfunc cortex_a715_core_pwr_dwn
 
 #if REPORT_ERRATA
 /*
- * Errata printing function for Cortex Makalu. Must follow AAPCS.
+ * Errata printing function for Cortex-A715. Must follow AAPCS.
  */
-func cortex_makalu_errata_report
+func cortex_a715_errata_report
 	stp	x8, x30, [sp, #-16]!
 
 	bl	cpu_get_rev_var
@@ -82,15 +82,15 @@
 	 * Report all errata. The revision-variant information is passed to
 	 * checking functions of each errata.
 	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_makalu, cve_2022_23960
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a715, cve_2022_23960
 
 	ldp     x8, x30, [sp], #16
 	ret
-endfunc cortex_makalu_errata_report
+endfunc cortex_a715_errata_report
 #endif
 
 	/* ---------------------------------------------
-	 * This function provides Cortex Makalu-specific
+	 * This function provides Cortex-A715 specific
 	 * register information for crash reporting.
 	 * It needs to return with x6 pointing to
 	 * a list of register names in ascii and
@@ -98,16 +98,16 @@
 	 * reported.
 	 * ---------------------------------------------
 	 */
-.section .rodata.cortex_makalu_regs, "aS"
-cortex_makalu_regs:  /* The ascii list of register names to be reported */
+.section .rodata.cortex_a715_regs, "aS"
+cortex_a715_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
 
-func cortex_makalu_cpu_reg_dump
-	adr	x6, cortex_makalu_regs
-	mrs	x8, CORTEX_MAKALU_CPUECTLR_EL1
+func cortex_a715_cpu_reg_dump
+	adr	x6, cortex_a715_regs
+	mrs	x8, CORTEX_A715_CPUECTLR_EL1
 	ret
-endfunc cortex_makalu_cpu_reg_dump
+endfunc cortex_a715_cpu_reg_dump
 
-declare_cpu_ops cortex_makalu, CORTEX_MAKALU_MIDR, \
-	cortex_makalu_reset_func, \
-	cortex_makalu_core_pwr_dwn
+declare_cpu_ops cortex_a715, CORTEX_A715_MIDR, \
+	cortex_a715_reset_func, \
+	cortex_a715_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
new file mode 100644
index 0000000..529ab50
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a720.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex A720 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex A720 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+        wa_cve_2022_23960_bhb_vector_table CORTEX_A720_BHB_LOOP_COUNT, cortex_a720
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+func cortex_a720_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex A720 generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a720
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+	isb
+	ret
+endfunc cortex_a720_reset_func
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a720_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A720_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A720_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_A720_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a720_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A720. Must follow AAPCS.
+ */
+func cortex_a720_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a720, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc cortex_a720_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Cortex A720-specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a720_regs, "aS"
+cortex_a720_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a720_cpu_reg_dump
+	adr	x6, cortex_a720_regs
+	mrs	x8, CORTEX_A720_CPUECTLR_EL1
+	ret
+endfunc cortex_a720_cpu_reg_dump
+
+declare_cpu_ops cortex_a720, CORTEX_A720_MIDR, \
+	cortex_a720_reset_func, \
+	cortex_a720_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index d561be4..e22c828 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -121,7 +121,7 @@
 	bl	errata_dsu_936184_wa
 #endif
 
-#if ENABLE_AMU
+#if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
 	orr	x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 421509d..69d7ab0 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -483,7 +483,7 @@
 	bl	errata_a78_2779479_wa
 #endif
 
-#if ENABLE_AMU
+#if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
 	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 27adc38..d56f835 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -214,7 +214,7 @@
 	bl	errata_a78_ae_2395408_wa
 #endif
 
-#if ENABLE_AMU
+#if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
 	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 71f0725..fddd24f 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -18,6 +18,60 @@
 #endif
 
 /* --------------------------------------------------
+ * Errata Workaround for A78C Erratum 1827430.
+ * This applies to revision r0p0 of the Cortex A78C
+ * processor and is fixed in r0p1.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78c_1827430_wa
+	mov	x17, x30
+	bl	check_errata_1827430
+	cbz	x0, 1f
+
+	/* Disable allocation of splintered pages in the L2 TLB */
+	mrs	x1, CORTEX_A78C_CPUECTLR_EL1
+	orr	x1, x1, CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN
+	msr	CORTEX_A78C_CPUECTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_a78c_1827430_wa
+
+func check_errata_1827430
+	/* Applies to revision r0p0 only */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_1827430
+
+/* --------------------------------------------------
+ * Errata Workaround for A78C Erratum 1827440.
+ * This applies to revision r0p0 of the Cortex A78C
+ * processor and is fixed in r0p1.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78c_1827440_wa
+	mov	x17, x30
+	bl	check_errata_1827440
+	cbz	x0, 1f
+
+	/* Force Atomic Store to WB memory be done in L1 data cache */
+	mrs	x1, CORTEX_A78C_CPUACTLR2_EL1
+	orr	x1, x1, #BIT(2)
+	msr	CORTEX_A78C_CPUACTLR2_EL1, x1
+1:
+	ret	x17
+endfunc errata_a78c_1827440_wa
+
+func check_errata_1827440
+	/* Applies to revision r0p0 only */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_1827440
+
+/* --------------------------------------------------
  * Errata Workaround for Cortex A78C Erratum 2376749.
  * This applies to revision r0p1 and r0p2 of the A78C
  * and is currently open. It is a Cat B erratum.
@@ -225,6 +279,16 @@
 	bl	cpu_get_rev_var
 	mov	x18, x0
 
+#if ERRATA_A78C_1827430
+	mov	x0, x18
+	bl	errata_a78c_1827430_wa
+#endif
+
+#if ERRATA_A78C_1827440
+	mov	x0, x18
+	bl	errata_a78c_1827440_wa
+#endif
+
 #if ERRATA_A78C_2132064
 	mov	x0, x18
 	bl	errata_a78c_2132064_wa
@@ -299,6 +363,8 @@
 	 * Report all errata. The revision-variant information is passed to
 	 * checking functions of each errata.
 	 */
+	report_errata ERRATA_A78C_1827430, cortex_a78c, 1827430
+	report_errata ERRATA_A78C_1827440, cortex_a78c, 1827440
 	report_errata ERRATA_A78C_2132064, cortex_a78c, 2132064
 	report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
 	report_errata ERRATA_A78C_2376749, cortex_a78c, 2376749
diff --git a/lib/cpus/aarch64/cortex_blackhawk.S b/lib/cpus/aarch64/cortex_blackhawk.S
new file mode 100644
index 0000000..8dac4e9
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_blackhawk.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_blackhawk.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex blackhawk must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex blackhawk supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+func cortex_blackhawk_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_blackhawk_reset_func
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_blackhawk_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_blackhawk_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Blackhawk. Must follow AAPCS.
+ */
+func cortex_blackhawk_errata_report
+	ret
+endfunc cortex_blackhawk_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Cortex Blackhawk specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_blackhawk_regs, "aS"
+cortex_blackhawk_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_blackhawk_cpu_reg_dump
+	adr	x6, cortex_blackhawk_regs
+	mrs	x8, CORTEX_BLACKHAWK_CPUECTLR_EL1
+	ret
+endfunc cortex_blackhawk_cpu_reg_dump
+
+declare_cpu_ops cortex_blackhawk, CORTEX_BLACKHAWK_MIDR, \
+	cortex_blackhawk_reset_func, \
+	cortex_blackhawk_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_chaberton.S b/lib/cpus/aarch64/cortex_chaberton.S
new file mode 100644
index 0000000..2c47bd3
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_chaberton.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_chaberton.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex Chaberton must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex Chaberton supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+func cortex_chaberton_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_chaberton_reset_func
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_chaberton_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_CHABERTON_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_CHABERTON_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_chaberton_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Chaberton. Must follow AAPCS.
+ */
+func cortex_chaberton_errata_report
+	ret
+endfunc cortex_chaberton_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Cortex Chaberton specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_chaberton_regs, "aS"
+cortex_chaberton_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_chaberton_cpu_reg_dump
+	adr	x6, cortex_chaberton_regs
+	mrs	x8, CORTEX_CHABERTON_CPUECTLR_EL1
+	ret
+endfunc cortex_chaberton_cpu_reg_dump
+
+declare_cpu_ops cortex_chaberton, CORTEX_CHABERTON_MIDR, \
+	cortex_chaberton_reset_func, \
+	cortex_chaberton_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_hayes.S b/lib/cpus/aarch64/cortex_hayes.S
deleted file mode 100644
index 445a691..0000000
--- a/lib/cpus/aarch64/cortex_hayes.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_hayes.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Hayes must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Hayes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_hayes_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_HAYES_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_HAYES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_HAYES_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_hayes_core_pwr_dwn
-
-	/*
-	 * Errata printing function for Cortex Hayes. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_hayes_errata_report
-	ret
-endfunc cortex_hayes_errata_report
-#endif
-
-func cortex_hayes_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_hayes_reset_func
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Hayes specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_hayes_regs, "aS"
-cortex_hayes_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_hayes_cpu_reg_dump
-	adr	x6, cortex_hayes_regs
-	mrs	x8, CORTEX_HAYES_CPUECTLR_EL1
-	ret
-endfunc cortex_hayes_cpu_reg_dump
-
-declare_cpu_ops cortex_hayes, CORTEX_HAYES_MIDR, \
-	cortex_hayes_reset_func, \
-	cortex_hayes_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_hunter.S b/lib/cpus/aarch64/cortex_hunter.S
deleted file mode 100644
index 973637e..0000000
--- a/lib/cpus/aarch64/cortex_hunter.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_hunter.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-#include "wa_cve_2022_23960_bhb_vector.S"
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Hunter must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Hunter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-#if WORKAROUND_CVE_2022_23960
-        wa_cve_2022_23960_bhb_vector_table CORTEX_HUNTER_BHB_LOOP_COUNT, cortex_hunter
-#endif /* WORKAROUND_CVE_2022_23960 */
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func cortex_hunter_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex Hunter generic vectors are overridden to apply errata
-	 * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_cortex_hunter
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret
-endfunc cortex_hunter_reset_func
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_hunter_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_HUNTER_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_HUNTER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_HUNTER_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_hunter_core_pwr_dwn
-
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex Hunter. Must follow AAPCS.
- */
-func cortex_hunter_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_hunter, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_hunter_errata_report
-#endif
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Hunter-specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_hunter_regs, "aS"
-cortex_hunter_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_hunter_cpu_reg_dump
-	adr	x6, cortex_hunter_regs
-	mrs	x8, CORTEX_HUNTER_CPUECTLR_EL1
-	ret
-endfunc cortex_hunter_cpu_reg_dump
-
-declare_cpu_ops cortex_hunter, CORTEX_HUNTER_MIDR, \
-	cortex_hunter_reset_func, \
-	cortex_hunter_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_hunter_elp_arm.S b/lib/cpus/aarch64/cortex_hunter_elp_arm.S
deleted file mode 100644
index 5f86d4e..0000000
--- a/lib/cpus/aarch64/cortex_hunter_elp_arm.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_hunter_elp_arm.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-#include "wa_cve_2022_23960_bhb_vector.S"
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Hunter ELP must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Hunter ELP supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-#if WORKAROUND_CVE_2022_23960
-        wa_cve_2022_23960_bhb_vector_table CORTEX_HUNTER_ELP_ARM_BHB_LOOP_COUNT, cortex_hunter_elp_arm
-#endif /* WORKAROUND_CVE_2022_23960 */
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func cortex_hunter_elp_arm_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex Hunter ELP generic vectors are overridden to apply errata
-	 * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_cortex_hunter_elp_arm
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret
-endfunc cortex_hunter_elp_arm_reset_func
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_hunter_elp_arm_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_hunter_elp_arm_core_pwr_dwn
-
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex Hunter ELP. Must follow AAPCS.
- */
-func cortex_hunter_elp_arm_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_hunter_elp_arm, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_hunter_elp_arm_errata_report
-#endif
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Hunter ELP-specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_hunter_elp_arm_regs, "aS"
-cortex_hunter_elp_arm_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_hunter_elp_arm_cpu_reg_dump
-	adr	x6, cortex_hunter_elp_arm_regs
-	mrs	x8, CORTEX_HUNTER_ELP_ARM_CPUECTLR_EL1
-	ret
-endfunc cortex_hunter_elp_arm_cpu_reg_dump
-
-declare_cpu_ops cortex_hunter_elp_arm, CORTEX_HUNTER_ELP_ARM_MIDR, \
-	cortex_hunter_elp_arm_reset_func, \
-	cortex_hunter_elp_arm_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index 9a7f666..de65365 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -37,7 +37,7 @@
 	bl	check_errata_1821534
 	cbz	x0, 1f
 	mrs	x1, CORTEX_X1_ACTLR2_EL1
-	orr	x1, x1, BIT(2)
+	orr	x1, x1, #BIT(2)
 	msr	CORTEX_X1_ACTLR2_EL1, x1
 	isb
 1:
@@ -64,7 +64,7 @@
 	bl	check_errata_1688305
 	cbz	x0, 1f
 	mrs	x0, CORTEX_X1_ACTLR2_EL1
-	orr	x0, x0, BIT(1)
+	orr	x0, x0, #BIT(1)
 	msr	CORTEX_X1_ACTLR2_EL1, x0
 	isb
 
@@ -92,7 +92,7 @@
 	bl	check_errata_1827429
 	cbz	x0, 1f
 	mrs	x0, CORTEX_X1_CPUECTLR_EL1
-	orr	x0, x0, BIT(53)
+	orr	x0, x0, #BIT(53)
 	msr	CORTEX_X1_CPUECTLR_EL1, x0
 	isb
 
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
new file mode 100644
index 0000000..db87008
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_x4.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex X4 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex X4 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+        wa_cve_2022_23960_bhb_vector_table CORTEX_X4_BHB_LOOP_COUNT, cortex_x4
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+func cortex_x4_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex X4 generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_x4
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+	isb
+	ret
+endfunc cortex_x4_reset_func
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_x4_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_X4_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_X4_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_x4_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex X4. Must follow AAPCS.
+ */
+func cortex_x4_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_x4, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc cortex_x4_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Cortex X4-specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_x4_regs, "aS"
+cortex_x4_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_x4_cpu_reg_dump
+	adr	x6, cortex_x4_regs
+	mrs	x8, CORTEX_X4_CPUECTLR_EL1
+	ret
+endfunc cortex_x4_cpu_reg_dump
+
+declare_cpu_ops cortex_x4, CORTEX_X4_MIDR, \
+	cortex_x4_reset_func, \
+	cortex_x4_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index ee880f7..a4285ed 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -10,7 +10,8 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <cpu_macros.S>
-#include <lib/cpus/errata_report.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 #include <lib/el3_runtime/cpu_data.h>
 
  /* Reset fn is needed in BL at reset vector */
@@ -31,10 +32,6 @@
 
 	/* Get the matching cpu_ops pointer */
 	bl	get_cpu_ops_ptr
-#if ENABLE_ASSERTIONS
-	cmp	x0, #0
-	ASM_ASSERT(ne)
-#endif
 
 	/* Get the cpu_ops reset handler */
 	ldr	x2, [x0, #CPU_RESET_FUNC]
@@ -100,10 +97,6 @@
 	cbnz	x0, 1f
 	mov	x10, x30
 	bl	get_cpu_ops_ptr
-#if ENABLE_ASSERTIONS
-	cmp	x0, #0
-	ASM_ASSERT(ne)
-#endif
 	str	x0, [x6, #CPU_DATA_CPU_OPS_PTR]!
 	mov x30, x10
 1:
@@ -287,72 +280,6 @@
 	ret
 endfunc cpu_rev_var_range
 
-#if REPORT_ERRATA
-/*
- * void print_errata_status(void);
- *
- * Function to print errata status for CPUs of its class. Must be called only:
- *
- *   - with MMU and data caches are enabled;
- *   - after cpu_ops have been initialized in per-CPU data.
- */
-	.globl print_errata_status
-func print_errata_status
-#ifdef IMAGE_BL1
-	/*
-	 * BL1 doesn't have per-CPU data. So retrieve the CPU operations
-	 * directly.
-	 */
-	stp	xzr, x30, [sp, #-16]!
-	bl	get_cpu_ops_ptr
-	ldp	xzr, x30, [sp], #16
-	ldr	x1, [x0, #CPU_ERRATA_FUNC]
-	cbnz	x1, .Lprint
-#else
-	/*
-	 * Retrieve pointer to cpu_ops from per-CPU data, and further, the
-	 * errata printing function. If it's non-NULL, jump to the function in
-	 * turn.
-	 */
-	mrs	x0, tpidr_el3
-#if ENABLE_ASSERTIONS
-	cmp	x0, #0
-	ASM_ASSERT(ne)
-#endif
-	ldr	x1, [x0, #CPU_DATA_CPU_OPS_PTR]
-#if ENABLE_ASSERTIONS
-	cmp	x1, #0
-	ASM_ASSERT(ne)
-#endif
-	ldr	x0, [x1, #CPU_ERRATA_FUNC]
-	cbz	x0, .Lnoprint
-
-	/*
-	 * Printing errata status requires atomically testing the printed flag.
-	 */
-	stp	x19, x30, [sp, #-16]!
-	mov	x19, x0
-
-	/*
-	 * Load pointers to errata lock and printed flag. Call
-	 * errata_needs_reporting to check whether this CPU needs to report
-	 * errata status pertaining to its class.
-	 */
-	ldr	x0, [x1, #CPU_ERRATA_LOCK]
-	ldr	x1, [x1, #CPU_ERRATA_PRINTED]
-	bl	errata_needs_reporting
-	mov	x1, x19
-	ldp	x19, x30, [sp], #16
-	cbnz	x0, .Lprint
-#endif
-.Lnoprint:
-	ret
-.Lprint:
-	/* Jump to errata reporting function for this CPU */
-	br	x1
-endfunc print_errata_status
-#endif
-
 /*
  * int check_wa_cve_2017_5715(void);
  *
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index 419b6ea..a34b9a6 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <asm_macros.S>
 #include <dsu_def.h>
-#include <lib/cpus/errata_report.h>
+#include <lib/cpus/errata.h>
 
 	/* -----------------------------------------------------------------------
 	 * DSU erratum 798953 check function
@@ -44,11 +44,11 @@
 	/* --------------------------------------------------
 	 * Errata Workaround for DSU erratum #798953.
 	 *
-	 * Can clobber only: x0-x17
+	 * Can clobber only: x0-x8
 	 * --------------------------------------------------
 	 */
 func errata_dsu_798953_wa
-	mov	x17, x30
+	mov	x8, x30
 	bl	check_errata_dsu_798953
 	cbz	x0, 1f
 
@@ -58,7 +58,7 @@
 	msr	CLUSTERACTLR_EL1, x0
 	isb
 1:
-	ret	x17
+	ret	x8
 endfunc errata_dsu_798953_wa
 
 	/* -----------------------------------------------------------------------
@@ -72,7 +72,7 @@
 	 * This function is called from both assembly and C environment. So it
 	 * follows AAPCS.
 	 *
-	 * Clobbers: x0-x15
+	 * Clobbers: x0-x4
 	 * -----------------------------------------------------------------------
 	 */
 	.globl	check_errata_dsu_936184
@@ -83,7 +83,7 @@
 	 * Default behaviour respresents SCU is always present with DSU.
 	 * CPUs can override this definition if required.
 	 *
-	 * Can clobber only: x0-x14
+	 * Can clobber only: x0-x3
 	 * --------------------------------------------------------------------
 	 */
 func is_scu_present_in_dsu
@@ -92,7 +92,7 @@
 endfunc is_scu_present_in_dsu
 
 func check_errata_dsu_936184
-	mov	x15, x30
+	mov	x4, x30
 	bl	is_scu_present_in_dsu
 	cmp	x0, xzr
 	/* Default error status */
@@ -116,17 +116,17 @@
 	b.hs	1f
 	mov	x0, #ERRATA_APPLIES
 1:
-	ret	x15
+	ret	x4
 endfunc check_errata_dsu_936184
 
 	/* --------------------------------------------------
 	 * Errata Workaround for DSU erratum #936184.
 	 *
-	 * Can clobber only: x0-x17
+	 * Can clobber only: x0-x8
 	 * --------------------------------------------------
 	 */
 func errata_dsu_936184_wa
-	mov	x17, x30
+	mov	x8, x30
 	bl	check_errata_dsu_936184
 	cbz	x0, 1f
 
@@ -137,7 +137,7 @@
 	msr	CLUSTERACTLR_EL1, x0
 	isb
 1:
-	ret	x17
+	ret	x8
 endfunc errata_dsu_936184_wa
 
 	/* -----------------------------------------------------------------------
@@ -176,11 +176,11 @@
 	/* --------------------------------------------------
 	 * Errata Workaround for DSU erratum #2313941.
 	 *
-	 * Can clobber only: x0-x17
+	 * Can clobber only: x0-x8
 	 * --------------------------------------------------
 	 */
 func errata_dsu_2313941_wa
-	mov	x17, x30
+	mov	x8, x30
 	bl	check_errata_dsu_2313941
 	cbz	x0, 1f
 
@@ -190,6 +190,5 @@
 	msr	CLUSTERACTLR_EL1, x0
 	isb
 1:
-	ret	x17
+	ret	x8
 endfunc errata_dsu_2313941_wa
-
diff --git a/lib/cpus/aarch64/neoverse_hermes.S b/lib/cpus/aarch64/neoverse_hermes.S
new file mode 100644
index 0000000..cb90b71
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_hermes.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_hermes.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse Hermes must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse Hermes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start neoverse_hermes
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end neoverse_hermes
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func neoverse_hermes_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set NEOVERSE_HERMES_CPUPWRCTLR_EL1, NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc neoverse_hermes_core_pwr_dwn
+
+errata_report_shim neoverse_hermes
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse Hermes specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.neoverse_hermes_regs, "aS"
+neoverse_hermes_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_hermes_cpu_reg_dump
+	adr	x6, neoverse_hermes_regs
+	mrs	x8, NEOVERSE_HERMES_CPUECTLR_EL1
+	ret
+endfunc neoverse_hermes_cpu_reg_dump
+
+declare_cpu_ops neoverse_hermes, NEOVERSE_HERMES_MIDR, \
+	neoverse_hermes_reset_func, \
+	neoverse_hermes_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index ec62519..2cf94c7 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -585,7 +585,7 @@
 	bl	errata_n1_1946160_wa
 #endif
 
-#if ENABLE_AMU
+#if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
 	orr	x0, x0, #NEOVERSE_N1_ACTLR_AMEN_BIT
@@ -706,7 +706,6 @@
 	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 
-#if IMAGE_BL31 && RAS_EXTENSION
 	/*
 	 * Issue Error Synchronization Barrier to synchronize SErrors before
 	 * exiting EL3. We're running with EAs unmasked, so any synchronized
@@ -714,7 +713,6 @@
 	 * DISR_EL1 register.
 	 */
 	esb
-#endif
 	exception_return
 1:
 	ret
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index dbf5941..60d322f 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -545,7 +545,7 @@
 	bl	errata_n2_2388450_wa
 #endif
 
-#if ENABLE_AMU
+#if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, cptr_el3
 	orr	x0, x0, #TAM_BIT
diff --git a/lib/cpus/aarch64/qemu_max.S b/lib/cpus/aarch64/qemu_max.S
index 8948fda..00963bc 100644
--- a/lib/cpus/aarch64/qemu_max.S
+++ b/lib/cpus/aarch64/qemu_max.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,14 +47,7 @@
 	b	dcsw_op_all
 endfunc qemu_max_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for QEMU "max". Must follow AAPCS.
- */
-func qemu_max_errata_report
-	ret
-endfunc qemu_max_errata_report
-#endif
+errata_report_shim qemu_max
 
 	/* ---------------------------------------------
 	 * This function provides cpu specific
diff --git a/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S
index 584ab97..c770f54 100644
--- a/lib/cpus/aarch64/rainier.S
+++ b/lib/cpus/aarch64/rainier.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,78 +41,30 @@
 	ret
 endfunc rainier_disable_speculative_loads
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse N1 Errata #1868343.
-	 * This applies to revision <= r4p0 of Neoverse N1.
-	 * This workaround is the same as the workaround for
-	 * errata 1262606 and 1275112 but applies to a wider
-	 * revision range.
-	 * Rainier R0P0 is based on Neoverse N1 R4P0 so the
-	 * workaround checks for r0p0 version of Rainier CPU.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1 & x17
-	 * --------------------------------------------------
-	 */
-func errata_n1_1868343_wa
-	/*
-	 * Compare x0 against revision r4p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1868343
-	cbz	x0, 1f
-	mrs	x1, RAINIER_CPUACTLR_EL1
-	orr	x1, x1, RAINIER_CPUACTLR_EL1_BIT_13
-	msr	RAINIER_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_n1_1868343_wa
-
-func check_errata_1868343
-	/* Applies to r0p0 of Rainier CPU */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_1868343
+	/* Rainier R0P0 is based on Neoverse N1 R4P0. */
+workaround_reset_start rainier, ERRATUM(1868343), ERRATA_N1_1868343
+	sysreg_bit_set RAINIER_CPUACTLR_EL1, RAINIER_CPUACTLR_EL1_BIT_13
+workaround_reset_end rainier, ERRATUM(1868343)
 
-func rainier_reset_func
-	mov	x19, x30
+check_erratum_ls rainier, ERRATUM(1868343), CPU_REV(0, 0)
 
+cpu_reset_func_start rainier
 	bl	rainier_disable_speculative_loads
-
 	/* Forces all cacheable atomic instructions to be near */
-	mrs	x0, RAINIER_CPUACTLR2_EL1
-	orr	x0, x0, #RAINIER_CPUACTLR2_EL1_BIT_2
-	msr	RAINIER_CPUACTLR2_EL1, x0
-	isb
-
-	bl	cpu_get_rev_var
-	mov	x18, x0
+	sysreg_bit_set RAINIER_CPUACTLR2_EL1, RAINIER_CPUACTLR2_EL1_BIT_2
 
-#if ERRATA_N1_1868343
-	mov	x0, x18
-	bl	errata_n1_1868343_wa
-#endif
-
-#if ENABLE_AMU
+#if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	mrs	x0, actlr_el3
-	orr	x0, x0, #RAINIER_ACTLR_AMEN_BIT
-	msr	actlr_el3, x0
+	sysreg_bit_set actlr_el3, RAINIER_ACTLR_AMEN_BIT
 
 	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
-	mrs	x0, actlr_el2
-	orr	x0, x0, #RAINIER_ACTLR_AMEN_BIT
-	msr	actlr_el2, x0
+	sysreg_bit_set actlr_el2, RAINIER_ACTLR_AMEN_BIT
 
 	/* Enable group0 counters */
 	mov	x0, #RAINIER_AMU_GROUP0_MASK
 	msr	CPUAMCNTENSET_EL0, x0
 #endif
-
-	isb
-	ret	x19
-endfunc rainier_reset_func
+cpu_reset_func_end rainier
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -123,33 +75,12 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, RAINIER_CPUPWRCTLR_EL1
-	orr	x0, x0, #RAINIER_CORE_PWRDN_EN_MASK
-	msr	RAINIER_CPUPWRCTLR_EL1, x0
+	 sysreg_bit_set RAINIER_CPUPWRCTLR_EL1, RAINIER_CORE_PWRDN_EN_MASK
 	isb
 	ret
 endfunc rainier_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Rainier. Must follow AAPCS.
- */
-func rainier_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_N1_1868343, rainier, 1868343
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc rainier_errata_report
-#endif
+errata_report_shim rainier
 
 	/* ---------------------------------------------
 	 * This function provides Rainier specific
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 51b2175..e16c8e4 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -5,1462 +5,811 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include ${MAKE_HELPERS_DIRECTORY}$/build_macros.mk
+
 # Cortex A57 specific optimisation to skip L1 cache flush when
 # cluster is powered down.
-SKIP_A57_L1_FLUSH_PWR_DWN		?=0
+CPU_FLAG_LIST += SKIP_A57_L1_FLUSH_PWR_DWN
 
 # Flag to disable the cache non-temporal hint.
 # It is enabled by default.
 A53_DISABLE_NON_TEMPORAL_HINT		?=1
+CPU_FLAG_LIST += A53_DISABLE_NON_TEMPORAL_HINT
 
 # Flag to disable the cache non-temporal hint.
 # It is enabled by default.
 A57_DISABLE_NON_TEMPORAL_HINT		?=1
+CPU_FLAG_LIST += A57_DISABLE_NON_TEMPORAL_HINT
 
 # Flag to enable higher performance non-cacheable load forwarding.
 # It is disabled by default.
-A57_ENABLE_NONCACHEABLE_LOAD_FWD	?= 0
+CPU_FLAG_LIST += A57_ENABLE_NONCACHEABLE_LOAD_FWD
 
 WORKAROUND_CVE_2017_5715		?=1
+CPU_FLAG_LIST += WORKAROUND_CVE_2017_5715
 WORKAROUND_CVE_2018_3639		?=1
-DYNAMIC_WORKAROUND_CVE_2018_3639	?=0
+CPU_FLAG_LIST += WORKAROUND_CVE_2018_3639
+CPU_FLAG_LIST += DYNAMIC_WORKAROUND_CVE_2018_3639
 WORKAROUND_CVE_2022_23960		?=1
+CPU_FLAG_LIST += WORKAROUND_CVE_2022_23960
 
 # Flags to indicate internal or external Last level cache
 # By default internal
-NEOVERSE_Nx_EXTERNAL_LLC		?=0
-
-# Process A57_ENABLE_NONCACHEABLE_LOAD_FWD flag
-$(eval $(call assert_boolean,A57_ENABLE_NONCACHEABLE_LOAD_FWD))
-$(eval $(call add_define,A57_ENABLE_NONCACHEABLE_LOAD_FWD))
-
-# Process SKIP_A57_L1_FLUSH_PWR_DWN flag
-$(eval $(call assert_boolean,SKIP_A57_L1_FLUSH_PWR_DWN))
-$(eval $(call add_define,SKIP_A57_L1_FLUSH_PWR_DWN))
-
-# Process A53_DISABLE_NON_TEMPORAL_HINT flag
-$(eval $(call assert_boolean,A53_DISABLE_NON_TEMPORAL_HINT))
-$(eval $(call add_define,A53_DISABLE_NON_TEMPORAL_HINT))
-
-# Process A57_DISABLE_NON_TEMPORAL_HINT flag
-$(eval $(call assert_boolean,A57_DISABLE_NON_TEMPORAL_HINT))
-$(eval $(call add_define,A57_DISABLE_NON_TEMPORAL_HINT))
-
-# Process WORKAROUND_CVE_2017_5715 flag
-$(eval $(call assert_boolean,WORKAROUND_CVE_2017_5715))
-$(eval $(call add_define,WORKAROUND_CVE_2017_5715))
-
-# Process WORKAROUND_CVE_2018_3639 flag
-$(eval $(call assert_boolean,WORKAROUND_CVE_2018_3639))
-$(eval $(call add_define,WORKAROUND_CVE_2018_3639))
-
-$(eval $(call assert_boolean,DYNAMIC_WORKAROUND_CVE_2018_3639))
-$(eval $(call add_define,DYNAMIC_WORKAROUND_CVE_2018_3639))
-
-# Process WORKAROUND_CVE_2022_23960 flag
-$(eval $(call assert_boolean,WORKAROUND_CVE_2022_23960))
-$(eval $(call add_define,WORKAROUND_CVE_2022_23960))
-
-$(eval $(call assert_boolean,NEOVERSE_Nx_EXTERNAL_LLC))
-$(eval $(call add_define,NEOVERSE_Nx_EXTERNAL_LLC))
-
-ifneq (${DYNAMIC_WORKAROUND_CVE_2018_3639},0)
-	ifeq (${WORKAROUND_CVE_2018_3639},0)
-		$(error "Error: WORKAROUND_CVE_2018_3639 must be 1 if DYNAMIC_WORKAROUND_CVE_2018_3639 is 1")
-	endif
-endif
+CPU_FLAG_LIST += NEOVERSE_Nx_EXTERNAL_LLC
 
 # CPU Errata Build flags.
 # These should be enabled by the platform if the erratum workaround needs to be
 # applied.
 
 # Flag to apply erratum 794073 workaround when disabling mmu.
-ERRATA_A9_794073	?=0
+CPU_FLAG_LIST += ERRATA_A9_794073
 
 # Flag to apply erratum 816470 workaround during power down. This erratum
 # applies only to revision >= r3p0 of the Cortex A15 cpu.
-ERRATA_A15_816470	?=0
+CPU_FLAG_LIST += ERRATA_A15_816470
 
 # Flag to apply erratum 827671 workaround during reset. This erratum applies
 # only to revision >= r3p0 of the Cortex A15 cpu.
-ERRATA_A15_827671	?=0
+CPU_FLAG_LIST += ERRATA_A15_827671
 
 # Flag to apply erratum 852421 workaround during reset. This erratum applies
 # only to revision <= r1p2 of the Cortex A17 cpu.
-ERRATA_A17_852421	?=0
+CPU_FLAG_LIST += ERRATA_A17_852421
 
 # Flag to apply erratum 852423 workaround during reset. This erratum applies
 # only to revision <= r1p2 of the Cortex A17 cpu.
-ERRATA_A17_852423	?=0
+CPU_FLAG_LIST += ERRATA_A17_852423
 
 # Flag to apply erratum 855472 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A35 cpu.
-ERRATA_A35_855472	?=0
+CPU_FLAG_LIST += ERRATA_A35_855472
 
 # Flag to apply erratum 819472 workaround during reset. This erratum applies
 # only to revision <= r0p1 of the Cortex A53 cpu.
-ERRATA_A53_819472	?=0
+CPU_FLAG_LIST += ERRATA_A53_819472
 
 # Flag to apply erratum 824069 workaround during reset. This erratum applies
 # only to revision <= r0p2 of the Cortex A53 cpu.
-ERRATA_A53_824069	?=0
+CPU_FLAG_LIST += ERRATA_A53_824069
 
 # Flag to apply erratum 826319 workaround during reset. This erratum applies
 # only to revision <= r0p2 of the Cortex A53 cpu.
-ERRATA_A53_826319	?=0
+CPU_FLAG_LIST += ERRATA_A53_826319
 
 # Flag to apply erratum 827319 workaround during reset. This erratum applies
 # only to revision <= r0p2 of the Cortex A53 cpu.
-ERRATA_A53_827319	?=0
+CPU_FLAG_LIST += ERRATA_A53_827319
 
 # Flag to apply erratum 835769 workaround at compile and link time. This
 # erratum applies to revision <= r0p4 of the Cortex A53 cpu. Enabling this
 # workaround can lead the linker to create "*.stub" sections.
-ERRATA_A53_835769	?=0
+CPU_FLAG_LIST += ERRATA_A53_835769
 
 # Flag to apply erratum 836870 workaround during reset. This erratum applies
 # only to revision <= r0p3 of the Cortex A53 cpu. From r0p4 and onwards, this
 # erratum workaround is enabled by default in hardware.
-ERRATA_A53_836870	?=0
+CPU_FLAG_LIST += ERRATA_A53_836870
 
 # Flag to apply erratum 843419 workaround at link time.
 # This erratum applies to revision <= r0p4 of the Cortex A53 cpu. Enabling this
 # workaround could lead the linker to emit "*.stub" sections which are 4kB
 # aligned.
-ERRATA_A53_843419	?=0
+CPU_FLAG_LIST += ERRATA_A53_843419
 
 # Flag to apply errata 855873 during reset. This errata applies to all
 # revisions of the Cortex A53 CPU, but this firmware workaround only works
 # for revisions r0p3 and higher. Earlier revisions are taken care
 # of by the rich OS.
-ERRATA_A53_855873	?=0
+CPU_FLAG_LIST += ERRATA_A53_855873
 
 # Flag to apply erratum 1530924 workaround during reset. This erratum applies
 # to all revisions of Cortex A53 cpu.
-ERRATA_A53_1530924	?=0
+CPU_FLAG_LIST += ERRATA_A53_1530924
 
 # Flag to apply erratum 768277 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A55 cpu.
-ERRATA_A55_768277	?=0
+CPU_FLAG_LIST += ERRATA_A55_768277
 
 # Flag to apply erratum 778703 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A55 cpu.
-ERRATA_A55_778703	?=0
+CPU_FLAG_LIST += ERRATA_A55_778703
 
 # Flag to apply erratum 798797 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A55 cpu.
-ERRATA_A55_798797	?=0
+CPU_FLAG_LIST += ERRATA_A55_798797
 
 # Flag to apply erratum 846532 workaround during reset. This erratum applies
 # only to revision <= r0p1 of the Cortex A55 cpu.
-ERRATA_A55_846532	?=0
+CPU_FLAG_LIST += ERRATA_A55_846532
 
 # Flag to apply erratum 903758 workaround during reset. This erratum applies
 # only to revision <= r0p1 of the Cortex A55 cpu.
-ERRATA_A55_903758	?=0
+CPU_FLAG_LIST += ERRATA_A55_903758
 
 # Flag to apply erratum 1221012 workaround during reset. This erratum applies
 # only to revision <= r1p0 of the Cortex A55 cpu.
-ERRATA_A55_1221012	?=0
+CPU_FLAG_LIST += ERRATA_A55_1221012
 
 # Flag to apply erratum 1530923 workaround during reset. This erratum applies
 # to all revisions of Cortex A55 cpu.
-ERRATA_A55_1530923	?=0
+CPU_FLAG_LIST += ERRATA_A55_1530923
 
 # Flag to apply erratum 806969 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
-ERRATA_A57_806969	?=0
+CPU_FLAG_LIST += ERRATA_A57_806969
 
 # Flag to apply erratum 813419 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
-ERRATA_A57_813419	?=0
+CPU_FLAG_LIST += ERRATA_A57_813419
 
 # Flag to apply erratum 813420 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
-ERRATA_A57_813420	?=0
+CPU_FLAG_LIST += ERRATA_A57_813420
 
 # Flag to apply erratum 814670 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
-ERRATA_A57_814670	?=0
+CPU_FLAG_LIST += ERRATA_A57_814670
 
 # Flag to apply erratum 817169 workaround during power down. This erratum
 # applies only to revision <= r0p1 of the Cortex A57 cpu.
-ERRATA_A57_817169	?=0
+CPU_FLAG_LIST += ERRATA_A57_817169
 
 # Flag to apply erratum 826974 workaround during reset. This erratum applies
 # only to revision <= r1p1 of the Cortex A57 cpu.
-ERRATA_A57_826974	?=0
+CPU_FLAG_LIST += ERRATA_A57_826974
 
 # Flag to apply erratum 826977 workaround during reset. This erratum applies
 # only to revision <= r1p1 of the Cortex A57 cpu.
-ERRATA_A57_826977	?=0
+CPU_FLAG_LIST += ERRATA_A57_826977
 
 # Flag to apply erratum 828024 workaround during reset. This erratum applies
 # only to revision <= r1p1 of the Cortex A57 cpu.
-ERRATA_A57_828024	?=0
+CPU_FLAG_LIST += ERRATA_A57_828024
 
 # Flag to apply erratum 829520 workaround during reset. This erratum applies
 # only to revision <= r1p2 of the Cortex A57 cpu.
-ERRATA_A57_829520	?=0
+CPU_FLAG_LIST += ERRATA_A57_829520
 
 # Flag to apply erratum 833471 workaround during reset. This erratum applies
 # only to revision <= r1p2 of the Cortex A57 cpu.
-ERRATA_A57_833471	?=0
+CPU_FLAG_LIST += ERRATA_A57_833471
 
 # Flag to apply erratum 855972 workaround during reset. This erratum applies
 # only to revision <= r1p3 of the Cortex A57 cpu.
-ERRATA_A57_859972	?=0
+CPU_FLAG_LIST += ERRATA_A57_859972
 
 # Flag to apply erratum 1319537 workaround during reset. This erratum applies
 # to all revisions of Cortex A57 cpu.
-ERRATA_A57_1319537	?=0
+CPU_FLAG_LIST += ERRATA_A57_1319537
 
 # Flag to apply erratum 855971 workaround during reset. This erratum applies
 # only to revision <= r0p3 of the Cortex A72 cpu.
-ERRATA_A72_859971	?=0
+CPU_FLAG_LIST += ERRATA_A72_859971
 
 # Flag to apply erratum 1319367 workaround during reset. This erratum applies
 # to all revisions of Cortex A72 cpu.
-ERRATA_A72_1319367	?=0
+CPU_FLAG_LIST += ERRATA_A72_1319367
 
 # Flag to apply erratum 852427 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A73 cpu.
-ERRATA_A73_852427	?=0
+CPU_FLAG_LIST += ERRATA_A73_852427
 
 # Flag to apply erratum 855423 workaround during reset. This erratum applies
 # only to revision <= r0p1 of the Cortex A73 cpu.
-ERRATA_A73_855423	?=0
+CPU_FLAG_LIST += ERRATA_A73_855423
 
 # Flag to apply erratum 764081 workaround during reset. This erratum applies
 # only to revision <= r0p0 of the Cortex A75 cpu.
-ERRATA_A75_764081	?=0
+CPU_FLAG_LIST += ERRATA_A75_764081
 
 # Flag to apply erratum 790748 workaround during reset. This erratum applies
 # only to revision <= r0p0 of the Cortex A75 cpu.
-ERRATA_A75_790748	?=0
+CPU_FLAG_LIST += ERRATA_A75_790748
 
 # Flag to apply erratum 1073348 workaround during reset. This erratum applies
 # only to revision <= r1p0 of the Cortex A76 cpu.
-ERRATA_A76_1073348	?=0
+CPU_FLAG_LIST += ERRATA_A76_1073348
 
 # Flag to apply erratum 1130799 workaround during reset. This erratum applies
 # only to revision <= r2p0 of the Cortex A76 cpu.
-ERRATA_A76_1130799	?=0
+CPU_FLAG_LIST += ERRATA_A76_1130799
 
 # Flag to apply erratum 1220197 workaround during reset. This erratum applies
 # only to revision <= r2p0 of the Cortex A76 cpu.
-ERRATA_A76_1220197	?=0
+CPU_FLAG_LIST += ERRATA_A76_1220197
 
 # Flag to apply erratum 1257314 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Cortex A76 cpu.
-ERRATA_A76_1257314	?=0
+CPU_FLAG_LIST += ERRATA_A76_1257314
 
 # Flag to apply erratum 1262606 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Cortex A76 cpu.
-ERRATA_A76_1262606	?=0
+CPU_FLAG_LIST += ERRATA_A76_1262606
 
 # Flag to apply erratum 1262888 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Cortex A76 cpu.
-ERRATA_A76_1262888	?=0
+CPU_FLAG_LIST += ERRATA_A76_1262888
 
 # Flag to apply erratum 1275112 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Cortex A76 cpu.
-ERRATA_A76_1275112	?=0
+CPU_FLAG_LIST += ERRATA_A76_1275112
 
 # Flag to apply erratum 1286807 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Cortex A76 cpu.
-ERRATA_A76_1286807	?=0
+CPU_FLAG_LIST += ERRATA_A76_1286807
 
 # Flag to apply erratum 1791580 workaround during reset. This erratum applies
 # only to revision <= r4p0 of the Cortex A76 cpu.
-ERRATA_A76_1791580	?=0
+CPU_FLAG_LIST += ERRATA_A76_1791580
 
 # Flag to apply erratum 1165522 workaround during reset. This erratum applies
 # to all revisions of Cortex A76 cpu.
-ERRATA_A76_1165522	?=0
+CPU_FLAG_LIST += ERRATA_A76_1165522
 
 # Flag to apply erratum 1868343 workaround during reset. This erratum applies
 # only to revision <= r4p0 of the Cortex A76 cpu.
-ERRATA_A76_1868343	?=0
+CPU_FLAG_LIST += ERRATA_A76_1868343
 
 # Flag to apply erratum 1946160 workaround during reset. This erratum applies
 # only to revisions r3p0 - r4p1 of the Cortex A76 cpu.
-ERRATA_A76_1946160	?=0
+CPU_FLAG_LIST += ERRATA_A76_1946160
 
 # Flag to apply erratum 2743102 workaround during powerdown. This erratum
 # applies to all revisions <= r4p1 of the Cortex A76 cpu and is still open.
-ERRATA_A76_2743102	?=0
+CPU_FLAG_LIST += ERRATA_A76_2743102
 
 # Flag to apply erratum 1508412 workaround during reset. This erratum applies
 # only to revision <= r1p0 of the Cortex A77 cpu.
-ERRATA_A77_1508412	?=0
+CPU_FLAG_LIST += ERRATA_A77_1508412
 
 # Flag to apply erratum 1925769 workaround during reset. This erratum applies
 # only to revision <= r1p1 of the Cortex A77 cpu.
-ERRATA_A77_1925769	?=0
+CPU_FLAG_LIST += ERRATA_A77_1925769
 
 # Flag to apply erratum 1946167 workaround during reset. This erratum applies
 # only to revision <= r1p1 of the Cortex A77 cpu.
-ERRATA_A77_1946167	?=0
+CPU_FLAG_LIST += ERRATA_A77_1946167
 
 # Flag to apply erratum 1791578 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r1p1, it is still open.
-ERRATA_A77_1791578	?=0
+CPU_FLAG_LIST += ERRATA_A77_1791578
 
 # Flag to apply erratum 2356587 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r1p1, it is still open.
-ERRATA_A77_2356587	?=0
+CPU_FLAG_LIST += ERRATA_A77_2356587
 
 # Flag to apply erratum 1800714 workaround during reset. This erratum applies
 # to revisions <= r1p1 of the Cortex A77 cpu.
-ERRATA_A77_1800714	?=0
+CPU_FLAG_LIST += ERRATA_A77_1800714
 
 # Flag to apply erratum 2743100 workaround during power down. This erratum
 # applies to revisions r0p0, r1p0, and r1p1, it is still open.
-ERRATA_A77_2743100	?=0
+CPU_FLAG_LIST += ERRATA_A77_2743100
 
 # Flag to apply erratum 1688305 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the A78 cpu.
-ERRATA_A78_1688305	?=0
+CPU_FLAG_LIST += ERRATA_A78_1688305
 
 # Flag to apply erratum 1941498 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r1p1 of the A78 cpu.
-ERRATA_A78_1941498	?=0
+CPU_FLAG_LIST += ERRATA_A78_1941498
 
 # Flag to apply erratum 1951500 workaround during reset. This erratum applies
 # to revisions r1p0 and r1p1 of the A78 cpu. The issue is present in r0p0 as
 # well but there is no workaround for that revision.
-ERRATA_A78_1951500	?=0
+CPU_FLAG_LIST += ERRATA_A78_1951500
 
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the A78 cpu.
-ERRATA_A78_1821534	?=0
+CPU_FLAG_LIST += ERRATA_A78_1821534
 
 # Flag to apply erratum 1952683 workaround during reset. This erratum applies
 # to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
-ERRATA_A78_1952683	?=0
+CPU_FLAG_LIST += ERRATA_A78_1952683
 
 # Flag to apply erratum 2132060 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
-ERRATA_A78_2132060	?=0
+CPU_FLAG_LIST += ERRATA_A78_2132060
 
 # Flag to apply erratum 2242635 workaround during reset. This erratum applies
 # to revisions r1p0, r1p1, and r1p2 of the A78 cpu and is open. The issue is
 # present in r0p0 as well but there is no workaround for that revision.
-ERRATA_A78_2242635	?=0
+CPU_FLAG_LIST += ERRATA_A78_2242635
 
 # Flag to apply erratum 2376745 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
-ERRATA_A78_2376745	?=0
+CPU_FLAG_LIST += ERRATA_A78_2376745
 
 # Flag to apply erratum 2395406 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
-ERRATA_A78_2395406	?=0
+CPU_FLAG_LIST += ERRATA_A78_2395406
+
+# Flag to apply erratum 2712571 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu.
+# It is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_A78_2712571
 
 # Flag to apply erratum 2742426 workaround during reset. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
 # open.
-ERRATA_A78_2742426	?=0
+CPU_FLAG_LIST += ERRATA_A78_2742426
 
 # Flag to apply erratum 2772019 workaround during powerdown. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
 # open.
-ERRATA_A78_2772019	?=0
+CPU_FLAG_LIST += ERRATA_A78_2772019
 
 # Flag to apply erratum 2779479 workaround during reset. This erratum applies
 # to revision r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still open.
-ERRATA_A78_2779479	?=0
+CPU_FLAG_LIST += ERRATA_A78_2779479
 
 # Flag to apply erratum 1941500 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
-ERRATA_A78_AE_1941500	?=0
+CPU_FLAG_LIST += ERRATA_A78_AE_1941500
 
 # Flag to apply erratum 1951502 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
-ERRATA_A78_AE_1951502	?=0
+CPU_FLAG_LIST += ERRATA_A78_AE_1951502
 
 # Flag to apply erratum 2376748 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
-ERRATA_A78_AE_2376748	?=0
+CPU_FLAG_LIST += ERRATA_A78_AE_2376748
 
 # Flag to apply erratum 2395408 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
-ERRATA_A78_AE_2395408	?=0
+CPU_FLAG_LIST += ERRATA_A78_AE_2395408
+
+# Flag to apply erratum 1827430 workaround during reset. This erratum applies
+# to revision r0p0 of the A78C cpu. It is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_A78C_1827430
+
+# Flag to apply erratum 1827440 workaround during reset. This erratum applies
+# to revision r0p0 of the A78C cpu. It is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_A78C_1827440
+
+# Flag to apply erratum 2712574 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r0p1 and r0p2 of the A78 AE cpu.
+# It is still open.
+CPU_FLAG_LIST += ERRATA_A78_AE_2712574
 
 # Flag to apply erratum 2132064 workaround during reset. This erratum applies
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
-ERRATA_A78C_2132064	?=0
+CPU_FLAG_LIST += ERRATA_A78C_2132064
 
 # Flag to apply erratum 2242638 workaround during reset. This erratum applies
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
-ERRATA_A78C_2242638	?=0
+CPU_FLAG_LIST += ERRATA_A78C_2242638
 
 # Flag to apply erratum 2376749 workaround during reset. This erratum applies
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
-ERRATA_A78C_2376749 	?=0
+CPU_FLAG_LIST += ERRATA_A78C_2376749
 
 # Flag to apply erratum 2395411 workaround during reset. This erratum applies
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
-ERRATA_A78C_2395411 	?=0
+CPU_FLAG_LIST += ERRATA_A78C_2395411
+
+# Flag to apply erratum 2712575 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p1 and r0p2 of the A78C cpu.
+# It is still open.
+CPU_FLAG_LIST += ERRATA_A78C_2712575
 
 # Flag to apply erratum 2772121 workaround during powerdown. This erratum
 # applies to revisions r0p0, r0p1 and r0p2 of the A78C cpu. It is still open.
-ERRATA_A78C_2772121 	?=0
+CPU_FLAG_LIST += ERRATA_A78C_2772121
 
 # Flag to apply erratum 2779484 workaround during reset. This erratum
 # applies to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
-ERRATA_A78C_2779484 	?=0
+CPU_FLAG_LIST += ERRATA_A78C_2779484
 
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
-ERRATA_X1_1821534	?=0
+CPU_FLAG_LIST += ERRATA_X1_1821534
 
 # Flag to apply erratum 1688305 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
-ERRATA_X1_1688305	?=0
+CPU_FLAG_LIST += ERRATA_X1_1688305
 
 # Flag to apply erratum 1827429 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
-ERRATA_X1_1827429	?=0
+CPU_FLAG_LIST += ERRATA_X1_1827429
 
 # Flag to apply T32 CLREX workaround during reset. This erratum applies
 # only to r0p0 and r1p0 of the Neoverse N1 cpu.
-ERRATA_N1_1043202	?=0
+CPU_FLAG_LIST += ERRATA_N1_1043202
 
 # Flag to apply erratum 1073348 workaround during reset. This erratum applies
 # only to revision r0p0 and r1p0 of the Neoverse N1 cpu.
-ERRATA_N1_1073348	?=0
+CPU_FLAG_LIST += ERRATA_N1_1073348
 
 # Flag to apply erratum 1130799 workaround during reset. This erratum applies
 # only to revision <= r2p0 of the Neoverse N1 cpu.
-ERRATA_N1_1130799	?=0
+CPU_FLAG_LIST += ERRATA_N1_1130799
 
 # Flag to apply erratum 1165347 workaround during reset. This erratum applies
 # only to revision <= r2p0 of the Neoverse N1 cpu.
-ERRATA_N1_1165347	?=0
+CPU_FLAG_LIST += ERRATA_N1_1165347
 
 # Flag to apply erratum 1207823 workaround during reset. This erratum applies
 # only to revision <= r2p0 of the Neoverse N1 cpu.
-ERRATA_N1_1207823	?=0
+CPU_FLAG_LIST += ERRATA_N1_1207823
 
 # Flag to apply erratum 1220197 workaround during reset. This erratum applies
 # only to revision <= r2p0 of the Neoverse N1 cpu.
-ERRATA_N1_1220197	?=0
+CPU_FLAG_LIST += ERRATA_N1_1220197
 
 # Flag to apply erratum 1257314 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Neoverse N1 cpu.
-ERRATA_N1_1257314	?=0
+CPU_FLAG_LIST += ERRATA_N1_1257314
 
 # Flag to apply erratum 1262606 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Neoverse N1 cpu.
-ERRATA_N1_1262606	?=0
+CPU_FLAG_LIST += ERRATA_N1_1262606
 
 # Flag to apply erratum 1262888 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Neoverse N1 cpu.
-ERRATA_N1_1262888	?=0
+CPU_FLAG_LIST += ERRATA_N1_1262888
 
 # Flag to apply erratum 1275112 workaround during reset. This erratum applies
 # only to revision <= r3p0 of the Neoverse N1 cpu.
-ERRATA_N1_1275112	?=0
+CPU_FLAG_LIST += ERRATA_N1_1275112
 
 # Flag to apply erratum 1315703 workaround during reset. This erratum applies
 # to revisions before r3p1 of the Neoverse N1 cpu.
-ERRATA_N1_1315703	?=0
+CPU_FLAG_LIST += ERRATA_N1_1315703
 
 # Flag to apply erratum 1542419 workaround during reset. This erratum applies
 # to revisions r3p0 - r4p0 of the Neoverse N1 cpu.
-ERRATA_N1_1542419	?=0
+CPU_FLAG_LIST += ERRATA_N1_1542419
 
 # Flag to apply erratum 1868343 workaround during reset. This erratum applies
 # to revision <= r4p0 of the Neoverse N1 cpu.
-ERRATA_N1_1868343	?=0
+CPU_FLAG_LIST += ERRATA_N1_1868343
 
 # Flag to apply erratum 1946160 workaround during reset. This erratum applies
 # to revisions r3p0, r3p1, r4p0, and r4p1 of the Neoverse N1 cpu. The issue
 # exists in revisions r0p0, r1p0, and r2p0 as well but there is no workaround.
-ERRATA_N1_1946160	?=0
+CPU_FLAG_LIST += ERRATA_N1_1946160
 
 # Flag to apply erratum 2743102 workaround during powerdown. This erratum
 # applies to all revisions <= r4p1 of the Neoverse N1 cpu and is still open.
-ERRATA_N1_2743102	?=0
+CPU_FLAG_LIST += ERRATA_N1_2743102
 
 # Flag to apply erratum 1618635 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse V1 cpu and was fixed in the revision r1p0.
-ERRATA_V1_1618635	?=0
+CPU_FLAG_LIST += ERRATA_V1_1618635
 
 # Flag to apply erratum 1774420 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the Neoverse V1 core, and was fixed in r1p1.
-ERRATA_V1_1774420	?=0
+CPU_FLAG_LIST += ERRATA_V1_1774420
 
 # Flag to apply erratum 1791573 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the Neoverse V1 core, and was fixed in r1p1.
-ERRATA_V1_1791573	?=0
+CPU_FLAG_LIST += ERRATA_V1_1791573
 
 # Flag to apply erratum 1852267 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the Neoverse V1 core, and was fixed in r1p1.
-ERRATA_V1_1852267	?=0
+CPU_FLAG_LIST += ERRATA_V1_1852267
 
 # Flag to apply erratum 1925756 workaround during reset. This needs to be
 # enabled for r0p0, r1p0, and r1p1 of the Neoverse V1 core, it is still open.
-ERRATA_V1_1925756	?=0
+CPU_FLAG_LIST += ERRATA_V1_1925756
 
 # Flag to apply erratum 1940577 workaround during reset. This erratum applies
 # to revisions r1p0 and r1p1 of the Neoverse V1 cpu.
-ERRATA_V1_1940577	?=0
+CPU_FLAG_LIST += ERRATA_V1_1940577
 
 # Flag to apply erratum 1966096 workaround during reset. This erratum applies
 # to revisions r1p0 and r1p1 of the Neoverse V1 CPU and is open. This issue
 # exists in r0p0 as well but there is no workaround for that revision.
-ERRATA_V1_1966096	?=0
+CPU_FLAG_LIST += ERRATA_V1_1966096
 
 # Flag to apply erratum 2139242 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
-ERRATA_V1_2139242	?=0
+CPU_FLAG_LIST += ERRATA_V1_2139242
 
 # Flag to apply erratum 2108267 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
-ERRATA_V1_2108267	?=0
+CPU_FLAG_LIST += ERRATA_V1_2108267
 
 # Flag to apply erratum 2216392 workaround during reset. This erratum applies
 # to revisions r1p0 and r1p1 of the Neoverse V1 cpu and is still open. This
 # issue exists in r0p0 as well but there is no workaround for that revision.
-ERRATA_V1_2216392	?=0
+CPU_FLAG_LIST += ERRATA_V1_2216392
 
 # Flag to apply erratum 2294912 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
-ERRATA_V1_2294912	?=0
+CPU_FLAG_LIST += ERRATA_V1_2294912
 
 # Flag to apply erratum 2372203 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
-ERRATA_V1_2372203	?=0
+CPU_FLAG_LIST += ERRATA_V1_2372203
+
+# Flag to apply erratum 2701953 workaround to non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r1p0, r1p1 of the Neoverse V1 cpu,
+# it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_V1_2701953
 
 # Flag to apply erratum 2743093 workaround during powerdown. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
 # still open.
-ERRATA_V1_2743093	?=0
+CPU_FLAG_LIST += ERRATA_V1_2743093
 
 # Flag to apply erratum 2743233 workaround during powerdown. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2 of the Neoverse V1 cpu and is
 # still open.
-ERRATA_V1_2743233	?=0
+CPU_FLAG_LIST += ERRATA_V1_2743233
 
 # Flag to apply erratum 2779461 workaround during powerdown. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
 # still open.
-ERRATA_V1_2779461       ?=0
+CPU_FLAG_LIST += ERRATA_V1_2779461
 
 # Flag to apply erratum 1987031 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
-ERRATA_A710_1987031	?=0
+CPU_FLAG_LIST += ERRATA_A710_1987031
 
 # Flag to apply erratum 2081180 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
-ERRATA_A710_2081180	?=0
+CPU_FLAG_LIST += ERRATA_A710_2081180
 
 # Flag to apply erratum 2083908 workaround during reset. This erratum applies
 # to revision r2p0 of the Cortex-A710 cpu and is still open.
-ERRATA_A710_2083908	?=0
+CPU_FLAG_LIST += ERRATA_A710_2083908
 
 # Flag to apply erratum 2058056 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
-ERRATA_A710_2058056	?=0
+CPU_FLAG_LIST += ERRATA_A710_2058056
 
 # Flag to apply erratum 2055002 workaround during reset. This erratum applies
 # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open.
-ERRATA_A710_2055002	?=0
+CPU_FLAG_LIST += ERRATA_A710_2055002
 
 # Flag to apply erratum 2017096 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
-ERRATA_A710_2017096	?=0
+CPU_FLAG_LIST += ERRATA_A710_2017096
 
 # Flag to apply erratum 2267065 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
-ERRATA_A710_2267065	?=0
+CPU_FLAG_LIST += ERRATA_A710_2267065
 
 # Flag to apply erratum 2136059 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
-ERRATA_A710_2136059	?=0
+CPU_FLAG_LIST += ERRATA_A710_2136059
 
 # Flag to apply erratum 2147715 workaround during reset. This erratum applies
 # to revision r2p0 of the Cortex-A710 CPU and is fixed in revision r2p1.
-ERRATA_A710_2147715	?=0
+CPU_FLAG_LIST += ERRATA_A710_2147715
 
 # Flag to apply erratum 2216384 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
-ERRATA_A710_2216384	?=0
+CPU_FLAG_LIST += ERRATA_A710_2216384
 
 # Flag to apply erratum 2282622 workaround during reset. This erratum applies
 # to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
 # open.
-ERRATA_A710_2282622	?=0
+CPU_FLAG_LIST += ERRATA_A710_2282622
 
 # Flag to apply erratum 2291219 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
-ERRATA_A710_2291219	?=0
+CPU_FLAG_LIST += ERRATA_A710_2291219
 
 # Flag to apply erratum 2008768 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
-ERRATA_A710_2008768	?=0
+CPU_FLAG_LIST += ERRATA_A710_2008768
 
 # Flag to apply erratum 2371105 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
-ERRATA_A710_2371105	?=0
+CPU_FLAG_LIST += ERRATA_A710_2371105
+
+# Flag to apply erratum 2701952 workaround for non-arm interconnect ip. This
+# erratum applies to revision r0p0, r1p0, r2p0, r2p1 of the Cortex-A710 cpu
+# and is still open.
+CPU_FLAG_LIST += ERRATA_A710_2701952
 
 # Flag to apply erratum 2768515 workaround during power down. This erratum
 # applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is
 # still open.
-ERRATA_A710_2768515	?=0
+CPU_FLAG_LIST += ERRATA_A710_2768515
 
 # Flag to apply erratum 2002655 workaround during reset. This erratum applies
 # to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
-ERRATA_N2_2002655	?=0
+CPU_FLAG_LIST += ERRATA_N2_2002655
 
 # Flag to apply erratum 2067956 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2067956	?=0
+CPU_FLAG_LIST += ERRATA_N2_2067956
 
 # Flag to apply erratum 2025414 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2025414	?=0
+CPU_FLAG_LIST += ERRATA_N2_2025414
 
 # Flag to apply erratum 2189731 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2189731	?=0
+CPU_FLAG_LIST += ERRATA_N2_2189731
 
 # Flag to apply erratum 2138956 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2138956	?=0
+CPU_FLAG_LIST += ERRATA_N2_2138956
 
 # Flag to apply erratum 2138953 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2138953	?=0
+CPU_FLAG_LIST += ERRATA_N2_2138953
 
 # Flag to apply erratum 2242415 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2242415	?=0
+CPU_FLAG_LIST += ERRATA_N2_2242415
 
 # Flag to apply erratum 2138958 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2138958	?=0
+CPU_FLAG_LIST += ERRATA_N2_2138958
 
 # Flag to apply erratum 2242400 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2242400	?=0
+CPU_FLAG_LIST += ERRATA_N2_2242400
 
 # Flag to apply erratum 2280757 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
-ERRATA_N2_2280757	?=0
+CPU_FLAG_LIST += ERRATA_N2_2280757
 
 # Flag to apply erraturm 2326639 workaroud during powerdown. This erratum
 # applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
-ERRATA_N2_2326639	?=0
+CPU_FLAG_LIST += ERRATA_N2_2326639
 
 # Flag to apply erratum 2376738 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
-ERRATA_N2_2376738	?=0
+CPU_FLAG_LIST += ERRATA_N2_2376738
 
 # Flag to apply erratum 2388450 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
-ERRATA_N2_2388450	?=0
+CPU_FLAG_LIST += ERRATA_N2_2388450
+
+# Flag to apply erratum 2728475 workaround for non-arm interconnect ip. This
+# erratum applies to r0p0, r0p1, r0p2 of the Neoverse N2 cpu, it is fixed in
+# r0p3.
+CPU_FLAG_LIST += ERRATA_N2_2728475
 
 # Flag to apply erratum 2743089 workaround during during powerdown. This erratum
 # applies to all revisions <= r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
-ERRATA_N2_2743089	?=0
+CPU_FLAG_LIST += ERRATA_N2_2743089
 
 # Flag to apply erratum 2002765 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
-ERRATA_X2_2002765	?=0
+CPU_FLAG_LIST += ERRATA_X2_2002765
 
 # Flag to apply erratum 2058056 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
-ERRATA_X2_2058056	?=0
+CPU_FLAG_LIST += ERRATA_X2_2058056
 
 # Flag to apply erratum 2083908 workaround during reset. This erratum applies
 # to revision r2p0 of the Cortex-X2 cpu and is still open.
-ERRATA_X2_2083908	?=0
+CPU_FLAG_LIST += ERRATA_X2_2083908
 
 # Flag to apply erratum 2017096 workaround during reset. This erratum applies
 # only to revisions r0p0, r1p0 and r2p0 of the Cortex-X2 cpu, it is fixed in
 # r2p1.
-ERRATA_X2_2017096	?=0
+CPU_FLAG_LIST += ERRATA_X2_2017096
 
 # Flag to apply erratum 2081180 workaround during reset. This erratum applies
 # only to revisions r0p0, r1p0 and r2p0 of the Cortex-X2 cpu, it is fixed in
 # r2p1.
-ERRATA_X2_2081180	?=0
+CPU_FLAG_LIST += ERRATA_X2_2081180
 
 # Flag to apply erratum 2216384 workaround during reset. This erratum applies
 # only to revisions r0p0, r1p0 and r2p0 of the Cortex-X2 cpu, it is fixed in
 # r2p1.
-ERRATA_X2_2216384	?=0
+CPU_FLAG_LIST += ERRATA_X2_2216384
 
 # Flag to apply erratum 2147715 workaround during reset. This erratum applies
 # only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
-ERRATA_X2_2147715	?=0
+CPU_FLAG_LIST += ERRATA_X2_2147715
 
 # Flag to apply erratum 2282622 workaround during reset. This erratum applies
 # to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still
 # open.
-ERRATA_X2_2282622	?=0
+CPU_FLAG_LIST += ERRATA_X2_2282622
 
 # Flag to apply erratum 2371105 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
-ERRATA_X2_2371105	?=0
+CPU_FLAG_LIST += ERRATA_X2_2371105
+
+# Flag to apply erratum 2701952 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r1p0, r2p0, r2p1 of the Cortex-x2 cpu
+# and is still open.
+CPU_FLAG_LIST += ERRATA_X2_2701952
 
 # Flag to apply erratum 2768515 workaround during power down. This erratum
 # applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is
 # still open.
-ERRATA_X2_2768515	?=0
+CPU_FLAG_LIST += ERRATA_X2_2768515
 
 # Flag to apply erratum 2313909 workaround on powerdown. This erratum applies
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
-ERRATA_X3_2313909	?=0
+CPU_FLAG_LIST += ERRATA_X3_2313909
 
 # Flag to apply erratum 2615812 workaround on powerdown. This erratum applies
 # to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is still open.
-ERRATA_X3_2615812	?=0
+CPU_FLAG_LIST += ERRATA_X3_2615812
 
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
-ERRATA_A510_1922240	?=0
+CPU_FLAG_LIST += ERRATA_A510_1922240
 
 # Flag to apply erratum 2288014 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3 and r1p0 of the Cortex-A510 cpu and is
 # fixed in r1p1.
-ERRATA_A510_2288014	?=0
+CPU_FLAG_LIST += ERRATA_A510_2288014
 
 # Flag to apply erratum 2042739 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1 and r0p2 of the Cortex-A510 cpu and is fixed in r0p3.
-ERRATA_A510_2042739	?=0
+CPU_FLAG_LIST += ERRATA_A510_2042739
 
 # Flag to apply erratum 2041909 workaround during reset. This erratum applies
 # to revision r0p2 of the Cortex-A510 cpu and is fixed in r0p3. The issue is
 # present in r0p0 and r0p1 but there is no workaround for those revisions.
-ERRATA_A510_2041909	?=0
+CPU_FLAG_LIST += ERRATA_A510_2041909
 
 # Flag to apply erratum 2250311 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3 and r1p0, and is fixed in r1p1.
-ERRATA_A510_2250311	?=0
+CPU_FLAG_LIST += ERRATA_A510_2250311
 
 # Flag to apply erratum 2218950 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3 and r1p0, and is fixed in r1p1.
-ERRATA_A510_2218950	?=0
+CPU_FLAG_LIST += ERRATA_A510_2218950
 
 # Flag to apply erratum 2172148 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3 and r1p0, and is fixed in r1p1.
-ERRATA_A510_2172148	?=0
+CPU_FLAG_LIST += ERRATA_A510_2172148
 
 # Flag to apply erratum 2347730 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3, r1p0 and r1p1 of the Cortex-A510 CPU,
 # and is fixed in r1p2.
-ERRATA_A510_2347730	?=0
+CPU_FLAG_LIST += ERRATA_A510_2347730
 
 # Flag to apply erratum 2371937 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
-ERRATA_A510_2371937	?=0
+CPU_FLAG_LIST += ERRATA_A510_2371937
 
 # Flag to apply erratum 2666669 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
-ERRATA_A510_2666669	?=0
+CPU_FLAG_LIST += ERRATA_A510_2666669
 
 # Flag to apply erratum 2684597 workaround during powerdown. This erratum
 # applies to revision r0p0, r0p1, r0p2, r0p3, r1p0, r1p1 and r1p2 of the
 # Cortex-A510 cpu and is fixed in r1p3.
-ERRATA_A510_2684597	?=0
+CPU_FLAG_LIST += ERRATA_A510_2684597
+
+# Flag to apply erratum 2719103 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, rop1. Fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2719103
+
+# Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
+# This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_A715_2701951
 
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
-ERRATA_DSU_798953	?=0
+CPU_FLAG_LIST += ERRATA_DSU_798953
 
 # Flag to apply DSU erratum 936184. This erratum applies to DSUs containing
 # the ACP interface and revision < r2p0. Applying the workaround results in
 # higher DSU power consumption on idle.
-ERRATA_DSU_936184	?=0
+CPU_FLAG_LIST += ERRATA_DSU_936184
 
 # Flag to apply DSU erratum 2313941. This erratum applies to DSUs revisions
 # r0p0, r1p0, r2p0, r2p1, r3p0, r3p1 and is still open. Applying the workaround
 # results in higher DSU power consumption on idle.
-ERRATA_DSU_2313941	?=0
-
-# Process ERRATA_A9_794073 flag
-$(eval $(call assert_boolean,ERRATA_A9_794073))
-$(eval $(call add_define,ERRATA_A9_794073))
-
-# Process ERRATA_A15_816470 flag
-$(eval $(call assert_boolean,ERRATA_A15_816470))
-$(eval $(call add_define,ERRATA_A15_816470))
-
-# Process ERRATA_A15_827671 flag
-$(eval $(call assert_boolean,ERRATA_A15_827671))
-$(eval $(call add_define,ERRATA_A15_827671))
-
-# Process ERRATA_A17_852421 flag
-$(eval $(call assert_boolean,ERRATA_A17_852421))
-$(eval $(call add_define,ERRATA_A17_852421))
-
-# Process ERRATA_A17_852423 flag
-$(eval $(call assert_boolean,ERRATA_A17_852423))
-$(eval $(call add_define,ERRATA_A17_852423))
-
-# Process ERRATA_A35_855472 flag
-$(eval $(call assert_boolean,ERRATA_A35_855472))
-$(eval $(call add_define,ERRATA_A35_855472))
-
-# Process ERRATA_A53_819472 flag
-$(eval $(call assert_boolean,ERRATA_A53_819472))
-$(eval $(call add_define,ERRATA_A53_819472))
-
-# Process ERRATA_A53_824069 flag
-$(eval $(call assert_boolean,ERRATA_A53_824069))
-$(eval $(call add_define,ERRATA_A53_824069))
-
-# Process ERRATA_A53_826319 flag
-$(eval $(call assert_boolean,ERRATA_A53_826319))
-$(eval $(call add_define,ERRATA_A53_826319))
-
-# Process ERRATA_A53_827319 flag
-$(eval $(call assert_boolean,ERRATA_A53_827319))
-$(eval $(call add_define,ERRATA_A53_827319))
-
-# Process ERRATA_A53_835769 flag
-$(eval $(call assert_boolean,ERRATA_A53_835769))
-$(eval $(call add_define,ERRATA_A53_835769))
-
-# Process ERRATA_A53_836870 flag
-$(eval $(call assert_boolean,ERRATA_A53_836870))
-$(eval $(call add_define,ERRATA_A53_836870))
-
-# Process ERRATA_A53_843419 flag
-$(eval $(call assert_boolean,ERRATA_A53_843419))
-$(eval $(call add_define,ERRATA_A53_843419))
-
-# Process ERRATA_A53_855873 flag
-$(eval $(call assert_boolean,ERRATA_A53_855873))
-$(eval $(call add_define,ERRATA_A53_855873))
-
-# Process ERRATA_A53_1530924 flag
-$(eval $(call assert_boolean,ERRATA_A53_1530924))
-$(eval $(call add_define,ERRATA_A53_1530924))
-
-# Process ERRATA_A55_768277 flag
-$(eval $(call assert_boolean,ERRATA_A55_768277))
-$(eval $(call add_define,ERRATA_A55_768277))
-
-# Process ERRATA_A55_778703 flag
-$(eval $(call assert_boolean,ERRATA_A55_778703))
-$(eval $(call add_define,ERRATA_A55_778703))
-
-# Process ERRATA_A55_798797 flag
-$(eval $(call assert_boolean,ERRATA_A55_798797))
-$(eval $(call add_define,ERRATA_A55_798797))
-
-# Process ERRATA_A55_846532 flag
-$(eval $(call assert_boolean,ERRATA_A55_846532))
-$(eval $(call add_define,ERRATA_A55_846532))
-
-# Process ERRATA_A55_903758 flag
-$(eval $(call assert_boolean,ERRATA_A55_903758))
-$(eval $(call add_define,ERRATA_A55_903758))
-
-# Process ERRATA_A55_1221012 flag
-$(eval $(call assert_boolean,ERRATA_A55_1221012))
-$(eval $(call add_define,ERRATA_A55_1221012))
-
-# Process ERRATA_A55_1530923 flag
-$(eval $(call assert_boolean,ERRATA_A55_1530923))
-$(eval $(call add_define,ERRATA_A55_1530923))
-
-# Process ERRATA_A57_806969 flag
-$(eval $(call assert_boolean,ERRATA_A57_806969))
-$(eval $(call add_define,ERRATA_A57_806969))
-
-# Process ERRATA_A57_813419 flag
-$(eval $(call assert_boolean,ERRATA_A57_813419))
-$(eval $(call add_define,ERRATA_A57_813419))
-
-# Process ERRATA_A57_813420 flag
-$(eval $(call assert_boolean,ERRATA_A57_813420))
-$(eval $(call add_define,ERRATA_A57_813420))
-
-# Process ERRATA_A57_814670 flag
-$(eval $(call assert_boolean,ERRATA_A57_814670))
-$(eval $(call add_define,ERRATA_A57_814670))
-
-# Process ERRATA_A57_817169 flag
-$(eval $(call assert_boolean,ERRATA_A57_817169))
-$(eval $(call add_define,ERRATA_A57_817169))
-
-# Process ERRATA_A57_826974 flag
-$(eval $(call assert_boolean,ERRATA_A57_826974))
-$(eval $(call add_define,ERRATA_A57_826974))
-
-# Process ERRATA_A57_826977 flag
-$(eval $(call assert_boolean,ERRATA_A57_826977))
-$(eval $(call add_define,ERRATA_A57_826977))
-
-# Process ERRATA_A57_828024 flag
-$(eval $(call assert_boolean,ERRATA_A57_828024))
-$(eval $(call add_define,ERRATA_A57_828024))
-
-# Process ERRATA_A57_829520 flag
-$(eval $(call assert_boolean,ERRATA_A57_829520))
-$(eval $(call add_define,ERRATA_A57_829520))
-
-# Process ERRATA_A57_833471 flag
-$(eval $(call assert_boolean,ERRATA_A57_833471))
-$(eval $(call add_define,ERRATA_A57_833471))
-
-# Process ERRATA_A57_859972 flag
-$(eval $(call assert_boolean,ERRATA_A57_859972))
-$(eval $(call add_define,ERRATA_A57_859972))
-
-# Process ERRATA_A57_1319537 flag
-$(eval $(call assert_boolean,ERRATA_A57_1319537))
-$(eval $(call add_define,ERRATA_A57_1319537))
-
-# Process ERRATA_A72_859971 flag
-$(eval $(call assert_boolean,ERRATA_A72_859971))
-$(eval $(call add_define,ERRATA_A72_859971))
-
-# Process ERRATA_A72_1319367 flag
-$(eval $(call assert_boolean,ERRATA_A72_1319367))
-$(eval $(call add_define,ERRATA_A72_1319367))
-
-# Process ERRATA_A73_852427 flag
-$(eval $(call assert_boolean,ERRATA_A73_852427))
-$(eval $(call add_define,ERRATA_A73_852427))
-
-# Process ERRATA_A73_855423 flag
-$(eval $(call assert_boolean,ERRATA_A73_855423))
-$(eval $(call add_define,ERRATA_A73_855423))
-
-# Process ERRATA_A75_764081 flag
-$(eval $(call assert_boolean,ERRATA_A75_764081))
-$(eval $(call add_define,ERRATA_A75_764081))
-
-# Process ERRATA_A75_790748 flag
-$(eval $(call assert_boolean,ERRATA_A75_790748))
-$(eval $(call add_define,ERRATA_A75_790748))
-
-# Process ERRATA_A76_1073348 flag
-$(eval $(call assert_boolean,ERRATA_A76_1073348))
-$(eval $(call add_define,ERRATA_A76_1073348))
-
-# Process ERRATA_A76_1130799 flag
-$(eval $(call assert_boolean,ERRATA_A76_1130799))
-$(eval $(call add_define,ERRATA_A76_1130799))
-
-# Process ERRATA_A76_1220197 flag
-$(eval $(call assert_boolean,ERRATA_A76_1220197))
-$(eval $(call add_define,ERRATA_A76_1220197))
-
-# Process ERRATA_A76_1257314 flag
-$(eval $(call assert_boolean,ERRATA_A76_1257314))
-$(eval $(call add_define,ERRATA_A76_1257314))
-
-# Process ERRATA_A76_1262606 flag
-$(eval $(call assert_boolean,ERRATA_A76_1262606))
-$(eval $(call add_define,ERRATA_A76_1262606))
-
-# Process ERRATA_A76_1262888 flag
-$(eval $(call assert_boolean,ERRATA_A76_1262888))
-$(eval $(call add_define,ERRATA_A76_1262888))
-
-# Process ERRATA_A76_1275112 flag
-$(eval $(call assert_boolean,ERRATA_A76_1275112))
-$(eval $(call add_define,ERRATA_A76_1275112))
-
-# Process ERRATA_A76_1286807 flag
-$(eval $(call assert_boolean,ERRATA_A76_1286807))
-$(eval $(call add_define,ERRATA_A76_1286807))
-
-# Process ERRATA_A76_1791580 flag
-$(eval $(call assert_boolean,ERRATA_A76_1791580))
-$(eval $(call add_define,ERRATA_A76_1791580))
-
-# Process ERRATA_A76_1165522 flag
-$(eval $(call assert_boolean,ERRATA_A76_1165522))
-$(eval $(call add_define,ERRATA_A76_1165522))
-
-# Process ERRATA_A76_1868343 flag
-$(eval $(call assert_boolean,ERRATA_A76_1868343))
-$(eval $(call add_define,ERRATA_A76_1868343))
-
-# Process ERRATA_A76_1946160 flag
-$(eval $(call assert_boolean,ERRATA_A76_1946160))
-$(eval $(call add_define,ERRATA_A76_1946160))
-
-# Process ERRATA_A76_2743102 flag
-$(eval $(call assert_boolean,ERRATA_A76_2743102))
-$(eval $(call add_define,ERRATA_A76_2743102))
-
-# Process ERRATA_A77_1508412 flag
-$(eval $(call assert_boolean,ERRATA_A77_1508412))
-$(eval $(call add_define,ERRATA_A77_1508412))
-
-# Process ERRATA_A77_1925769 flag
-$(eval $(call assert_boolean,ERRATA_A77_1925769))
-$(eval $(call add_define,ERRATA_A77_1925769))
-
-# Process ERRATA_A77_1946167 flag
-$(eval $(call assert_boolean,ERRATA_A77_1946167))
-$(eval $(call add_define,ERRATA_A77_1946167))
-
-# Process ERRATA_A77_1791578 flag
-$(eval $(call assert_boolean,ERRATA_A77_1791578))
-$(eval $(call add_define,ERRATA_A77_1791578))
-
-# Process ERRATA_A77_2356587 flag
-$(eval $(call assert_boolean,ERRATA_A77_2356587))
-$(eval $(call add_define,ERRATA_A77_2356587))
-
-# Process ERRATA_A77_1800714 flag
-$(eval $(call assert_boolean,ERRATA_A77_1800714))
-$(eval $(call add_define,ERRATA_A77_1800714))
-
-# Process ERRATA_A77_2743100 flag
-$(eval $(call assert_boolean,ERRATA_A77_2743100))
-$(eval $(call add_define,ERRATA_A77_2743100))
-
-# Process ERRATA_A78_1688305 flag
-$(eval $(call assert_boolean,ERRATA_A78_1688305))
-$(eval $(call add_define,ERRATA_A78_1688305))
-
-# Process ERRATA_A78_1941498 flag
-$(eval $(call assert_boolean,ERRATA_A78_1941498))
-$(eval $(call add_define,ERRATA_A78_1941498))
-
-# Process ERRATA_A78_1951500 flag
-$(eval $(call assert_boolean,ERRATA_A78_1951500))
-$(eval $(call add_define,ERRATA_A78_1951500))
-
-# Process ERRATA_A78_1821534 flag
-$(eval $(call assert_boolean,ERRATA_A78_1821534))
-$(eval $(call add_define,ERRATA_A78_1821534))
-
-# Process ERRATA_A78_1952683 flag
-$(eval $(call assert_boolean,ERRATA_A78_1952683))
-$(eval $(call add_define,ERRATA_A78_1952683))
-
-# Process ERRATA_A78_2132060 flag
-$(eval $(call assert_boolean,ERRATA_A78_2132060))
-$(eval $(call add_define,ERRATA_A78_2132060))
-
-# Process ERRATA_A78_2242635 flag
-$(eval $(call assert_boolean,ERRATA_A78_2242635))
-$(eval $(call add_define,ERRATA_A78_2242635))
-
-# Process ERRATA_A78_2376745 flag
-$(eval $(call assert_boolean,ERRATA_A78_2376745))
-$(eval $(call add_define,ERRATA_A78_2376745))
-
-# Process ERRATA_A78_2395406 flag
-$(eval $(call assert_boolean,ERRATA_A78_2395406))
-$(eval $(call add_define,ERRATA_A78_2395406))
-
-# Process ERRATA_A78_2742426 flag
-$(eval $(call assert_boolean,ERRATA_A78_2742426))
-$(eval $(call add_define,ERRATA_A78_2742426))
-
-# Process ERRATA_A78_2772019 flag
-$(eval $(call assert_boolean,ERRATA_A78_2772019))
-$(eval $(call add_define,ERRATA_A78_2772019))
-
-# Process ERRATA_A78_2779479 flag
-$(eval $(call assert_boolean,ERRATA_A78_2779479))
-$(eval $(call add_define,ERRATA_A78_2779479))
-
-# Process ERRATA_A78_AE_1941500 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
-$(eval $(call add_define,ERRATA_A78_AE_1941500))
+CPU_FLAG_LIST += ERRATA_DSU_2313941
 
-# Process ERRATA_A78_AE_1951502 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
-$(eval $(call add_define,ERRATA_A78_AE_1951502))
-
-# Process ERRATA_A78_AE_2376748 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_2376748))
-$(eval $(call add_define,ERRATA_A78_AE_2376748))
-
-# Process ERRATA_A78_AE_2395408 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_2395408))
-$(eval $(call add_define,ERRATA_A78_AE_2395408))
-
-# Process ERRATA_A78C_2132064 flag
-$(eval $(call assert_boolean,ERRATA_A78C_2132064))
-$(eval $(call add_define,ERRATA_A78C_2132064))
-
-# Process ERRATA_A78C_2242638 flag
-$(eval $(call assert_boolean,ERRATA_A78C_2242638))
-$(eval $(call add_define,ERRATA_A78C_2242638))
-
-# Process ERRATA_A78C_2376749 flag
-$(eval $(call assert_boolean,ERRATA_A78C_2376749))
-$(eval $(call add_define,ERRATA_A78C_2376749))
-
-# Process ERRATA_A78C_2395411 flag
-$(eval $(call assert_boolean,ERRATA_A78C_2395411))
-$(eval $(call add_define,ERRATA_A78C_2395411))
-
-# Process ERRATA_A78C_2772121 flag
-$(eval $(call assert_boolean,ERRATA_A78C_2772121))
-$(eval $(call add_define,ERRATA_A78C_2772121))
-
-# Process ERRATA_A78C_2779484 flag
-$(eval $(call assert_boolean,ERRATA_A78C_2779484))
-$(eval $(call add_define,ERRATA_A78C_2779484))
-
-# Process ERRATA_X1_1821534 flag
-$(eval $(call assert_boolean,ERRATA_X1_1821534))
-$(eval $(call add_define,ERRATA_X1_1821534))
-
-# Process ERRATA_X1_1688305 flag
-$(eval $(call assert_boolean,ERRATA_X1_1688305))
-$(eval $(call add_define,ERRATA_X1_1688305))
-
-# Process ERRATA_X1_1827429 flag
-$(eval $(call assert_boolean,ERRATA_X1_1827429))
-$(eval $(call add_define,ERRATA_X1_1827429))
-
-# Process ERRATA_N1_1043202 flag
-$(eval $(call assert_boolean,ERRATA_N1_1043202))
-$(eval $(call add_define,ERRATA_N1_1043202))
-
-# Process ERRATA_N1_1073348 flag
-$(eval $(call assert_boolean,ERRATA_N1_1073348))
-$(eval $(call add_define,ERRATA_N1_1073348))
-
-# Process ERRATA_N1_1130799 flag
-$(eval $(call assert_boolean,ERRATA_N1_1130799))
-$(eval $(call add_define,ERRATA_N1_1130799))
-
-# Process ERRATA_N1_1165347 flag
-$(eval $(call assert_boolean,ERRATA_N1_1165347))
-$(eval $(call add_define,ERRATA_N1_1165347))
-
-# Process ERRATA_N1_1207823 flag
-$(eval $(call assert_boolean,ERRATA_N1_1207823))
-$(eval $(call add_define,ERRATA_N1_1207823))
-
-# Process ERRATA_N1_1220197 flag
-$(eval $(call assert_boolean,ERRATA_N1_1220197))
-$(eval $(call add_define,ERRATA_N1_1220197))
-
-# Process ERRATA_N1_1257314 flag
-$(eval $(call assert_boolean,ERRATA_N1_1257314))
-$(eval $(call add_define,ERRATA_N1_1257314))
-
-# Process ERRATA_N1_1262606 flag
-$(eval $(call assert_boolean,ERRATA_N1_1262606))
-$(eval $(call add_define,ERRATA_N1_1262606))
-
-# Process ERRATA_N1_1262888 flag
-$(eval $(call assert_boolean,ERRATA_N1_1262888))
-$(eval $(call add_define,ERRATA_N1_1262888))
-
-# Process ERRATA_N1_1275112 flag
-$(eval $(call assert_boolean,ERRATA_N1_1275112))
-$(eval $(call add_define,ERRATA_N1_1275112))
-
-# Process ERRATA_N1_1315703 flag
-$(eval $(call assert_boolean,ERRATA_N1_1315703))
-$(eval $(call add_define,ERRATA_N1_1315703))
-
-# Process ERRATA_N1_1542419 flag
-$(eval $(call assert_boolean,ERRATA_N1_1542419))
-$(eval $(call add_define,ERRATA_N1_1542419))
-
-# Process ERRATA_N1_1868343 flag
-$(eval $(call assert_boolean,ERRATA_N1_1868343))
-$(eval $(call add_define,ERRATA_N1_1868343))
-
-# Process ERRATA_N1_1946160 flag
-$(eval $(call assert_boolean,ERRATA_N1_1946160))
-$(eval $(call add_define,ERRATA_N1_1946160))
-
-# Process ERRATA_N1_2743102 flag
-$(eval $(call assert_boolean,ERRATA_N1_2743102))
-$(eval $(call add_define,ERRATA_N1_2743102))
-
-# Process ERRATA_V1_1618635 flag
-$(eval $(call assert_boolean,ERRATA_V1_1618635))
-$(eval $(call add_define,ERRATA_V1_1618635))
-
-# Process ERRATA_V1_1774420 flag
-$(eval $(call assert_boolean,ERRATA_V1_1774420))
-$(eval $(call add_define,ERRATA_V1_1774420))
-
-# Process ERRATA_V1_1791573 flag
-$(eval $(call assert_boolean,ERRATA_V1_1791573))
-$(eval $(call add_define,ERRATA_V1_1791573))
-
-# Process ERRATA_V1_1852267 flag
-$(eval $(call assert_boolean,ERRATA_V1_1852267))
-$(eval $(call add_define,ERRATA_V1_1852267))
-
-# Process ERRATA_V1_1925756 flag
-$(eval $(call assert_boolean,ERRATA_V1_1925756))
-$(eval $(call add_define,ERRATA_V1_1925756))
-
-# Process ERRATA_V1_1940577 flag
-$(eval $(call assert_boolean,ERRATA_V1_1940577))
-$(eval $(call add_define,ERRATA_V1_1940577))
-
-# Process ERRATA_V1_1966096 flag
-$(eval $(call assert_boolean,ERRATA_V1_1966096))
-$(eval $(call add_define,ERRATA_V1_1966096))
-
-# Process ERRATA_V1_2139242 flag
-$(eval $(call assert_boolean,ERRATA_V1_2139242))
-$(eval $(call add_define,ERRATA_V1_2139242))
-
-# Process ERRATA_V1_2108267 flag
-$(eval $(call assert_boolean,ERRATA_V1_2108267))
-$(eval $(call add_define,ERRATA_V1_2108267))
-
-# Process ERRATA_V1_2216392 flag
-$(eval $(call assert_boolean,ERRATA_V1_2216392))
-$(eval $(call add_define,ERRATA_V1_2216392))
-
-# Process ERRATA_V1_2294912 flag
-$(eval $(call assert_boolean,ERRATA_V1_2294912))
-$(eval $(call add_define,ERRATA_V1_2294912))
-
-# Process ERRATA_V1_2372203 flag
-$(eval $(call assert_boolean,ERRATA_V1_2372203))
-$(eval $(call add_define,ERRATA_V1_2372203))
-
-# Process ERRATA_V1_2743093 flag
-$(eval $(call assert_boolean,ERRATA_V1_2743093))
-$(eval $(call add_define,ERRATA_V1_2743093))
-
-# Process ERRATA_V1_2743233 flag
-$(eval $(call assert_boolean,ERRATA_V1_2743233))
-$(eval $(call add_define,ERRATA_V1_2743233))
-
-# Process ERRATA_V1_2779461 flag
-$(eval $(call assert_boolean,ERRATA_V1_2779461))
-$(eval $(call add_define,ERRATA_V1_2779461))
-
-# Process ERRATA_A710_1987031 flag
-$(eval $(call assert_boolean,ERRATA_A710_1987031))
-$(eval $(call add_define,ERRATA_A710_1987031))
-
-# Process ERRATA_A710_2081180 flag
-$(eval $(call assert_boolean,ERRATA_A710_2081180))
-$(eval $(call add_define,ERRATA_A710_2081180))
-
-# Process ERRATA_A710_2083908 flag
-$(eval $(call assert_boolean,ERRATA_A710_2083908))
-$(eval $(call add_define,ERRATA_A710_2083908))
-
-# Process ERRATA_A710_2058056 flag
-$(eval $(call assert_boolean,ERRATA_A710_2058056))
-$(eval $(call add_define,ERRATA_A710_2058056))
-
-# Process ERRATA_A710_2055002 flag
-$(eval $(call assert_boolean,ERRATA_A710_2055002))
-$(eval $(call add_define,ERRATA_A710_2055002))
-
-# Process ERRATA_A710_2017096 flag
-$(eval $(call assert_boolean,ERRATA_A710_2017096))
-$(eval $(call add_define,ERRATA_A710_2017096))
-
-# Process ERRATA_A710_2267065 flag
-$(eval $(call assert_boolean,ERRATA_A710_2267065))
-$(eval $(call add_define,ERRATA_A710_2267065))
-
-# Process ERRATA_A710_2136059 flag
-$(eval $(call assert_boolean,ERRATA_A710_2136059))
-$(eval $(call add_define,ERRATA_A710_2136059))
-
-# Process ERRATA_A710_2147715 flag
-$(eval $(call assert_boolean,ERRATA_A710_2147715))
-$(eval $(call add_define,ERRATA_A710_2147715))
-
-# Process ERRATA_A710_2216384 flag
-$(eval $(call assert_boolean,ERRATA_A710_2216384))
-$(eval $(call add_define,ERRATA_A710_2216384))
-
-# Process ERRATA_A710_2282622 flag
-$(eval $(call assert_boolean,ERRATA_A710_2282622))
-$(eval $(call add_define,ERRATA_A710_2282622))
-
-# Process ERRATA_A710_2291219 flag
-$(eval $(call assert_boolean,ERRATA_A710_2291219))
-$(eval $(call add_define,ERRATA_A710_2291219))
-
-# Process ERRATA_A710_2008768 flag
-$(eval $(call assert_boolean,ERRATA_A710_2008768))
-$(eval $(call add_define,ERRATA_A710_2008768))
-
-# Process ERRATA_A710_2371105 flag
-$(eval $(call assert_boolean,ERRATA_A710_2371105))
-$(eval $(call add_define,ERRATA_A710_2371105))
-
-# Process ERRATA_A710_2768515 flag
-$(eval $(call assert_boolean,ERRATA_A710_2768515))
-$(eval $(call add_define,ERRATA_A710_2768515))
-
-# Process ERRATA_N2_2002655 flag
-$(eval $(call assert_boolean,ERRATA_N2_2002655))
-$(eval $(call add_define,ERRATA_N2_2002655))
-
-# Process ERRATA_N2_2067956 flag
-$(eval $(call assert_boolean,ERRATA_N2_2067956))
-$(eval $(call add_define,ERRATA_N2_2067956))
-
-# Process ERRATA_N2_2025414 flag
-$(eval $(call assert_boolean,ERRATA_N2_2025414))
-$(eval $(call add_define,ERRATA_N2_2025414))
-
-# Process ERRATA_N2_2189731 flag
-$(eval $(call assert_boolean,ERRATA_N2_2189731))
-$(eval $(call add_define,ERRATA_N2_2189731))
-
-# Process ERRATA_N2_2138956 flag
-$(eval $(call assert_boolean,ERRATA_N2_2138956))
-$(eval $(call add_define,ERRATA_N2_2138956))
-
-# Process ERRATA_N2_2138953 flag
-$(eval $(call assert_boolean,ERRATA_N2_2138953))
-$(eval $(call add_define,ERRATA_N2_2138953))
-
-# Process ERRATA_N2_2242415 flag
-$(eval $(call assert_boolean,ERRATA_N2_2242415))
-$(eval $(call add_define,ERRATA_N2_2242415))
-
-# Process ERRATA_N2_2138958 flag
-$(eval $(call assert_boolean,ERRATA_N2_2138958))
-$(eval $(call add_define,ERRATA_N2_2138958))
-
-# Process ERRATA_N2_2242400 flag
-$(eval $(call assert_boolean,ERRATA_N2_2242400))
-$(eval $(call add_define,ERRATA_N2_2242400))
-
-# Process ERRATA_N2_2280757 flag
-$(eval $(call assert_boolean,ERRATA_N2_2280757))
-$(eval $(call add_define,ERRATA_N2_2280757))
-
-# Process ERRATA_N2_2326639 flag
-$(eval $(call assert_boolean,ERRATA_N2_2326639))
-$(eval $(call add_define,ERRATA_N2_2326639))
-
-# Process ERRATA_N2_2376738 flag
-$(eval $(call assert_boolean,ERRATA_N2_2376738))
-$(eval $(call add_define,ERRATA_N2_2376738))
-
-# Process ERRATA_N2_2388450 flag
-$(eval $(call assert_boolean,ERRATA_N2_2388450))
-$(eval $(call add_define,ERRATA_N2_2388450))
-
-# Process ERRATA_N2_2743089 flag
-$(eval $(call assert_boolean,ERRATA_N2_2743089))
-$(eval $(call add_define,ERRATA_N2_2743089))
-
-# Process ERRATA_X2_2002765 flag
-$(eval $(call assert_boolean,ERRATA_X2_2002765))
-$(eval $(call add_define,ERRATA_X2_2002765))
-
-# Process ERRATA_X2_2058056 flag
-$(eval $(call assert_boolean,ERRATA_X2_2058056))
-$(eval $(call add_define,ERRATA_X2_2058056))
-
-# Process ERRATA_X2_2083908 flag
-$(eval $(call assert_boolean,ERRATA_X2_2083908))
-$(eval $(call add_define,ERRATA_X2_2083908))
-
-# Process ERRATA_X2_2017096 flag
-$(eval $(call assert_boolean,ERRATA_X2_2017096))
-$(eval $(call add_define,ERRATA_X2_2017096))
-
-# Process ERRATA_X2_2081180 flag
-$(eval $(call assert_boolean,ERRATA_X2_2081180))
-$(eval $(call add_define,ERRATA_X2_2081180))
-
-# Process ERRATA_X2_2216384 flag
-$(eval $(call assert_boolean,ERRATA_X2_2216384))
-$(eval $(call add_define,ERRATA_X2_2216384))
-
-# Process ERRATA_X2_2147715 flag
-$(eval $(call assert_boolean,ERRATA_X2_2147715))
-$(eval $(call add_define,ERRATA_X2_2147715))
-
-# Process ERRATA_X2_2282622 flag
-$(eval $(call assert_boolean,ERRATA_X2_2282622))
-$(eval $(call add_define,ERRATA_X2_2282622))
-
-# Process ERRATA_X2_2371105 flag
-$(eval $(call assert_boolean,ERRATA_X2_2371105))
-$(eval $(call add_define,ERRATA_X2_2371105))
-
-# Process ERRATA_X2_2768515 flag
-$(eval $(call assert_boolean,ERRATA_X2_2768515))
-$(eval $(call add_define,ERRATA_X2_2768515))
-
-# Process ERRATA_X3_2313909 flag
-$(eval $(call assert_boolean,ERRATA_X3_2313909))
-$(eval $(call add_define,ERRATA_X3_2313909))
-
-# Process ERRATA_X3_2615812 flag
-$(eval $(call assert_boolean,ERRATA_X3_2615812))
-$(eval $(call add_define,ERRATA_X3_2615812))
-
-# Process ERRATA_A510_1922240 flag
-$(eval $(call assert_boolean,ERRATA_A510_1922240))
-$(eval $(call add_define,ERRATA_A510_1922240))
-
-# Process ERRATA_A510_2288014 flag
-$(eval $(call assert_boolean,ERRATA_A510_2288014))
-$(eval $(call add_define,ERRATA_A510_2288014))
-
-# Process ERRATA_A510_2042739 flag
-$(eval $(call assert_boolean,ERRATA_A510_2042739))
-$(eval $(call add_define,ERRATA_A510_2042739))
-
-# Process ERRATA_A510_2041909 flag
-$(eval $(call assert_boolean,ERRATA_A510_2041909))
-$(eval $(call add_define,ERRATA_A510_2041909))
-
-# Process ERRATA_A510_2250311 flag
-$(eval $(call assert_boolean,ERRATA_A510_2250311))
-$(eval $(call add_define,ERRATA_A510_2250311))
-
-# Process ERRATA_A510_2218950 flag
-$(eval $(call assert_boolean,ERRATA_A510_2218950))
-$(eval $(call add_define,ERRATA_A510_2218950))
-
-# Process ERRATA_A510_2172148 flag
-$(eval $(call assert_boolean,ERRATA_A510_2172148))
-$(eval $(call add_define,ERRATA_A510_2172148))
-
-# Process ERRATA_A510_2347730 flag
-$(eval $(call assert_boolean,ERRATA_A510_2347730))
-$(eval $(call add_define,ERRATA_A510_2347730))
-
-# Process ERRATA_A510_2371937 flag
-$(eval $(call assert_boolean,ERRATA_A510_2371937))
-$(eval $(call add_define,ERRATA_A510_2371937))
-
-# Process ERRATA_A510_2666669 flag
-$(eval $(call assert_boolean,ERRATA_A510_2666669))
-$(eval $(call add_define,ERRATA_A510_2666669))
-
-# Process ERRATA_A510_2684597 flag
-$(eval $(call assert_boolean,ERRATA_A510_2684597))
-$(eval $(call add_define,ERRATA_A510_2684597))
-
-#Process ERRATA_DSU_798953 flag
-$(eval $(call assert_boolean,ERRATA_DSU_798953))
-$(eval $(call add_define,ERRATA_DSU_798953))
-
-# Process ERRATA_DSU_936184 flag
-$(eval $(call assert_boolean,ERRATA_DSU_936184))
-$(eval $(call add_define,ERRATA_DSU_936184))
+ifneq (${DYNAMIC_WORKAROUND_CVE_2018_3639},0)
+	ifeq (${WORKAROUND_CVE_2018_3639},0)
+		$(error "Error: WORKAROUND_CVE_2018_3639 must be 1 if DYNAMIC_WORKAROUND_CVE_2018_3639 is 1")
+	endif
+endif
 
-# Process ERRATA_DSU_2313941 flag
-$(eval $(call assert_boolean,ERRATA_DSU_2313941))
-$(eval $(call add_define,ERRATA_DSU_2313941))
+# process all flags
+$(eval $(call default_zeros, $(CPU_FLAG_LIST)))
+$(eval $(call add_defines, $(CPU_FLAG_LIST)))
+$(eval $(call assert_booleans, $(CPU_FLAG_LIST)))
 
 # Errata build flags
 ifneq (${ERRATA_A53_843419},0)
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index 5f41aee..4e9bdfc 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,8 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
-#include <lib/cpus/errata_report.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/spinlock.h>
 
@@ -30,11 +31,106 @@
 /* Errata format: BL stage, CPU, errata ID, message */
 #define ERRATA_FORMAT	"%s: %s: CPU workaround for %s was %s\n"
 
+#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"
+
+
+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
+ * 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;
+	bool failed = false;
+#endif /* FEATURE_DETECTION */
+
+	for (; entry != end; entry += 1) {
+		uint64_t status = entry->check_func(rev_var);
+
+		assert(entry->id != 0);
+
+		/*
+		 * Errata workaround has not been compiled in. If the errata
+		 * would have applied had it been compiled in, print its status
+		 * as missing.
+		 */
+		if (status == ERRATA_APPLIES && entry->chosen == 0) {
+			status = ERRATA_MISSING;
+		}
+
+		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",
+				      entry->cve, entry->id);
+				failed = true;
+			}
+			check_cve = true;
+			last_cve_yr = entry->cve;
+		} else {
+			if (last_erratum_id >= entry->id || check_cve) {
+				ERROR("Erratum %u was out of order!\n",
+				      entry->id);
+				failed = true;
+			}
+		}
+		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 */
+}
+
 /*
  * Returns whether errata needs to be reported. Passed arguments are private to
  * a CPU type.
  */
-int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
+static __unused int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
 {
 	bool report_now;
 
@@ -56,14 +152,44 @@
 }
 
 /*
- * Print errata status message.
- *
- * Unknown: WARN
- * Missing: WARN
- * Applied: INFO
- * Not applied: VERBOSE
+ * Function to print errata status for the calling CPU (and others of the same
+ * type). Must be called only:
+ *   - when MMU and data caches are enabled;
+ *   - after cpu_ops have been initialized in per-CPU data.
+ */
+void print_errata_status(void)
+{
+	struct cpu_ops *cpu_ops;
+#ifdef IMAGE_BL1
+	/*
+	 * BL1 doesn't have per-CPU data. So retrieve the CPU operations
+	 * directly.
+	 */
+	cpu_ops = get_cpu_ops_ptr();
+
+	if (cpu_ops->errata_func != NULL) {
+		cpu_ops->errata_func();
+	}
+#else /* IMAGE_BL1 */
+	cpu_ops = (void *) get_cpu_data(cpu_ops_ptr);
+
+	assert(cpu_ops != NULL);
+
+	if (cpu_ops->errata_func == NULL) {
+		return;
+	}
+
+	if (errata_needs_reporting(cpu_ops->errata_lock, cpu_ops->errata_reported)) {
+		cpu_ops->errata_func();
+	}
+#endif /* IMAGE_BL1 */
+}
+
+/*
+ * Old errata status message printer
+ * TODO: remove once all cpus have been converted to the new printing method
  */
-void errata_print_msg(unsigned int status, const char *cpu, const char *id)
+void __unused errata_print_msg(unsigned int status, const char *cpu, const char *id)
 {
 	/* Errata status strings */
 	static const char *const errata_status_str[] = {
@@ -99,3 +225,4 @@
 		break;
 	}
 }
+#endif /* !REPORT_ERRATA */
diff --git a/lib/debugfs/debugfs_smc.c b/lib/debugfs/debugfs_smc.c
index 400c166..13ced3d 100644
--- a/lib/debugfs/debugfs_smc.c
+++ b/lib/debugfs/debugfs_smc.c
@@ -54,7 +54,7 @@
 } parms;
 
 /* debugfs_access_lock protects shared buffer and internal */
-/* FS functions from concurrent acccesses.                 */
+/* FS functions from concurrent accesses.                 */
 static spinlock_t debugfs_access_lock;
 
 static bool debugfs_initialized;
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index e494a86..6414aaa 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 #include <context.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/extensions/amu.h>
+#include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sys_reg_trace.h>
 #include <lib/extensions/trf.h>
 #include <lib/utils.h>
@@ -136,17 +137,23 @@
 static void enable_extensions_nonsecure(bool el2_unused)
 {
 #if IMAGE_BL32
-#if ENABLE_AMU
-	amu_enable(el2_unused);
-#endif
+	if (is_feat_amu_supported()) {
+		amu_enable(el2_unused);
+	}
 
-#if ENABLE_SYS_REG_TRACE_FOR_NS
-	sys_reg_trace_enable();
-#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+	if (is_feat_sys_reg_trace_supported()) {
+		sys_reg_trace_enable();
+	}
 
 	if (is_feat_trf_supported()) {
 		trf_enable();
 	}
+
+	/*
+	 * Also applies to PMU < v3. The PMU is only disabled for EL3 and Secure
+	 * state execution. This does not affect lower NS ELs.
+	 */
+	pmuv3_disable_el3();
 #endif
 }
 
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index d439148..771fcdc 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -13,38 +13,10 @@
 #if CTX_INCLUDE_EL2_REGS
 	.global	el2_sysregs_context_save_common
 	.global	el2_sysregs_context_restore_common
-#if ENABLE_SPE_FOR_LOWER_ELS
-	.global	el2_sysregs_context_save_spe
-	.global	el2_sysregs_context_restore_spe
-#endif /* ENABLE_SPE_FOR_LOWER_ELS */
 #if CTX_INCLUDE_MTE_REGS
 	.global	el2_sysregs_context_save_mte
 	.global	el2_sysregs_context_restore_mte
 #endif /* CTX_INCLUDE_MTE_REGS */
-#if ENABLE_MPAM_FOR_LOWER_ELS
-	.global	el2_sysregs_context_save_mpam
-	.global	el2_sysregs_context_restore_mpam
-#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-#if ENABLE_FEAT_ECV
-	.global	el2_sysregs_context_save_ecv
-	.global	el2_sysregs_context_restore_ecv
-#endif /* ENABLE_FEAT_ECV */
-#if ENABLE_FEAT_VHE
-	.global	el2_sysregs_context_save_vhe
-	.global	el2_sysregs_context_restore_vhe
-#endif /* ENABLE_FEAT_VHE */
-#if RAS_EXTENSION
-	.global	el2_sysregs_context_save_ras
-	.global	el2_sysregs_context_restore_ras
-#endif /* RAS_EXTENSION */
-#if CTX_INCLUDE_NEVE_REGS
-	.global	el2_sysregs_context_save_nv2
-	.global	el2_sysregs_context_restore_nv2
-#endif /* CTX_INCLUDE_NEVE_REGS */
-#if ENABLE_FEAT_CSV2_2
-	.global	el2_sysregs_context_save_csv2
-	.global	el2_sysregs_context_restore_csv2
-#endif /* ENABLE_FEAT_CSV2_2 */
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	.global	el1_sysregs_context_save
@@ -220,20 +192,6 @@
 	ret
 endfunc el2_sysregs_context_restore_common
 
-#if ENABLE_SPE_FOR_LOWER_ELS
-func el2_sysregs_context_save_spe
-	mrs	x13, PMSCR_EL2
-	str	x13, [x0, #CTX_PMSCR_EL2]
-	ret
-endfunc el2_sysregs_context_save_spe
-
-func el2_sysregs_context_restore_spe
-	ldr	x13, [x0, #CTX_PMSCR_EL2]
-	msr	PMSCR_EL2, x13
-	ret
-endfunc el2_sysregs_context_restore_spe
-#endif /* ENABLE_SPE_FOR_LOWER_ELS */
-
 #if CTX_INCLUDE_MTE_REGS
 func el2_sysregs_context_save_mte
 	mrs	x9, TFSR_EL2
@@ -248,310 +206,6 @@
 endfunc el2_sysregs_context_restore_mte
 #endif /* CTX_INCLUDE_MTE_REGS */
 
-#if ENABLE_MPAM_FOR_LOWER_ELS
-func el2_sysregs_context_save_mpam
-	mrs	x10, MPAM2_EL2
-	str	x10, [x0, #CTX_MPAM2_EL2]
-
-	mrs	x10, MPAMIDR_EL1
-
-	/*
-	 * The context registers that we intend to save would be part of the
-	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
-	 */
-	tbz	w10, #MPAMIDR_EL1_HAS_HCR_SHIFT, 3f
-
-	/*
-	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 would be present in the
-	 * system register frame if MPAMIDR_EL1.HAS_HCR == 1. Proceed to save
-	 * the context of these registers.
-	 */
-	mrs	x11, MPAMHCR_EL2
-	mrs	x12, MPAMVPM0_EL2
-	stp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
-
-	mrs	x13, MPAMVPMV_EL2
-	str	x13, [x0, #CTX_MPAMVPMV_EL2]
-
-	/*
-	 * MPAMIDR_EL1.VPMR_MAX has to be probed to obtain the maximum supported
-	 * VPMR value. Proceed to save the context of registers from
-	 * MPAMVPM1_EL2 to MPAMVPM<x>_EL2 where x is VPMR_MAX. From MPAM spec,
-	 * VPMR_MAX should not be zero if HAS_HCR == 1.
-	 */
-	ubfx	x10, x10, #MPAMIDR_EL1_VPMR_MAX_SHIFT, \
-		#MPAMIDR_EL1_VPMR_MAX_WIDTH
-
-	/*
-	 * Once VPMR_MAX has been identified, calculate the offset relative to
-	 * PC to jump to so that relevant context can be saved. The offset is
-	 * calculated as (VPMR_POSSIBLE_MAX - VPMR_MAX) * (instruction size for
-	 * saving one VPM register) + (absolute address of label "1").
-	 */
-	mov	w11, #MPAMIDR_EL1_VPMR_MAX_POSSIBLE
-	sub	w10, w11, w10
-
-	/* Calculate the size of one block of MPAMVPM*_EL2 save */
-	adr	x11, 1f
-	adr	x12, 2f
-	sub	x12, x12, x11
-
-	madd	x10, x10, x12, x11
-	br	x10
-
-	/*
-	 * The branch above would land properly on one of the blocks following
-	 * label "1". Make sure that the order of save is retained.
-	 */
-1:
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x10, MPAMVPM7_EL2
-	str	x10, [x0, #CTX_MPAMVPM7_EL2]
-2:
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x11, MPAMVPM6_EL2
-	str	x11, [x0, #CTX_MPAMVPM6_EL2]
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x12, MPAMVPM5_EL2
-	str	x12, [x0, #CTX_MPAMVPM5_EL2]
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x13, MPAMVPM4_EL2
-	str	x13, [x0, #CTX_MPAMVPM4_EL2]
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x14, MPAMVPM3_EL2
-	str	x14, [x0, #CTX_MPAMVPM3_EL2]
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x15, MPAMVPM2_EL2
-	str	x15, [x0, #CTX_MPAMVPM2_EL2]
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	mrs	x16, MPAMVPM1_EL2
-	str	x16, [x0, #CTX_MPAMVPM1_EL2]
-
-3:	ret
-endfunc el2_sysregs_context_save_mpam
-
-func el2_sysregs_context_restore_mpam
-	ldr	x10, [x0, #CTX_MPAM2_EL2]
-	msr	MPAM2_EL2, x10
-
-	mrs	x10, MPAMIDR_EL1
-	/*
-	 * The context registers that we intend to restore would be part of the
-	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
-	 */
-	tbz	w10, #MPAMIDR_EL1_HAS_HCR_SHIFT, 3f
-
-	/*
-	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 would be present in the
-	 * system register frame if MPAMIDR_EL1.HAS_HCR == 1. Proceed to restore
-	 * the context of these registers
-	 */
-	ldp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
-	msr	MPAMHCR_EL2, x11
-	msr	MPAMVPM0_EL2, x12
-
-	ldr	x13, [x0, #CTX_MPAMVPMV_EL2]
-	msr	MPAMVPMV_EL2, x13
-
-	/*
-	 * MPAMIDR_EL1.VPMR_MAX has to be probed to obtain the maximum supported
-	 * VPMR value. Proceed to restore the context of registers from
-	 * MPAMVPM1_EL2 to MPAMVPM<x>_EL2 where x is VPMR_MAX. from MPAM spec,
-	 * VPMR_MAX should not be zero if HAS_HCR == 1.
-	 */
-	ubfx	x10, x10, #MPAMIDR_EL1_VPMR_MAX_SHIFT,	\
-		#MPAMIDR_EL1_VPMR_MAX_WIDTH
-
-	/*
-	 * Once VPMR_MAX has been identified, calculate the offset relative to
-	 * PC to jump to so that relevant context can be restored. The offset is
-	 * calculated as (VPMR_POSSIBLE_MAX - VPMR_MAX) * (instruction size for
-	 * restoring one VPM register) + (absolute address of label "1").
-	 */
-	mov	w11, #MPAMIDR_EL1_VPMR_MAX_POSSIBLE
-	sub	w10, w11, w10
-
-	/* Calculate the size of one block of MPAMVPM*_EL2 restore */
-	adr	x11, 1f
-	adr	x12, 2f
-	sub	x12, x12, x11
-
-	madd	x10, x10, x12, x11
-	br	x10
-
-	/*
-	 * The branch above would land properly on one of the blocks following
-	 * label "1". Make sure that the order of restore is retained.
-	 */
-1:
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x10, [x0, #CTX_MPAMVPM7_EL2]
-	msr	MPAMVPM7_EL2, x10
-2:
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x11, [x0, #CTX_MPAMVPM6_EL2]
-	msr	MPAMVPM6_EL2, x11
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x12, [x0, #CTX_MPAMVPM5_EL2]
-	msr	MPAMVPM5_EL2, x12
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x13, [x0, #CTX_MPAMVPM4_EL2]
-	msr	MPAMVPM4_EL2, x13
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x14, [x0, #CTX_MPAMVPM3_EL2]
-	msr	MPAMVPM3_EL2, x14
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x15, [x0, #CTX_MPAMVPM2_EL2]
-	msr	MPAMVPM2_EL2, x15
-
-#if ENABLE_BTI
-	bti	j
-#endif
-	ldr	x16, [x0, #CTX_MPAMVPM1_EL2]
-	msr	MPAMVPM1_EL2, x16
-
-3:	ret
-endfunc el2_sysregs_context_restore_mpam
-#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-
-#if ENABLE_FEAT_ECV
-func el2_sysregs_context_save_ecv
-	mrs	x11, CNTPOFF_EL2
-	str	x11, [x0, #CTX_CNTPOFF_EL2]
-	ret
-endfunc el2_sysregs_context_save_ecv
-
-func el2_sysregs_context_restore_ecv
-	ldr	x11, [x0, #CTX_CNTPOFF_EL2]
-	msr	CNTPOFF_EL2, x11
-	ret
-endfunc el2_sysregs_context_restore_ecv
-#endif /* ENABLE_FEAT_ECV */
-
-#if ENABLE_FEAT_VHE
-func el2_sysregs_context_save_vhe
-	/*
-	 * CONTEXTIDR_EL2 register is saved only when FEAT_VHE or
-	 * FEAT_Debugv8p2 (currently not in TF-A) is supported.
-	 */
-	mrs	x9, contextidr_el2
-	mrs	x10, ttbr1_el2
-	stp	x9, x10, [x0, #CTX_CONTEXTIDR_EL2]
-	ret
-endfunc el2_sysregs_context_save_vhe
-
-func el2_sysregs_context_restore_vhe
-	/*
-	 * CONTEXTIDR_EL2 register is restored only when FEAT_VHE or
-	 * FEAT_Debugv8p2 (currently not in TF-A) is supported.
-	 */
-	ldp	x9, x10, [x0, #CTX_CONTEXTIDR_EL2]
-	msr	contextidr_el2, x9
-	msr	ttbr1_el2, x10
-	ret
-endfunc el2_sysregs_context_restore_vhe
-#endif /* ENABLE_FEAT_VHE */
-
-#if RAS_EXTENSION
-func el2_sysregs_context_save_ras
-	/*
-	 * VDISR_EL2 and VSESR_EL2 registers are saved only when
-	 * FEAT_RAS is supported.
-	 */
-	mrs	x11, vdisr_el2
-	mrs	x12, vsesr_el2
-	stp	x11, x12, [x0, #CTX_VDISR_EL2]
-	ret
-endfunc el2_sysregs_context_save_ras
-
-func el2_sysregs_context_restore_ras
-	/*
-	 * VDISR_EL2 and VSESR_EL2 registers are restored only when FEAT_RAS
-	 * is supported.
-	 */
-	ldp	x11, x12, [x0, #CTX_VDISR_EL2]
-	msr	vdisr_el2, x11
-	msr	vsesr_el2, x12
-	ret
-endfunc el2_sysregs_context_restore_ras
-#endif /* RAS_EXTENSION */
-
-#if CTX_INCLUDE_NEVE_REGS
-func el2_sysregs_context_save_nv2
-	/*
-	 * VNCR_EL2 register is saved only when FEAT_NV2 is supported.
-	 */
-	mrs	x16, vncr_el2
-	str	x16, [x0, #CTX_VNCR_EL2]
-	ret
-endfunc el2_sysregs_context_save_nv2
-
-func el2_sysregs_context_restore_nv2
-	/*
-	 * VNCR_EL2 register is restored only when FEAT_NV2 is supported.
-	 */
-	ldr	x16, [x0, #CTX_VNCR_EL2]
-	msr	vncr_el2, x16
-	ret
-endfunc el2_sysregs_context_restore_nv2
-#endif /* CTX_INCLUDE_NEVE_REGS */
-
-#if ENABLE_FEAT_CSV2_2
-func el2_sysregs_context_save_csv2
-	/*
-	 * SCXTNUM_EL2 register is saved only when FEAT_CSV2_2 is supported.
-	 */
-	mrs	x13, scxtnum_el2
-	str	x13, [x0, #CTX_SCXTNUM_EL2]
-	ret
-endfunc el2_sysregs_context_save_csv2
-
-func el2_sysregs_context_restore_csv2
-	/*
-	 * SCXTNUM_EL2 register is restored only when FEAT_CSV2_2 is supported.
-	 */
-	ldr	x13, [x0, #CTX_SCXTNUM_EL2]
-	msr	scxtnum_el2, x13
-	ret
-endfunc el2_sysregs_context_restore_csv2
-#endif /* ENABLE_FEAT_CSV2_2 */
-
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 /* ------------------------------------------------------------------
@@ -871,8 +525,14 @@
 	 * always enable DIT in EL3
 	 */
 #if ENABLE_FEAT_DIT
+#if ENABLE_FEAT_DIT == 2
+	mrs	x8, id_aa64pfr0_el1
+	and	x8, x8, #(ID_AA64PFR0_DIT_MASK << ID_AA64PFR0_DIT_SHIFT)
+	cbz	x8, 1f
+#endif
 	mov     x8, #DIT_BIT
 	msr     DIT, x8
+1:
 #endif /* ENABLE_FEAT_DIT */
 	.endm /* set_unset_pstate_bits */
 
@@ -909,47 +569,13 @@
 	mrs	x18, sp_el0
 	str	x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
 
-	/* ----------------------------------------------------------
-	 * Check if earlier initialization of MDCR_EL3.SCCD/MCCD to 1
-	 * has failed.
-	 *
-	 * MDCR_EL3:
-	 * MCCD bit set, Prohibits the Cycle Counter PMCCNTR_EL0 from
-	 * counting at EL3.
-	 * SCCD bit set, Secure Cycle Counter Disable. Prohibits PMCCNTR_EL0
-	 * from counting in Secure state.
-	 * If these bits are not set, meaning that FEAT_PMUv3p5/7 is
-	 * not implemented and PMCR_EL0 should be saved in non-secure
-	 * context.
-	 * ----------------------------------------------------------
-	 */
-	mov_imm	x10, (MDCR_SCCD_BIT | MDCR_MCCD_BIT)
-	mrs	x9, mdcr_el3
-	tst	x9, x10
-	bne	1f
-
-	/* ----------------------------------------------------------
-	 * If control reaches here, it ensures the Secure Cycle
-	 * Counter (PMCCNTR_EL0) is not prohibited from counting at
-	 * EL3 and in secure states.
-	 * Henceforth, PMCR_EL0 to be saved before world switch.
-	 * ----------------------------------------------------------
-	 */
+	/* PMUv3 is presumed to be always present */
 	mrs	x9, pmcr_el0
-
-	/* Check caller's security state */
-	mrs	x10, scr_el3
-	tst	x10, #SCR_NS_BIT
-	beq	2f
-
-	/* Save PMCR_EL0 if called from Non-secure state */
 	str	x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
-
 	/* Disable cycle counter when event counting is prohibited */
-2:	orr	x9, x9, #PMCR_EL0_DP_BIT
+	orr	x9, x9, #PMCR_EL0_DP_BIT
 	msr	pmcr_el0, x9
 	isb
-1:
 #if CTX_INCLUDE_PAUTH_REGS
 	/* ----------------------------------------------------------
  	 * Save the ARMv8.3-PAuth keys as they are not banked
@@ -1028,30 +654,9 @@
 	msr	APGAKeyHi_EL1, x9
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
-	/* ----------------------------------------------------------
-	 * Restore PMCR_EL0 when returning to Non-secure state if
-	 * Secure Cycle Counter is not disabled in MDCR_EL3 when
-	 * ARMv8.5-PMU is implemented.
-	 * ----------------------------------------------------------
-	 */
-	mrs	x0, scr_el3
-	tst	x0, #SCR_NS_BIT
-	beq	2f
-
-	/* ----------------------------------------------------------
-	 * Back to Non-secure state.
-	 * Check if earlier initialization MDCR_EL3.SCCD/MCCD to 1
-	 * failed, meaning that FEAT_PMUv3p5/7 is not implemented and
-	 * PMCR_EL0 should be restored from non-secure context.
-	 * ----------------------------------------------------------
-	 */
-	mov_imm	x1, (MDCR_SCCD_BIT | MDCR_MCCD_BIT)
-	mrs	x0, mdcr_el3
-	tst	x0, x1
-	bne	2f
+	/* PMUv3 is presumed to be always present */
 	ldr	x0, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
 	msr	pmcr_el0, x0
-2:
 	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
 	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
@@ -1167,7 +772,12 @@
 1:
 #endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
 
-#if IMAGE_BL31 && RAS_EXTENSION
+/*
+ * This is a hot path, so we don't want to do some actual FEAT_RAS runtime
+ * detection here. The "esb" is a cheaper variant, so using "dsb" in the
+ * ENABLE_FEAT_RAS==2 case is not ideal, but won't hurt.
+ */
+#if IMAGE_BL31 && ENABLE_FEAT_RAS == 1
 	/* ----------------------------------------------------------
 	 * Issue Error Synchronization Barrier to synchronize SErrors
 	 * before exiting EL3. We're running with EAs unmasked, so
@@ -1178,7 +788,7 @@
 	esb
 #else
 	dsb	sy
-#endif /* IMAGE_BL31 && RAS_EXTENSION */
+#endif /* IMAGE_BL31 && ENABLE_FEAT_RAS */
 
 	/* ----------------------------------------------------------
 	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 507a8ce..4a6598a 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -24,6 +24,7 @@
 #include <lib/extensions/amu.h>
 #include <lib/extensions/brbe.h>
 #include <lib/extensions/mpam.h>
+#include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
@@ -37,6 +38,7 @@
 CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
 #endif /* ENABLE_FEAT_TWED */
 
+static void manage_extensions_nonsecure(cpu_context_t *ctx);
 static void manage_extensions_secure(cpu_context_t *ctx);
 
 static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
@@ -134,7 +136,7 @@
 #endif /* CTX_INCLUDE_MTE_REGS */
 
 	/* Enable S-EL2 if the next EL is EL2 and S-EL2 is present */
-	if ((GET_EL(ep->spsr) == MODE_EL2) && is_armv8_4_sel2_present()) {
+	if ((GET_EL(ep->spsr) == MODE_EL2) && is_feat_sel2_supported()) {
 		if (GET_RW(ep->spsr) != MODE_RW_64) {
 			ERROR("S-EL2 can not be used in AArch32\n.");
 			panic();
@@ -171,10 +173,10 @@
 
 	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
 
-#if ENABLE_FEAT_CSV2_2
-	/* Enable access to the SCXTNUM_ELx registers. */
-	scr_el3 |= SCR_EnSCXT_BIT;
-#endif
+	if (is_feat_csv2_2_supported()) {
+		/* Enable access to the SCXTNUM_ELx registers. */
+		scr_el3 |= SCR_EnSCXT_BIT;
+	}
 
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 }
@@ -227,10 +229,10 @@
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
-#if ENABLE_FEAT_CSV2_2
-	/* Enable access to the SCXTNUM_ELx registers. */
-	scr_el3 |= SCR_EnSCXT_BIT;
-#endif
+	if (is_feat_csv2_2_supported()) {
+		/* Enable access to the SCXTNUM_ELx registers. */
+		scr_el3 |= SCR_EnSCXT_BIT;
+	}
 
 #ifdef IMAGE_BL31
 	/*
@@ -265,16 +267,21 @@
 	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
 			icc_sre_el2);
 
-	/*
-	 * Initialize MDCR_EL2.HPMN to its hardware reset value so we don't
-	 * throw anyone off who expects this to be sensible.
-	 * TODO: A similar thing happens in cm_prepare_el3_exit. They should be
-	 * unified with the proper PMU implementation
-	 */
-	u_register_t mdcr_el2 = ((read_pmcr_el0() >> PMCR_EL0_N_SHIFT) &
-			PMCR_EL0_N_MASK);
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
+	if (is_feat_hcx_supported()) {
+		/*
+		 * Initialize register HCRX_EL2 with its init value.
+		 * As the value of HCRX_EL2 is UNKNOWN on reset, there is a
+		 * chance that this can lead to unexpected behavior in lower
+		 * ELs that have not been updated since the introduction of
+		 * this feature if not properly initialized, especially when
+		 * it comes to those bits that enable/disable traps.
+		 */
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
+			HCRX_EL2_INIT_VAL);
+	}
 #endif /* CTX_INCLUDE_EL2_REGS */
+
+	manage_extensions_nonsecure(ctx);
 }
 
 /*******************************************************************************
@@ -355,6 +362,21 @@
 	}
 
 	/*
+	 * SCR_EL3.PIEN: Enable permission indirection and overlay
+	 * registers for AArch64 if present.
+	 */
+	if (is_feat_sxpie_supported() || is_feat_sxpoe_supported()) {
+		scr_el3 |= SCR_PIEN_BIT;
+	}
+
+	/*
+	 * SCR_EL3.GCSEn: Enable GCS registers for AArch64 if present.
+	 */
+	if ((is_feat_gcs_supported()) && (GET_RW(ep->spsr) == MODE_RW_64)) {
+		scr_el3 |= SCR_GCSEn_BIT;
+	}
+
+	/*
 	 * CPTR_EL3 was initialized out of reset, copy that value to the
 	 * context register.
 	 */
@@ -380,22 +402,21 @@
 			scr_el3 |= SCR_FGTEN_BIT;
 		}
 
-		if (get_armv8_6_ecv_support()
-		    == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) {
+		if (is_feat_ecv_supported()) {
 			scr_el3 |= SCR_ECVEN_BIT;
 		}
 	}
 
-#if ENABLE_FEAT_TWED
 	/* Enable WFE trap delay in SCR_EL3 if supported and configured */
-	/* Set delay in SCR_EL3 */
-	scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
-	scr_el3 |= ((TWED_DELAY & SCR_TWEDEL_MASK)
-			<< SCR_TWEDEL_SHIFT);
+	if (is_feat_twed_supported()) {
+		/* Set delay in SCR_EL3 */
+		scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+		scr_el3 |= ((TWED_DELAY & SCR_TWEDEL_MASK)
+				<< SCR_TWEDEL_SHIFT);
 
-	/* Enable WFE delay */
-	scr_el3 |= SCR_TWEDEn_BIT;
-#endif /* ENABLE_FEAT_TWED */
+		/* Enable WFE delay */
+		scr_el3 |= SCR_TWEDEn_BIT;
+	}
 
 	/*
 	 * Populate EL3 state so that we've the right context
@@ -430,7 +451,7 @@
 void __init cm_init(void)
 {
 	/*
-	 * The context management library has only global data to intialize, but
+	 * The context management library has only global data to initialize, but
 	 * that will be done when the BSS is zeroed out.
 	 */
 }
@@ -477,30 +498,33 @@
 /*******************************************************************************
  * Enable architecture extensions on first entry to Non-secure world.
  * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
- * it is zero.
+ * it is zero. This function updates some registers in-place and its contents
+ * are being prepared to be moved to cm_manage_extensions_el3 and
+ * cm_manage_extensions_nonsecure.
  ******************************************************************************/
-static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
+static void manage_extensions_nonsecure_mixed(bool el2_unused, cpu_context_t *ctx)
 {
 #if IMAGE_BL31
-#if ENABLE_SPE_FOR_LOWER_ELS
-	spe_enable(el2_unused);
-#endif
+	if (is_feat_spe_supported()) {
+		spe_enable(el2_unused);
+	}
 
-#if ENABLE_AMU
-	amu_enable(el2_unused, ctx);
-#endif
+	if (is_feat_amu_supported()) {
+		amu_enable(el2_unused, ctx);
+	}
 
-#if ENABLE_SME_FOR_NS
-	/* Enable SME, SVE, and FPU/SIMD for non-secure world. */
-	sme_enable(ctx);
-#elif ENABLE_SVE_FOR_NS
-	/* Enable SVE and FPU/SIMD for non-secure world. */
-	sve_enable(ctx);
-#endif
+	/* Enable SVE and FPU/SIMD */
+	if (is_feat_sve_supported()) {
+		sve_enable(ctx);
+	}
 
-#if ENABLE_MPAM_FOR_LOWER_ELS
-	mpam_enable(el2_unused);
-#endif
+	if (is_feat_sme_supported()) {
+		sme_enable(ctx);
+	}
+
+	if (is_feat_mpam_supported()) {
+		mpam_enable(el2_unused);
+	}
 
 	if (is_feat_trbe_supported()) {
 		trbe_enable();
@@ -510,51 +534,87 @@
 		brbe_enable();
 	}
 
-#if ENABLE_SYS_REG_TRACE_FOR_NS
-	sys_reg_trace_enable(ctx);
-#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+	if (is_feat_sys_reg_trace_supported()) {
+		sys_reg_trace_enable(ctx);
+	}
 
 	if (is_feat_trf_supported()) {
 		trf_enable();
 	}
 #endif
 }
+
+/*******************************************************************************
+ * Enable architecture extensions for EL3 execution. This function only updates
+ * registers in-place which are expected to either never change or be
+ * overwritten by el3_exit.
+ ******************************************************************************/
+#if IMAGE_BL31
+void cm_manage_extensions_el3(void)
+{
+	pmuv3_disable_el3();
+}
+#endif /* IMAGE_BL31 */
 
 /*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world.
+ ******************************************************************************/
+static void manage_extensions_nonsecure(cpu_context_t *ctx)
+{
+#if IMAGE_BL31
+	pmuv3_enable(ctx);
+#endif /* IMAGE_BL31 */
+}
+
+/*******************************************************************************
+ * Enable architecture extensions in-place at EL2 on first entry to Non-secure
+ * world when EL2 is empty and unused.
+ ******************************************************************************/
+static void manage_extensions_nonsecure_el2_unused(void)
+{
+#if IMAGE_BL31
+	pmuv3_init_el2_unused();
+#endif /* IMAGE_BL31 */
+}
+
+/*******************************************************************************
  * Enable architecture extensions on first entry to Secure world.
  ******************************************************************************/
 static void manage_extensions_secure(cpu_context_t *ctx)
 {
 #if IMAGE_BL31
- #if ENABLE_SME_FOR_NS
-  #if ENABLE_SME_FOR_SWD
-	/*
-	 * Enable SME, SVE, FPU/SIMD in secure context, secure manager must
-	 * ensure SME, SVE, and FPU/SIMD context properly managed.
-	 */
-	sme_enable(ctx);
-  #else /* ENABLE_SME_FOR_SWD */
-	/*
-	 * Disable SME, SVE, FPU/SIMD in secure context so non-secure world can
-	 * safely use the associated registers.
-	 */
-	sme_disable(ctx);
-  #endif /* ENABLE_SME_FOR_SWD */
- #elif ENABLE_SVE_FOR_NS
-  #if ENABLE_SVE_FOR_SWD
-	/*
-	 * Enable SVE and FPU in secure context, secure manager must ensure that
-	 * the SVE and FPU register contexts are properly managed.
-	 */
-	sve_enable(ctx);
- #else /* ENABLE_SVE_FOR_SWD */
-	/*
-	 * Disable SVE and FPU in secure context so non-secure world can safely
-	 * use them.
-	 */
-	sve_disable(ctx);
-  #endif /* ENABLE_SVE_FOR_SWD */
- #endif /* ENABLE_SVE_FOR_NS */
+	if (is_feat_sve_supported()) {
+		if (ENABLE_SVE_FOR_SWD) {
+		/*
+		 * Enable SVE and FPU in secure context, secure manager must
+		 * ensure that the SVE and FPU register contexts are properly
+		 * managed.
+		 */
+			sve_enable(ctx);
+		} else {
+		/*
+		 * Disable SVE and FPU in secure context so non-secure world
+		 * can safely use them.
+		 */
+			sve_disable(ctx);
+		}
+	}
+
+	if (is_feat_sme_supported()) {
+		if (ENABLE_SME_FOR_SWD) {
+		/*
+		 * Enable SME, SVE, FPU/SIMD in secure context, secure manager
+		 * must ensure SME, SVE, and FPU/SIMD context properly managed.
+		 */
+			sme_enable(ctx);
+		} else {
+		/*
+		 * Disable SME, SVE, FPU/SIMD in secure context so non-secure
+		 * world can safely use the associated registers.
+		 */
+			sme_disable(ctx);
+		}
+	}
 #endif /* IMAGE_BL31 */
 }
 
@@ -602,8 +662,22 @@
 	assert(ctx != NULL);
 
 	if (security_state == NON_SECURE) {
+		uint64_t el2_implemented = el_implemented(2);
+
 		scr_el3 = read_ctx_reg(get_el3state_ctx(ctx),
 						 CTX_SCR_EL3);
+
+		if (((scr_el3 & SCR_HCE_BIT) != 0U)
+			|| (el2_implemented != EL_IMPL_NONE)) {
+			/*
+			 * If context is not being used for EL2, initialize
+			 * HCRX_EL2 with its init value here.
+			 */
+			if (is_feat_hcx_supported()) {
+				write_hcrx_el2(HCRX_EL2_INIT_VAL);
+			}
+		}
+
 		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
 			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
 			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
@@ -619,7 +693,7 @@
 			sctlr_elx |= SCTLR_IESB_BIT;
 #endif
 			write_sctlr_el2(sctlr_elx);
-		} else if (el_implemented(2) != EL_IMPL_NONE) {
+		} else if (el2_implemented != EL_IMPL_NONE) {
 			el2_unused = true;
 
 			/*
@@ -713,24 +787,11 @@
 			 * relying on hw. Some fields are architecturally
 			 * UNKNOWN on reset.
 			 *
-			 * MDCR_EL2.HLP: Set to one so that event counter
-			 *  overflow, that is recorded in PMOVSCLR_EL0[0-30],
-			 *  occurs on the increment that changes
-			 *  PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU is
-			 *  implemented. This bit is RES0 in versions of the
-			 *  architecture earlier than ARMv8.5, setting it to 1
-			 *  doesn't have any effect on them.
-			 *
 			 * MDCR_EL2.TTRF: Set to zero so that access to Trace
 			 *  Filter Control register TRFCR_EL1 at EL1 is not
 			 *  trapped to EL2. This bit is RES0 in versions of
 			 *  the architecture earlier than ARMv8.4.
 			 *
-			 * MDCR_EL2.HPMD: Set to one so that event counting is
-			 *  prohibited at EL2. This bit is RES0 in versions of
-			 *  the architecture earlier than ARMv8.1, setting it
-			 *  to 1 doesn't have any effect on them.
-			 *
 			 * MDCR_EL2.TPMS: Set to zero so that accesses to
 			 *  Statistical Profiling control registers from EL1
 			 *  do not trap to EL2. This bit is RES0 when SPE is
@@ -750,35 +811,15 @@
 			 * MDCR_EL2.TDE: Set to zero so that debug exceptions
 			 *  are not routed to EL2.
 			 *
-			 * MDCR_EL2.HPME: Set to zero to disable EL2 Performance
-			 *  Monitors.
-			 *
-			 * MDCR_EL2.TPM: Set to zero so that Non-secure EL0 and
-			 *  EL1 accesses to all Performance Monitors registers
-			 *  are not trapped to EL2.
-			 *
-			 * MDCR_EL2.TPMCR: Set to zero so that Non-secure EL0
-			 *  and EL1 accesses to the PMCR_EL0 or PMCR are not
-			 *  trapped to EL2.
-			 *
-			 * MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the
-			 *  architecturally-defined reset value.
-			 *
 			 * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
 			 *  owning exception level is NS-EL1 and, tracing is
 			 *  prohibited at NS-EL2. These bits are RES0 when
 			 *  FEAT_TRBE is not implemented.
 			 */
-			mdcr_el2 = ((MDCR_EL2_RESET_VAL | MDCR_EL2_HLP |
-				     MDCR_EL2_HPMD) |
-				   ((read_pmcr_el0() & PMCR_EL0_N_BITS)
-				   >> PMCR_EL0_N_SHIFT)) &
-				   ~(MDCR_EL2_TTRF | MDCR_EL2_TPMS |
+			mdcr_el2 = ((MDCR_EL2_RESET_VAL) & ~(MDCR_EL2_TTRF |
 				     MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT |
 				     MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT |
-				     MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT |
-				     MDCR_EL2_TPMCR_BIT |
-				     MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
+				     MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1)));
 
 			write_mdcr_el2(mdcr_el2);
 
@@ -800,8 +841,10 @@
 			 */
 			write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
 						~(CNTHP_CTL_ENABLE_BIT));
+
+			manage_extensions_nonsecure_el2_unused();
 		}
-		manage_extensions_nonsecure(el2_unused, ctx);
+		manage_extensions_nonsecure_mixed(el2_unused, ctx);
 	}
 
 	cm_el1_sysregs_context_restore(security_state);
@@ -834,6 +877,96 @@
 	write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
 }
 
+static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
+{
+	u_register_t mpam_idr = read_mpamidr_el1();
+
+	write_ctx_reg(ctx, CTX_MPAM2_EL2, read_mpam2_el2());
+
+	/*
+	 * The context registers that we intend to save would be part of the
+	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
+	 */
+	if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
+		return;
+	}
+
+	/*
+	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 are always present if
+	 * MPAMIDR_HAS_HCR_BIT == 1.
+	 */
+	write_ctx_reg(ctx, CTX_MPAMHCR_EL2, read_mpamhcr_el2());
+	write_ctx_reg(ctx, CTX_MPAMVPM0_EL2, read_mpamvpm0_el2());
+	write_ctx_reg(ctx, CTX_MPAMVPMV_EL2, read_mpamvpmv_el2());
+
+	/*
+	 * The number of MPAMVPM registers is implementation defined, their
+	 * number is stored in the MPAMIDR_EL1 register.
+	 */
+	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
+	case 7:
+		write_ctx_reg(ctx, CTX_MPAMVPM7_EL2, read_mpamvpm7_el2());
+		__fallthrough;
+	case 6:
+		write_ctx_reg(ctx, CTX_MPAMVPM6_EL2, read_mpamvpm6_el2());
+		__fallthrough;
+	case 5:
+		write_ctx_reg(ctx, CTX_MPAMVPM5_EL2, read_mpamvpm5_el2());
+		__fallthrough;
+	case 4:
+		write_ctx_reg(ctx, CTX_MPAMVPM4_EL2, read_mpamvpm4_el2());
+		__fallthrough;
+	case 3:
+		write_ctx_reg(ctx, CTX_MPAMVPM3_EL2, read_mpamvpm3_el2());
+		__fallthrough;
+	case 2:
+		write_ctx_reg(ctx, CTX_MPAMVPM2_EL2, read_mpamvpm2_el2());
+		__fallthrough;
+	case 1:
+		write_ctx_reg(ctx, CTX_MPAMVPM1_EL2, read_mpamvpm1_el2());
+		break;
+	}
+}
+
+static void el2_sysregs_context_restore_mpam(el2_sysregs_t *ctx)
+{
+	u_register_t mpam_idr = read_mpamidr_el1();
+
+	write_mpam2_el2(read_ctx_reg(ctx, CTX_MPAM2_EL2));
+
+	if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
+		return;
+	}
+
+	write_mpamhcr_el2(read_ctx_reg(ctx, CTX_MPAMHCR_EL2));
+	write_mpamvpm0_el2(read_ctx_reg(ctx, CTX_MPAMVPM0_EL2));
+	write_mpamvpmv_el2(read_ctx_reg(ctx, CTX_MPAMVPMV_EL2));
+
+	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
+	case 7:
+		write_mpamvpm7_el2(read_ctx_reg(ctx, CTX_MPAMVPM7_EL2));
+		__fallthrough;
+	case 6:
+		write_mpamvpm6_el2(read_ctx_reg(ctx, CTX_MPAMVPM6_EL2));
+		__fallthrough;
+	case 5:
+		write_mpamvpm5_el2(read_ctx_reg(ctx, CTX_MPAMVPM5_EL2));
+		__fallthrough;
+	case 4:
+		write_mpamvpm4_el2(read_ctx_reg(ctx, CTX_MPAMVPM4_EL2));
+		__fallthrough;
+	case 3:
+		write_mpamvpm3_el2(read_ctx_reg(ctx, CTX_MPAMVPM3_EL2));
+		__fallthrough;
+	case 2:
+		write_mpamvpm2_el2(read_ctx_reg(ctx, CTX_MPAMVPM2_EL2));
+		__fallthrough;
+	case 1:
+		write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
+		break;
+	}
+}
+
 /*******************************************************************************
  * Save EL2 sysreg context
  ******************************************************************************/
@@ -856,44 +989,70 @@
 		el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 		el2_sysregs_context_save_common(el2_sysregs_ctx);
-#if ENABLE_SPE_FOR_LOWER_ELS
-		el2_sysregs_context_save_spe(el2_sysregs_ctx);
-#endif
 #if CTX_INCLUDE_MTE_REGS
 		el2_sysregs_context_save_mte(el2_sysregs_ctx);
 #endif
-#if ENABLE_MPAM_FOR_LOWER_ELS
-		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
-#endif
+		if (is_feat_mpam_supported()) {
+			el2_sysregs_context_save_mpam(el2_sysregs_ctx);
+		}
 
 		if (is_feat_fgt_supported()) {
 			el2_sysregs_context_save_fgt(el2_sysregs_ctx);
 		}
 
-#if ENABLE_FEAT_ECV
-		el2_sysregs_context_save_ecv(el2_sysregs_ctx);
-#endif
-#if ENABLE_FEAT_VHE
-		el2_sysregs_context_save_vhe(el2_sysregs_ctx);
-#endif
-#if RAS_EXTENSION
-		el2_sysregs_context_save_ras(el2_sysregs_ctx);
-#endif
-#if CTX_INCLUDE_NEVE_REGS
-		el2_sysregs_context_save_nv2(el2_sysregs_ctx);
-#endif
+		if (is_feat_ecv_v2_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2,
+				      read_cntpoff_el2());
+		}
+
+		if (is_feat_vhe_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2,
+				      read_contextidr_el2());
+			write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2,
+				      read_ttbr1_el2());
+		}
+
+		if (is_feat_ras_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2,
+				      read_vdisr_el2());
+			write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2,
+				      read_vsesr_el2());
+		}
+
+		if (is_feat_nv2_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2,
+				      read_vncr_el2());
+		}
+
 		if (is_feat_trf_supported()) {
 			write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
 		}
-#if ENABLE_FEAT_CSV2_2
-		el2_sysregs_context_save_csv2(el2_sysregs_ctx);
-#endif
+
+		if (is_feat_csv2_2_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2,
+				      read_scxtnum_el2());
+		}
+
 		if (is_feat_hcx_supported()) {
 			write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
 		}
 		if (is_feat_tcr2_supported()) {
 			write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
 		}
+		if (is_feat_sxpie_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
+			write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
+		}
+		if (is_feat_s2pie_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
+		}
+		if (is_feat_sxpoe_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+		}
+		if (is_feat_gcs_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
+			write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
+		}
 	}
 }
 
@@ -919,44 +1078,64 @@
 		el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 		el2_sysregs_context_restore_common(el2_sysregs_ctx);
-#if ENABLE_SPE_FOR_LOWER_ELS
-		el2_sysregs_context_restore_spe(el2_sysregs_ctx);
-#endif
 #if CTX_INCLUDE_MTE_REGS
 		el2_sysregs_context_restore_mte(el2_sysregs_ctx);
 #endif
-#if ENABLE_MPAM_FOR_LOWER_ELS
-		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
-#endif
+		if (is_feat_mpam_supported()) {
+			el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
+		}
 
 		if (is_feat_fgt_supported()) {
 			el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
 		}
 
-#if ENABLE_FEAT_ECV
-		el2_sysregs_context_restore_ecv(el2_sysregs_ctx);
-#endif
-#if ENABLE_FEAT_VHE
-		el2_sysregs_context_restore_vhe(el2_sysregs_ctx);
-#endif
-#if RAS_EXTENSION
-		el2_sysregs_context_restore_ras(el2_sysregs_ctx);
-#endif
-#if CTX_INCLUDE_NEVE_REGS
-		el2_sysregs_context_restore_nv2(el2_sysregs_ctx);
-#endif
+		if (is_feat_ecv_v2_supported()) {
+			write_cntpoff_el2(read_ctx_reg(el2_sysregs_ctx,
+						       CTX_CNTPOFF_EL2));
+		}
+
+		if (is_feat_vhe_supported()) {
+			write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
+			write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
+		}
+
+		if (is_feat_ras_supported()) {
+			write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
+			write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
+		}
+
+		if (is_feat_nv2_supported()) {
+			write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));
+		}
 		if (is_feat_trf_supported()) {
 			write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
 		}
-#if ENABLE_FEAT_CSV2_2
-		el2_sysregs_context_restore_csv2(el2_sysregs_ctx);
-#endif
+
+		if (is_feat_csv2_2_supported()) {
+			write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx,
+						       CTX_SCXTNUM_EL2));
+		}
+
 		if (is_feat_hcx_supported()) {
 			write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
 		}
 		if (is_feat_tcr2_supported()) {
 			write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
 		}
+		if (is_feat_sxpie_supported()) {
+			write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
+			write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
+		}
+		if (is_feat_s2pie_supported()) {
+			write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+		}
+		if (is_feat_sxpoe_supported()) {
+			write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+		}
+		if (is_feat_gcs_supported()) {
+			write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
+			write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
+		}
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
@@ -986,7 +1165,7 @@
 	 * direct register updates. Therefore, do this here
 	 * instead of when setting up context.
 	 */
-	manage_extensions_nonsecure(0, ctx);
+	manage_extensions_nonsecure_mixed(0, ctx);
 
 	/*
 	 * Set the NS bit to be able to access the ICC_SRE_EL2
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
index 57b1158..03186d6 100644
--- a/lib/extensions/amu/aarch32/amu.c
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -10,6 +10,7 @@
 
 #include "../amu_private.h"
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/el3_runtime/pubsub_events.h>
@@ -39,12 +40,6 @@
 	amu_ctx_group1_enable_cannot_represent_all_group1_counters);
 #endif
 
-static inline __unused uint32_t read_id_pfr0_amu(void)
-{
-	return (read_id_pfr0() >> ID_PFR0_AMU_SHIFT) &
-		ID_PFR0_AMU_MASK;
-}
-
 static inline __unused void write_hcptr_tam(uint32_t value)
 {
 	write_hcptr((read_hcptr() & ~TAM_BIT) |
@@ -129,11 +124,6 @@
 	write_amcntenclr1(value);
 }
 
-static __unused bool amu_supported(void)
-{
-	return read_id_pfr0_amu() >= ID_PFR0_AMU_V1;
-}
-
 #if ENABLE_AMU_AUXILIARY_COUNTERS
 static __unused bool amu_group1_supported(void)
 {
@@ -147,23 +137,12 @@
  */
 void amu_enable(bool el2_unused)
 {
-	uint32_t id_pfr0_amu;		/* AMU version */
-
 	uint32_t amcfgr_ncg;		/* Number of counter groups */
 	uint32_t amcgcr_cg0nc;		/* Number of group 0 counters */
 
 	uint32_t amcntenset0_px = 0x0;	/* Group 0 enable mask */
 	uint32_t amcntenset1_px = 0x0;	/* Group 1 enable mask */
 
-	id_pfr0_amu = read_id_pfr0_amu();
-	if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) {
-		/*
-		 * If the AMU is unsupported, nothing needs to be done.
-		 */
-
-		return;
-	}
-
 	if (el2_unused) {
 		/*
 		 * HCPTR.TAM: Set to zero so any accesses to the Activity
@@ -221,8 +200,8 @@
 #endif
 	}
 
-	/* Initialize FEAT_AMUv1p1 features if present. */
-	if (id_pfr0_amu < ID_PFR0_AMU_V1P1) {
+	/* Bail out if FEAT_AMUv1p1 features are not present. */
+	if (!is_feat_amuv1p1_supported()) {
 		return;
 	}
 
@@ -244,7 +223,7 @@
 /* Read the group 0 counter identified by the given `idx`. */
 static uint64_t amu_group0_cnt_read(unsigned int idx)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(idx < read_amcgcr_cg0nc());
 
 	return amu_group0_cnt_read_internal(idx);
@@ -253,7 +232,7 @@
 /* Write the group 0 counter identified by the given `idx` with `val` */
 static void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(idx < read_amcgcr_cg0nc());
 
 	amu_group0_cnt_write_internal(idx, val);
@@ -264,7 +243,7 @@
 /* Read the group 1 counter identified by the given `idx` */
 static uint64_t amu_group1_cnt_read(unsigned  int idx)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(amu_group1_supported());
 	assert(idx < read_amcgcr_cg1nc());
 
@@ -274,7 +253,7 @@
 /* Write the group 1 counter identified by the given `idx` with `val` */
 static void amu_group1_cnt_write(unsigned  int idx, uint64_t val)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(amu_group1_supported());
 	assert(idx < read_amcgcr_cg1nc());
 
@@ -290,7 +269,6 @@
 	unsigned int core_pos;
 	struct amu_ctx *ctx;
 
-	uint32_t id_pfr0_amu;	/* AMU version */
 	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
@@ -298,8 +276,7 @@
 	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
 #endif
 
-	id_pfr0_amu = read_id_pfr0_amu();
-	if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) {
+	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
@@ -353,8 +330,6 @@
 	unsigned int core_pos;
 	struct amu_ctx *ctx;
 
-	uint32_t id_pfr0_amu;	/* AMU version */
-
 	uint32_t amcfgr_ncg;	/* Number of counter groups */
 	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
 
@@ -362,8 +337,7 @@
 	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
 #endif
 
-	id_pfr0_amu = read_id_pfr0_amu();
-	if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) {
+	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index 72566fd..c650629 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -57,12 +57,6 @@
 	amu_ctx_group1_enable_cannot_represent_all_group1_counters);
 #endif
 
-static inline __unused uint64_t read_id_aa64pfr0_el1_amu(void)
-{
-	return (read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
-		ID_AA64PFR0_AMU_MASK;
-}
-
 static inline __unused uint64_t read_hcr_el2_amvoffen(void)
 {
 	return (read_hcr_el2() & HCR_AMVOFFEN_BIT) >>
@@ -183,16 +177,6 @@
 	write_amcntenclr1_el0(value);
 }
 
-static __unused bool amu_supported(void)
-{
-	return read_id_aa64pfr0_el1_amu() >= ID_AA64PFR0_AMU_V1;
-}
-
-static __unused bool amu_v1p1_supported(void)
-{
-	return read_id_aa64pfr0_el1_amu() >= ID_AA64PFR0_AMU_V1P1;
-}
-
 #if ENABLE_AMU_AUXILIARY_COUNTERS
 static __unused bool amu_group1_supported(void)
 {
@@ -206,23 +190,12 @@
  */
 void amu_enable(bool el2_unused, cpu_context_t *ctx)
 {
-	uint64_t id_aa64pfr0_el1_amu;		/* AMU version */
-
 	uint64_t amcfgr_el0_ncg;		/* Number of counter groups */
 	uint64_t amcgcr_el0_cg0nc;		/* Number of group 0 counters */
 
 	uint64_t amcntenset0_el0_px = 0x0;	/* Group 0 enable mask */
 	uint64_t amcntenset1_el0_px = 0x0;	/* Group 1 enable mask */
 
-	id_aa64pfr0_el1_amu = read_id_aa64pfr0_el1_amu();
-	if (id_aa64pfr0_el1_amu == ID_AA64PFR0_AMU_NOT_SUPPORTED) {
-		/*
-		 * If the AMU is unsupported, nothing needs to be done.
-		 */
-
-		return;
-	}
-
 	if (el2_unused) {
 		/*
 		 * CPTR_EL2.TAM: Set to zero so any accesses to the Activity
@@ -288,7 +261,7 @@
 	}
 
 	/* Initialize FEAT_AMUv1p1 features if present. */
-	if (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) {
+	if (is_feat_amuv1p1_supported()) {
 		if (el2_unused) {
 			/*
 			 * Make sure virtual offsets are disabled if EL2 not
@@ -327,7 +300,7 @@
 /* Read the group 0 counter identified by the given `idx`. */
 static uint64_t amu_group0_cnt_read(unsigned int idx)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(idx < read_amcgcr_el0_cg0nc());
 
 	return amu_group0_cnt_read_internal(idx);
@@ -336,7 +309,7 @@
 /* Write the group 0 counter identified by the given `idx` with `val` */
 static void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(idx < read_amcgcr_el0_cg0nc());
 
 	amu_group0_cnt_write_internal(idx, val);
@@ -376,7 +349,7 @@
  */
 static uint64_t amu_group0_voffset_read(unsigned int idx)
 {
-	assert(amu_v1p1_supported());
+	assert(is_feat_amuv1p1_supported());
 	assert(idx < read_amcgcr_el0_cg0nc());
 	assert(idx != 1U);
 
@@ -391,7 +364,7 @@
  */
 static void amu_group0_voffset_write(unsigned int idx, uint64_t val)
 {
-	assert(amu_v1p1_supported());
+	assert(is_feat_amuv1p1_supported());
 	assert(idx < read_amcgcr_el0_cg0nc());
 	assert(idx != 1U);
 
@@ -403,7 +376,7 @@
 /* Read the group 1 counter identified by the given `idx` */
 static uint64_t amu_group1_cnt_read(unsigned int idx)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(amu_group1_supported());
 	assert(idx < read_amcgcr_el0_cg1nc());
 
@@ -413,7 +386,7 @@
 /* Write the group 1 counter identified by the given `idx` with `val` */
 static void amu_group1_cnt_write(unsigned int idx, uint64_t val)
 {
-	assert(amu_supported());
+	assert(is_feat_amu_supported());
 	assert(amu_group1_supported());
 	assert(idx < read_amcgcr_el0_cg1nc());
 
@@ -428,7 +401,7 @@
  */
 static uint64_t amu_group1_voffset_read(unsigned int idx)
 {
-	assert(amu_v1p1_supported());
+	assert(is_feat_amuv1p1_supported());
 	assert(amu_group1_supported());
 	assert(idx < read_amcgcr_el0_cg1nc());
 	assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U);
@@ -443,7 +416,7 @@
  */
 static void amu_group1_voffset_write(unsigned int idx, uint64_t val)
 {
-	assert(amu_v1p1_supported());
+	assert(is_feat_amuv1p1_supported());
 	assert(amu_group1_supported());
 	assert(idx < read_amcgcr_el0_cg1nc());
 	assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U);
@@ -460,8 +433,7 @@
 	unsigned int core_pos;
 	struct amu_ctx *ctx;
 
-	uint64_t id_aa64pfr0_el1_amu;	/* AMU version */
-	uint64_t hcr_el2_amvoffen;	/* AMU virtual offsets enabled */
+	uint64_t hcr_el2_amvoffen = 0;	/* AMU virtual offsets enabled */
 	uint64_t amcgcr_el0_cg0nc;	/* Number of group 0 counters */
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
@@ -470,8 +442,7 @@
 	uint64_t amcgcr_el0_cg1nc;	/* Number of group 1 counters */
 #endif
 
-	id_aa64pfr0_el1_amu = read_id_aa64pfr0_el1_amu();
-	if (id_aa64pfr0_el1_amu == ID_AA64PFR0_AMU_NOT_SUPPORTED) {
+	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
@@ -479,8 +450,9 @@
 	ctx = &amu_ctxs_[core_pos];
 
 	amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc();
-	hcr_el2_amvoffen = (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) ?
-		read_hcr_el2_amvoffen() : 0U;
+	if (is_feat_amuv1p1_supported()) {
+		hcr_el2_amvoffen = read_hcr_el2_amvoffen();
+	}
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
 	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
@@ -552,9 +524,7 @@
 	unsigned int core_pos;
 	struct amu_ctx *ctx;
 
-	uint64_t id_aa64pfr0_el1_amu;	/* AMU version */
-
-	uint64_t hcr_el2_amvoffen;	/* AMU virtual offsets enabled */
+	uint64_t hcr_el2_amvoffen = 0;	/* AMU virtual offsets enabled */
 
 	uint64_t amcfgr_el0_ncg;	/* Number of counter groups */
 	uint64_t amcgcr_el0_cg0nc;	/* Number of group 0 counters */
@@ -564,8 +534,7 @@
 	uint64_t amcg1idr_el0_voff;	/* Auxiliary counters with virtual offsets */
 #endif
 
-	id_aa64pfr0_el1_amu = read_id_aa64pfr0_el1_amu();
-	if (id_aa64pfr0_el1_amu == ID_AA64PFR0_AMU_NOT_SUPPORTED) {
+	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
@@ -575,8 +544,9 @@
 	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
 	amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc();
 
-	hcr_el2_amvoffen = (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) ?
-		read_hcr_el2_amvoffen() : 0U;
+	if (is_feat_amuv1p1_supported()) {
+		hcr_el2_amvoffen = read_hcr_el2_amvoffen();
+	}
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
 	amcgcr_el0_cg1nc = (amcfgr_el0_ncg > 0U) ? read_amcgcr_el0_cg1nc() : 0U;
diff --git a/lib/extensions/amu/amu.mk b/lib/extensions/amu/amu.mk
index 0d203cb..868ab12 100644
--- a/lib/extensions/amu/amu.mk
+++ b/lib/extensions/amu/amu.mk
@@ -10,8 +10,8 @@
 			lib/extensions/amu/${ARCH}/amu_helpers.S
 
 ifneq (${ENABLE_AMU_AUXILIARY_COUNTERS},0)
-        ifeq (${ENABLE_AMU},0)
-                $(error AMU auxiliary counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`) requires AMU support (`ENABLE_AMU`))
+        ifeq (${ENABLE_FEAT_AMU},0)
+                $(error AMU auxiliary counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`) requires AMU support (`ENABLE_FEAT_AMU`))
         endif
 endif
 
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
index 884d480..62533fc 100644
--- a/lib/extensions/mpam/mpam.c
+++ b/lib/extensions/mpam/mpam.c
@@ -13,11 +13,6 @@
 
 void mpam_enable(bool el2_unused)
 {
-	/* Check if MPAM is implemented */
-	if (get_mpam_version() == 0U) {
-		return;
-	}
-
 	/*
 	 * Enable MPAM, and disable trapping to EL3 when lower ELs access their
 	 * own MPAM registers.
diff --git a/lib/extensions/mtpmu/aarch32/mtpmu.S b/lib/extensions/mtpmu/aarch32/mtpmu.S
deleted file mode 100644
index 834cee3..0000000
--- a/lib/extensions/mtpmu/aarch32/mtpmu.S
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-
-	.global	mtpmu_disable
-
-/* -------------------------------------------------------------
- * The functions in this file are called at entrypoint, before
- * the CPU has decided whether this is a cold or a warm boot.
- * Therefore there are no stack yet to rely on for a C function
- * call.
- * -------------------------------------------------------------
- */
-
-/*
- * bool mtpmu_supported(void)
- *
- * Return a boolean indicating whether FEAT_MTPMU is supported or not.
- *
- * Trash registers: r0.
- */
-func mtpmu_supported
-	ldcopr	r0, ID_DFR1
-	and	r0, r0, #(ID_DFR1_MTPMU_MASK >> ID_DFR1_MTPMU_SHIFT)
-	cmp	r0, #ID_DFR1_MTPMU_SUPPORTED
-	mov	r0, #0
-	addeq	r0, r0, #1
-	bx	lr
-endfunc mtpmu_supported
-
-/*
- * bool el_implemented(unsigned int el)
- *
- * Return a boolean indicating if the specified EL (2 or 3) is implemented.
- *
- * Trash registers: r0
- */
-func el_implemented
-	cmp	r0, #3
-	ldcopr	r0, ID_PFR1
-	lsreq	r0, r0, #ID_PFR1_SEC_SHIFT
-	lsrne	r0, r0, #ID_PFR1_VIRTEXT_SHIFT
-	/*
-	 * ID_PFR1_VIRTEXT_MASK is the same as ID_PFR1_SEC_MASK
-	 * so use any one of them
-	 */
-	and	r0, r0, #ID_PFR1_VIRTEXT_MASK
-	cmp	r0, #ID_PFR1_ELx_ENABLED
-	mov	r0, #0
-	addeq	r0, r0, #1
-	bx	lr
-endfunc el_implemented
-
-/*
- * void mtpmu_disable(void)
- *
- * Disable mtpmu feature if supported.
- *
- * Trash register: r0, r1, r2
- */
-func mtpmu_disable
-	mov	r2, lr
-	bl	mtpmu_supported
-	cmp	r0, #0
-	bxeq	r2	/* FEAT_MTPMU not supported */
-
-	/* FEAT_MTMPU Supported */
-	mov	r0, #3
-	bl	el_implemented
-	cmp	r0, #0
-	beq	1f
-
-	/* EL3 implemented */
-	ldcopr	r0, SDCR
-	ldr	r1, =SDCR_MTPME_BIT
-	bic	r0, r0, r1
-	stcopr	r0, SDCR
-
-	/*
-	 * If EL3 is implemented, HDCR.MTPME is implemented as Res0 and
-	 * FEAT_MTPMU is controlled only from EL3, so no need to perform
-	 * any operations for EL2.
-	 */
-	isb
-	bx	r2
-1:
-	/* EL3 not implemented */
-	mov	r0, #2
-	bl	el_implemented
-	cmp	r0, #0
-	bxeq	r2	/* No EL2 or EL3 implemented */
-
-	/* EL2 implemented */
-	ldcopr	r0, HDCR
-	ldr	r1, =HDCR_MTPME_BIT
-	orr	r0, r0, r1
-	stcopr	r0, HDCR
-	isb
-	bx	r2
-endfunc mtpmu_disable
diff --git a/lib/extensions/mtpmu/aarch64/mtpmu.S b/lib/extensions/mtpmu/aarch64/mtpmu.S
deleted file mode 100644
index 0a1d57b..0000000
--- a/lib/extensions/mtpmu/aarch64/mtpmu.S
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-
-	.global	mtpmu_disable
-
-/* -------------------------------------------------------------
- * The functions in this file are called at entrypoint, before
- * the CPU has decided whether this is a cold or a warm boot.
- * Therefore there are no stack yet to rely on for a C function
- * call.
- * -------------------------------------------------------------
- */
-
-/*
- * bool mtpmu_supported(void)
- *
- * Return a boolean indicating whether FEAT_MTPMU is supported or not.
- *
- * Trash registers: x0, x1
- */
-func mtpmu_supported
-	mrs	x0, id_aa64dfr0_el1
-	mov_imm	x1, ID_AA64DFR0_MTPMU_MASK
-	and	x0, x1, x0, LSR #ID_AA64DFR0_MTPMU_SHIFT
-	cmp	x0, ID_AA64DFR0_MTPMU_SUPPORTED
-	cset	x0, eq
-	ret
-endfunc mtpmu_supported
-
-/*
- * bool el_implemented(unsigned int el_shift)
- *
- * Return a boolean indicating if the specified EL is implemented.
- * The EL is represented as the bitmask shift on id_aa64pfr0_el1 register.
- *
- * Trash registers: x0, x1
- */
-func el_implemented
-	mrs	x1, id_aa64pfr0_el1
-	lsr	x1, x1, x0
-	cmp	x1, #ID_AA64PFR0_ELX_MASK
-	cset	x0, eq
-	ret
-endfunc el_implemented
-
-/*
- * void mtpmu_disable(void)
- *
- * Disable mtpmu feature if supported.
- *
- * Trash register: x0, x1, x30
- */
-func mtpmu_disable
-	mov	x10, x30
-	bl	mtpmu_supported
-	cbz	x0, exit_disable
-
-	/* FEAT_MTMPU Supported */
-	mov_imm	x0, ID_AA64PFR0_EL3_SHIFT
-	bl	el_implemented
-	cbz	x0, 1f
-
-	/* EL3 implemented */
-	mrs	x0, mdcr_el3
-	mov_imm x1, MDCR_MTPME_BIT
-	bic	x0, x0, x1
-	msr	mdcr_el3, x0
-
-	/*
-	 * If EL3 is implemented, MDCR_EL2.MTPME is implemented as Res0 and
-	 * FEAT_MTPMU is controlled only from EL3, so no need to perform
-	 * any operations for EL2.
-	 */
-	isb
-exit_disable:
-	ret	x10
-1:
-	/* EL3 not implemented */
-	mov_imm	x0, ID_AA64PFR0_EL2_SHIFT
-	bl	el_implemented
-	cbz	x0, exit_disable
-
-	/* EL2 implemented */
-	mrs	x0, mdcr_el2
-	mov_imm x1, MDCR_EL2_MTPME
-	bic	x0, x0, x1
-	msr	mdcr_el2, x0
-	isb
-	ret	x10
-endfunc mtpmu_disable
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/extensions/pmuv3/aarch32/pmuv3.c b/lib/extensions/pmuv3/aarch32/pmuv3.c
new file mode 100644
index 0000000..fe4205e
--- /dev/null
+++ b/lib/extensions/pmuv3/aarch32/pmuv3.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/pmuv3.h>
+
+static u_register_t mtpmu_disable_el3(u_register_t sdcr)
+{
+	if (!is_feat_mtpmu_supported()) {
+		return sdcr;
+	}
+
+	/*
+	 * SDCR.MTPME = 0
+	 * FEAT_MTPMU is disabled. The Effective value of PMEVTYPER<n>.MT is
+	 * zero.
+	 */
+	sdcr &= ~SDCR_MTPME_BIT;
+
+	return sdcr;
+}
+
+/*
+ * Applies to all PMU versions. Name is PMUv3 for compatibility with aarch64 and
+ * to not clash with platforms which reuse the PMU name
+ */
+void pmuv3_disable_el3(void)
+{
+	u_register_t sdcr = read_sdcr();
+
+	/* ---------------------------------------------------------------------
+	 * Initialise SDCR, setting all the fields rather than relying on hw.
+	 *
+	 * SDCR.SCCD: Set to one so that cycle counting by PMCCNTR is prohibited
+	 *  in Secure state. This bit is RES0 in versions of the architecture
+	 *  earlier than ARMv8.5
+	 *
+	 * SDCR.SPME: Set to zero so that event counting is prohibited in Secure
+	 *  state (and explicitly EL3 with later revisions). If ARMv8.2 Debug is
+	 *  not implemented this bit does not have any effect on the counters
+	 *  unless there is support for the implementation defined
+	 *  authentication interface ExternalSecureNoninvasiveDebugEnabled().
+	 * ---------------------------------------------------------------------
+	 */
+	sdcr = (sdcr | SDCR_SCCD_BIT) & ~SDCR_SPME_BIT;
+	sdcr = mtpmu_disable_el3(sdcr);
+	write_sdcr(sdcr);
+
+	/* ---------------------------------------------------------------------
+	 * Initialise PMCR, setting all fields rather than relying
+	 * on hw. Some fields are architecturally UNKNOWN on reset.
+	 *
+	 * PMCR.DP: Set to one to prohibit cycle counting whilst in Secure mode.
+	 *
+	 * PMCR.X: Set to zero to disable export of events.
+	 *
+	 * PMCR.C: Set to one to reset PMCCNTR.
+	 *
+	 * PMCR.P: Set to one to reset each event counter PMEVCNTR<n> to zero.
+	 *
+	 * PMCR.E: Set to zero to disable cycle and event counters.
+	 * ---------------------------------------------------------------------
+	 */
+
+	write_pmcr(read_pmcr() | PMCR_DP_BIT | PMCR_C_BIT | PMCR_P_BIT |
+		 ~(PMCR_X_BIT | PMCR_E_BIT));
+}
diff --git a/lib/extensions/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
new file mode 100644
index 0000000..f83a5ee
--- /dev/null
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/pmuv3.h>
+
+static u_register_t init_mdcr_el2_hpmn(u_register_t mdcr_el2)
+{
+	/*
+	 * Initialize MDCR_EL2.HPMN to its hardware reset value so we don't
+	 * throw anyone off who expects this to be sensible.
+	 */
+	mdcr_el2 &= ~MDCR_EL2_HPMN_MASK;
+	mdcr_el2 |= ((read_pmcr_el0() >> PMCR_EL0_N_SHIFT) & PMCR_EL0_N_MASK);
+
+	return mdcr_el2;
+}
+
+void pmuv3_enable(cpu_context_t *ctx)
+{
+#if CTX_INCLUDE_EL2_REGS
+	u_register_t mdcr_el2;
+
+	mdcr_el2 = read_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2);
+	mdcr_el2 = init_mdcr_el2_hpmn(mdcr_el2);
+	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
+#endif /* CTX_INCLUDE_EL2_REGS */
+}
+
+static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
+{
+	if (!is_feat_mtpmu_supported()) {
+		return mdcr_el3;
+	}
+
+	/*
+	 * MDCR_EL3.MTPME = 0
+	 * FEAT_MTPMU is disabled. The Effective value of PMEVTYPER<n>_EL0.MT is
+	 * zero.
+	 */
+	mdcr_el3 &= ~MDCR_MTPME_BIT;
+
+	return mdcr_el3;
+}
+
+void pmuv3_disable_el3(void)
+{
+	u_register_t mdcr_el3 = read_mdcr_el3();
+
+	/* ---------------------------------------------------------------------
+	 * Initialise MDCR_EL3, setting all fields rather than relying on hw.
+	 * Some fields are architecturally UNKNOWN on reset.
+	 *
+	 * MDCR_EL3.MPMX: Set to zero to not affect event counters (when
+	 * SPME = 0).
+	 *
+	 * MDCR_EL3.MCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
+	 *  prohibited in EL3. This bit is RES0 in versions of the
+	 *  architecture with FEAT_PMUv3p7 not implemented.
+	 *
+	 * MDCR_EL3.SCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
+	 *  prohibited in Secure state. This bit is RES0 in versions of the
+	 *  architecture with FEAT_PMUv3p5 not implemented.
+	 *
+	 * MDCR_EL3.SPME: Set to zero so that event counting is prohibited in
+	 *  Secure state (and explicitly EL3 with later revisions). If ARMv8.2
+	 *  Debug is not implemented this bit does not have any effect on the
+	 *  counters unless there is support for the implementation defined
+	 *  authentication interface ExternalSecureNoninvasiveDebugEnabled().
+	 *
+	 * The SPME/MPMX combination is a little tricky. Below is a small
+	 * summary if another combination is ever needed:
+	 * SPME | MPMX | secure world |   EL3
+	 * -------------------------------------
+	 *   0  |  0   |    disabled  | disabled
+	 *   1  |  0   |    enabled   | enabled
+	 *   0  |  1   |    enabled   | disabled
+	 *   1  |  1   |    enabled   | disabled only for counters 0 to
+	 *                              MDCR_EL2.HPMN - 1. Enabled for the rest
+	 */
+	mdcr_el3 = (mdcr_el3 | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
+		  ~(MDCR_MPMX_BIT | MDCR_SPME_BIT);
+	mdcr_el3 = mtpmu_disable_el3(mdcr_el3);
+	write_mdcr_el3(mdcr_el3);
+
+	/* ---------------------------------------------------------------------
+	 * Initialise PMCR_EL0 setting all fields rather than relying
+	 * on hw. Some fields are architecturally UNKNOWN on reset.
+	 *
+	 * PMCR_EL0.DP: Set to one so that the cycle counter,
+	 *  PMCCNTR_EL0 does not count when event counting is prohibited.
+	 *  Necessary on PMUv3 <= p7 where MDCR_EL3.{SCCD,MCCD} are not
+	 *  available
+	 *
+	 * PMCR_EL0.X: Set to zero to disable export of events.
+	 *
+	 * PMCR_EL0.C: Set to one to reset PMCCNTR_EL0 to zero.
+	 *
+	 * PMCR_EL0.P: Set to one to reset each event counter PMEVCNTR<n>_EL0 to
+	 *  zero.
+	 *
+	 * PMCR_EL0.E: Set to zero to disable cycle and event counters.
+	 * ---------------------------------------------------------------------
+	 */
+	write_pmcr_el0((read_pmcr_el0() | PMCR_EL0_DP_BIT | PMCR_EL0_C_BIT |
+			PMCR_EL0_P_BIT) & ~(PMCR_EL0_X_BIT | PMCR_EL0_E_BIT));
+}
+
+static u_register_t mtpmu_disable_el2(u_register_t mdcr_el2)
+{
+	if (!is_feat_mtpmu_supported()) {
+		return mdcr_el2;
+	}
+
+	/*
+	 * MDCR_EL2.MTPME = 0
+	 * FEAT_MTPMU is disabled. The Effective value of PMEVTYPER<n>_EL0.MT is
+	 * zero.
+	 */
+	mdcr_el2 &= ~MDCR_EL2_MTPME;
+
+	return mdcr_el2;
+}
+
+void pmuv3_init_el2_unused(void)
+{
+	u_register_t mdcr_el2 = read_mdcr_el2();
+
+	/*
+	 * Initialise MDCR_EL2, setting all fields rather than
+	 * relying on hw. Some fields are architecturally
+	 * UNKNOWN on reset.
+	 *
+	 * MDCR_EL2.HLP: Set to one so that event counter overflow, that is
+	 *  recorded in PMOVSCLR_EL0[0-30], occurs on the increment that changes
+	 *  PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU is implemented.
+	 *  This bit is RES0 in versions of the architecture earlier than
+	 *  ARMv8.5, setting it to 1 doesn't have any effect on them.
+	 *
+	 * MDCR_EL2.HCCD: Set to one to prohibit cycle counting at EL2. This bit
+	 *  is RES0 in versions of the architecture with FEAT_PMUv3p5 not
+	 *  implemented.
+	 *
+	 * MDCR_EL2.HPMD: Set to one so that event counting is
+	 *  prohibited at EL2 for counter n < MDCR_EL2.HPMN. This bit  is RES0
+	 *  in versions of the architecture with FEAT_PMUv3p1 not implemented.
+	 *
+	 * MDCR_EL2.HPME: Set to zero to disable event counters for counters
+	 *  n >= MDCR_EL2.HPMN.
+	 *
+	 * MDCR_EL2.TPM: Set to zero so that Non-secure EL0 and
+	 *  EL1 accesses to all Performance Monitors registers
+	 *  are not trapped to EL2.
+	 *
+	 * MDCR_EL2.TPMCR: Set to zero so that Non-secure EL0
+	 *  and EL1 accesses to the PMCR_EL0 or PMCR are not
+	 *  trapped to EL2.
+	 */
+	mdcr_el2 = (mdcr_el2 | MDCR_EL2_HLP_BIT | MDCR_EL2_HPMD_BIT |
+		    MDCR_EL2_HCCD_BIT) &
+		  ~(MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT | MDCR_EL2_TPMCR_BIT);
+	mdcr_el2 = init_mdcr_el2_hpmn(mdcr_el2);
+	mdcr_el2 = mtpmu_disable_el2(mdcr_el2);
+	write_mdcr_el2(mdcr_el2);
+}
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index ec8cca8..3423dba 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,41 +7,19 @@
 #include <stdbool.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/sve.h>
 
-static bool feat_sme_supported(void)
-{
-	uint64_t features;
-
-	features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
-	return (features & ID_AA64PFR1_EL1_SME_MASK) != 0U;
-}
-
-static bool feat_sme_fa64_supported(void)
-{
-	uint64_t features;
-
-	features = read_id_aa64smfr0_el1();
-	return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U;
-}
-
 void sme_enable(cpu_context_t *context)
 {
 	u_register_t reg;
 	u_register_t cptr_el3;
 	el3_state_t *state;
 
-	/* Make sure SME is implemented in hardware before continuing. */
-	if (!feat_sme_supported()) {
-		/* Perhaps the hardware supports SVE only */
-		sve_enable(context);
-		return;
-	}
-
 	/* Get the context state. */
 	state = get_el3state_ctx(context);
 
@@ -65,19 +43,28 @@
 	 * to be the least restrictive, then lower ELs can restrict as needed
 	 * using SMCR_EL2 and SMCR_EL1.
 	 */
-	reg = SMCR_ELX_LEN_MASK;
-	if (feat_sme_fa64_supported()) {
+	reg = SMCR_ELX_LEN_MAX;
+
+	if (read_feat_sme_fa64_id_field() != 0U) {
 		VERBOSE("[SME] FA64 enabled\n");
 		reg |= SMCR_ELX_FA64_BIT;
 	}
+
+	/*
+	 * Enable access to ZT0 register.
+	 * Make sure FEAT_SME2 is supported by the hardware before continuing.
+	 * If supported, Set the EZT0 bit in SMCR_EL3 to allow instructions to
+	 * access ZT0 register without trapping.
+	 */
+	if (is_feat_sme2_supported()) {
+		VERBOSE("SME2 enabled\n");
+		reg |= SMCR_ELX_EZT0_BIT;
+	}
 	write_smcr_el3(reg);
 
 	/* Reset CPTR_EL3 value. */
 	write_cptr_el3(cptr_el3);
 	isb();
-
-	/* Enable SVE/FPU in addition to SME. */
-	sve_enable(context);
 }
 
 void sme_disable(cpu_context_t *context)
@@ -85,13 +72,6 @@
 	u_register_t reg;
 	el3_state_t *state;
 
-	/* Make sure SME is implemented in hardware before continuing. */
-	if (!feat_sme_supported()) {
-		/* Perhaps the hardware supports SVE only */
-		sve_disable(context);
-		return;
-	}
-
 	/* Get the context state. */
 	state = get_el3state_ctx(context);
 
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index d747efc..b1fe39f 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -7,6 +7,7 @@
 #include <stdbool.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/el3_runtime/pubsub.h>
 #include <lib/extensions/spe.h>
@@ -20,21 +21,10 @@
 	__asm__ volatile("hint #17");
 }
 
-bool spe_supported(void)
-{
-	uint64_t features;
-
-	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
-	return (features & ID_AA64DFR0_PMS_MASK) > 0ULL;
-}
-
 void spe_enable(bool el2_unused)
 {
 	uint64_t v;
 
-	if (!spe_supported())
-		return;
-
 	if (el2_unused) {
 		/*
 		 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
@@ -69,9 +59,6 @@
 {
 	uint64_t v;
 
-	if (!spe_supported())
-		return;
-
 	/* Drain buffered data */
 	psb_csync();
 	dsbnsh();
@@ -85,7 +72,7 @@
 
 static void *spe_drain_buffers_hook(const void *arg)
 {
-	if (!spe_supported())
+	if (!is_feat_spe_supported())
 		return (void *)-1;
 
 	/* Drain buffered data */
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index f7dcc76..f551ca7 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,22 +22,10 @@
  */
 #define CONVERT_SVE_LENGTH(x)	(((x / 128) - 1))
 
-static bool sve_supported(void)
-{
-	uint64_t features;
-
-	features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT;
-	return (features & ID_AA64PFR0_SVE_MASK) == 1U;
-}
-
 void sve_enable(cpu_context_t *context)
 {
 	u_register_t cptr_el3;
 
-	if (!sve_supported()) {
-		return;
-	}
-
 	cptr_el3 = read_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3);
 
 	/* Enable access to SVE functionality for all ELs. */
@@ -54,11 +42,6 @@
 	u_register_t reg;
 	el3_state_t *state;
 
-	/* Make sure SME is implemented in hardware before continuing. */
-	if (!sve_supported()) {
-		return;
-	}
-
 	/* Get the context state. */
 	state = get_el3state_ctx(context);
 
diff --git a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
index 89b8029..b3f44b7 100644
--- a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
+++ b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
@@ -10,27 +10,16 @@
 #include <arch_helpers.h>
 #include <lib/extensions/sys_reg_trace.h>
 
-static bool sys_reg_trace_supported(void)
-{
-	uint32_t features;
-
-	features = read_id_dfr0() >> ID_DFR0_COPTRC_SHIFT;
-	return ((features & ID_DFR0_COPTRC_MASK) ==
-		ID_DFR0_COPTRC_SUPPORTED);
-}
-
 void sys_reg_trace_enable(void)
 {
 	uint32_t val;
 
-	if (sys_reg_trace_supported()) {
-		/*
-		 * NSACR.NSTRCDIS = b0
-		 * enable NS system register access to implemented trace
-		 * registers.
-		 */
-		val = read_nsacr();
-		val &= ~NSTRCDIS_BIT;
-		write_nsacr(val);
-	}
+	/*
+	 * NSACR.NSTRCDIS = b0
+	 * enable NS system register access to implemented trace
+	 * registers.
+	 */
+	val = read_nsacr();
+	val &= ~NSTRCDIS_BIT;
+	write_nsacr(val);
 }
diff --git a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
index 960d698..e61cb90 100644
--- a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
+++ b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
@@ -10,28 +10,17 @@
 #include <arch_helpers.h>
 #include <lib/extensions/sys_reg_trace.h>
 
-static bool sys_reg_trace_supported(void)
-{
-	uint64_t features;
-
-	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEVER_SHIFT;
-	return ((features & ID_AA64DFR0_TRACEVER_MASK) ==
-		ID_AA64DFR0_TRACEVER_SUPPORTED);
-}
-
 void sys_reg_trace_enable(cpu_context_t *ctx)
 {
 	uint64_t val;
 
-	if (sys_reg_trace_supported()) {
-		/* Retrieve CPTR_EL3 value from the given context 'ctx',
-		 * and update CPTR_EL3.TTA bit to 0.
-		 * This function is called while switching context to NS to
-		 * allow system trace register access to NS-EL2 and NS-EL1
-		 * when NS-EL2 is implemented but not used.
-		 */
-		val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
-		val &= ~TTA_BIT;
-		write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val);
-	}
+	/* Retrieve CPTR_EL3 value from the given context 'ctx',
+	 * and update CPTR_EL3.TTA bit to 0.
+	 * This function is called while switching context to NS to
+	 * allow system trace register access to NS-EL2 and NS-EL1
+	 * when NS-EL2 is implemented but not used.
+	 */
+	val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
+	val &= ~TTA_BIT;
+	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val);
 }
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/libc/printf.c b/lib/libc/printf.c
index e52cbed..faccfdf 100644
--- a/lib/libc/printf.c
+++ b/lib/libc/printf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -81,6 +81,7 @@
  * %x - hexadecimal format
  * %s - string format
  * %d or %i - signed decimal format
+ * %c - character format
  * %u - unsigned decimal format
  * %p - pointer format
  *
@@ -130,6 +131,10 @@
 				count += unsigned_num_print(unum, 10,
 							    padc, padn);
 				break;
+			case 'c':
+				(void)putchar(va_arg(args, int));
+				count++;
+				break;
 			case 's':
 				str = va_arg(args, char *);
 				count += string_print(str);
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 0e3256c..21d3416 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -85,6 +85,7 @@
  *
  * %x (or %X) - hexadecimal format
  * %d or %i - signed decimal format
+ * %c - character format
  * %s - string format
  * %u - unsigned decimal format
  * %p - pointer format
@@ -181,6 +182,9 @@
 				unsigned_num_print(&s, n, &chars_printed,
 						   unum, 10, padc, padn, false);
 				break;
+			case 'c':
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, va_arg(args, int));
+				break;
 			case 's':
 				str = va_arg(args, char *);
 				string_print(&s, n, &chars_printed, str);
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 9fe7cf4..20c6415 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -106,7 +106,6 @@
 	}
 	hdrsize = fdt_header_size(fdt);
 	if (!can_assume(VALID_DTB)) {
-
 		if ((fdt_totalsize(fdt) < hdrsize)
 		    || (fdt_totalsize(fdt) > INT_MAX))
 			return -FDT_ERR_TRUNCATED;
@@ -115,9 +114,7 @@
 		if (!check_off_(hdrsize, fdt_totalsize(fdt),
 				fdt_off_mem_rsvmap(fdt)))
 			return -FDT_ERR_TRUNCATED;
-	}
 
-	if (!can_assume(VALID_DTB)) {
 		/* Bounds check structure block */
 		if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
 			if (!check_off_(hdrsize, fdt_totalsize(fdt),
@@ -165,7 +162,7 @@
 uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
 {
 	const fdt32_t *tagp, *lenp;
-	uint32_t tag;
+	uint32_t tag, len, sum;
 	int offset = startoffset;
 	const char *p;
 
@@ -191,12 +188,19 @@
 		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
 		if (!can_assume(VALID_DTB) && !lenp)
 			return FDT_END; /* premature end */
+
+		len = fdt32_to_cpu(*lenp);
+		sum = len + offset;
+		if (!can_assume(VALID_DTB) &&
+		    (INT_MAX <= sum || sum < (uint32_t) offset))
+			return FDT_END; /* premature end */
+
 		/* skip-name offset, length and value */
-		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
-			+ fdt32_to_cpu(*lenp);
+		offset += sizeof(struct fdt_property) - FDT_TAGSIZE + len;
+
 		if (!can_assume(LATEST) &&
-		    fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
-		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
+		    fdt_version(fdt) < 0x10 && len >= 8 &&
+		    ((offset - len) % 8) != 0)
 			offset += 4;
 		break;
 
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 25272fc..6641db9 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -180,7 +180,7 @@
 
 	/*
 	 * Update "pc" value which should comes from pager image. After the
-	 * header image is parsed, it will be unuseful, and the actual
+	 * header image is parsed, it will be useless, and the actual
 	 * execution image after BL31 is pager image.
 	 */
 	header_ep->pc =	pager_image_info->image_base;
diff --git a/lib/psa/delegated_attestation.c b/lib/psa/delegated_attestation.c
index 399a3f1..a813e84 100644
--- a/lib/psa/delegated_attestation.c
+++ b/lib/psa/delegated_attestation.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -87,104 +87,90 @@
 };
 
 static const uint8_t platform_token[] = {
-	0xD2, 0x84, 0x43, 0xA1, 0x01, 0x26, 0xA0, 0x59,
-	0x02, 0xBE, 0xAA, 0x3A, 0x00, 0x01, 0x24, 0xFF,
-	0x58, 0x20, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
-	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
-	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
-	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
-	0xAB, 0xAB, 0x3A, 0x00, 0x01, 0x24, 0xFB, 0x58,
-	0x20, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
-	0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE,
-	0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
-	0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
-	0xBF, 0x3A, 0x00, 0x01, 0x25, 0x00, 0x58, 0x21,
-	0x01, 0xFA, 0x58, 0x75, 0x5F, 0x65, 0x86, 0x27,
-	0xCE, 0x54, 0x60, 0xF2, 0x9B, 0x75, 0x29, 0x67,
-	0x13, 0x24, 0x8C, 0xAE, 0x7A, 0xD9, 0xE2, 0x98,
-	0x4B, 0x90, 0x28, 0x0E, 0xFC, 0xBC, 0xB5, 0x02,
-	0x48, 0x3A, 0x00, 0x01, 0x24, 0xFA, 0x58, 0x20,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0x3A, 0x00, 0x01, 0x24, 0xF8, 0x20, 0x3A, 0x00,
-	0x01, 0x24, 0xF9, 0x00, 0x3A, 0x00, 0x01, 0x24,
-	0xFD, 0x85, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60,
-	0x01, 0x65, 0x42, 0x4C, 0x31, 0x5F, 0x32, 0x06,
-	0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x02,
-	0x58, 0x20, 0xF8, 0xB7, 0xCE, 0xAD, 0x9B, 0xE4,
-	0x5A, 0x8F, 0x5C, 0x52, 0x6F, 0x0C, 0x05, 0x25,
-	0x8F, 0xF3, 0xE9, 0x81, 0xDC, 0xBC, 0xF2, 0x05,
-	0x7F, 0x33, 0xF6, 0xBB, 0xDC, 0xD9, 0x4D, 0xA2,
-	0x34, 0x3A, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x67,
-	0x31, 0x2E, 0x37, 0x2E, 0x32, 0x2B, 0x30, 0x01,
-	0x63, 0x42, 0x4C, 0x32, 0x06, 0x66, 0x53, 0x48,
-	0x41, 0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x3A,
-	0xE5, 0x9E, 0x40, 0xA9, 0x6B, 0xD5, 0x29, 0x1C,
-	0xAB, 0x7A, 0x5F, 0xBD, 0x1F, 0x9A, 0xA6, 0x52,
-	0xFB, 0x77, 0x7D, 0xA3, 0xEC, 0x9C, 0x29, 0xBC,
-	0xE6, 0x5B, 0x3B, 0x43, 0xFC, 0x9D, 0x26, 0xA5,
-	0x05, 0x58, 0x20, 0xBF, 0xE6, 0xD8, 0x6F, 0x88,
-	0x26, 0xF4, 0xFF, 0x97, 0xFB, 0x96, 0xC4, 0xE6,
-	0xFB, 0xC4, 0x99, 0x3E, 0x46, 0x19, 0xFC, 0x56,
-	0x5D, 0xA2, 0x6A, 0xDF, 0x34, 0xC3, 0x29, 0x48,
-	0x9A, 0xDC, 0x38, 0x04, 0x67, 0x31, 0x2E, 0x35,
-	0x2E, 0x30, 0x2B, 0x30, 0x01, 0x64, 0x52, 0x54,
-	0x5F, 0x30, 0x06, 0x66, 0x53, 0x48, 0x41, 0x32,
-	0x35, 0x36, 0x02, 0x58, 0x20, 0x47, 0x94, 0x9D,
-	0x27, 0x33, 0x82, 0x45, 0x1A, 0xDD, 0x25, 0xF4,
-	0x9A, 0x89, 0x6F, 0x5F, 0xD9, 0xB0, 0xE8, 0x14,
-	0xD3, 0xA4, 0x9B, 0x53, 0xB0, 0x44, 0x0B, 0xCF,
-	0x32, 0x1A, 0xC4, 0xD2, 0x65, 0xA5, 0x05, 0x58,
-	0x20, 0xB3, 0x60, 0xCA, 0xF5, 0xC9, 0x8C, 0x6B,
-	0x94, 0x2A, 0x48, 0x82, 0xFA, 0x9D, 0x48, 0x23,
-	0xEF, 0xB1, 0x66, 0xA9, 0xEF, 0x6A, 0x6E, 0x4A,
-	0xA3, 0x7C, 0x19, 0x19, 0xED, 0x1F, 0xCC, 0xC0,
-	0x49, 0x04, 0x67, 0x30, 0x2E, 0x30, 0x2E, 0x37,
-	0x2B, 0x30, 0x01, 0x64, 0x52, 0x54, 0x5F, 0x31,
-	0x06, 0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
-	0x02, 0x58, 0x20, 0xCD, 0x38, 0xBE, 0xC8, 0xB7,
-	0xC0, 0x9E, 0xD5, 0x24, 0x30, 0xFE, 0xC8, 0xD0,
-	0x19, 0x12, 0x56, 0xB2, 0x7A, 0xA5, 0x53, 0x6F,
-	0xBC, 0x7D, 0x09, 0xCA, 0x11, 0xDD, 0x90, 0xD7,
-	0xD6, 0x70, 0xFD, 0xA5, 0x05, 0x58, 0x20, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x04,
-	0x60, 0x01, 0x60, 0x06, 0x66, 0x53, 0x48, 0x41,
-	0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x28, 0x3D,
-	0x0C, 0x25, 0x22, 0x0C, 0x87, 0x46, 0xA0, 0x58,
-	0x64, 0x6C, 0x0B, 0x14, 0x37, 0x39, 0x40, 0x9D,
-	0x2D, 0x11, 0xD1, 0xCC, 0x54, 0x51, 0xB4, 0x29,
-	0x22, 0xCD, 0x70, 0x92, 0x71, 0xC3, 0x3A, 0x00,
-	0x01, 0x25, 0x01, 0x77, 0x77, 0x77, 0x77, 0x2E,
-	0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x66,
-	0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2E,
-	0x6F, 0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF7,
-	0x71, 0x50, 0x53, 0x41, 0x5F, 0x49, 0x4F, 0x54,
-	0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45,
-	0x5F, 0x31, 0x3A, 0x00, 0x01, 0x24, 0xFC, 0x70,
-	0x30, 0x36, 0x30, 0x34, 0x35, 0x36, 0x35, 0x32,
-	0x37, 0x32, 0x38, 0x32, 0x39, 0x31, 0x30, 0x30,
-	0x58, 0x40, 0x1E, 0x0D, 0x2B, 0xD8, 0x7A, 0xC9,
-	0x2D, 0xCB, 0x73, 0xD1, 0x42, 0x2F, 0xBF, 0xDA,
-	0x24, 0x71, 0xE2, 0xAF, 0xEA, 0x48, 0x60, 0x17,
-	0x23, 0x75, 0x64, 0xAC, 0xCC, 0x23, 0xA2, 0x67,
-	0xC4, 0xE7, 0x8F, 0x1C, 0x7C, 0x68, 0x49, 0x42,
-	0x4D, 0xDA, 0xC6, 0xD6, 0x21, 0x1C, 0xAA, 0x00,
-	0xDA, 0x1E, 0x68, 0x56, 0xA3, 0x48, 0xEE, 0xA7,
-	0x92, 0xA9, 0x09, 0x83, 0x42, 0x04, 0x06, 0x9E,
-	0x62, 0xBB
+	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
+	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
+	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
+	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
+	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
+	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
+	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
+	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
+	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
+	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
+	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
+	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
+	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
+	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
+	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
+	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
+	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
+	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
+	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
+	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
+	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
+	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
+	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
+	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
+	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
+	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
+	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
+	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
+	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
+	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
+	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
+	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
+	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
+	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
+	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
+	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
+	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
+	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
+	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
+	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
+	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
+	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
+	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
+	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
+	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
+	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
 };
 
 psa_status_t
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 10c43f1..c359e9f 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -80,16 +80,23 @@
 		.lock_measurement = lock_measurement,
 		.measurement_algo = measurement_algo,
 		.sw_type = {0},
-		/* Removing \0 */
-		.sw_type_size = (sw_type_size > 0) ? (sw_type_size - 1) : 0,
+		.sw_type_size = sw_type_size,
 	};
 
+	if (version_size > VERSION_MAX_SIZE) {
+		return PSA_ERROR_INVALID_ARGUMENT;
+	}
+
+
+	if (version_size > 0 && version[version_size - 1] == '\0') {
+		version_size--;
+	}
+
 	psa_invec in_vec[] = {
 		{.base = &extend_iov,
 			.len = sizeof(struct measured_boot_extend_iovec_t)},
 		{.base = signer_id, .len = signer_id_size},
-		{.base = version,
-			.len = (version_size > 0) ? (version_size - 1) : 0},
+		{.base = version, .len = version_size },
 		{.base = measurement_value, .len = measurement_value_size}
 	};
 
@@ -97,6 +104,9 @@
 		if (extend_iov.sw_type_size > SW_TYPE_MAX_SIZE) {
 			return PSA_ERROR_INVALID_ARGUMENT;
 		}
+		if (sw_type_size > 0 && sw_type[sw_type_size - 1] == '\0') {
+			extend_iov.sw_type_size--;
+		}
 		memcpy(extend_iov.sw_type, sw_type, extend_iov.sw_type_size);
 	}
 
diff --git a/lib/cpus/aarch64/runtime_errata.S b/lib/psci/aarch64/runtime_errata.S
similarity index 100%
rename from lib/cpus/aarch64/runtime_errata.S
rename to lib/psci/aarch64/runtime_errata.S
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index f233be1..8aa0cce 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -76,6 +76,14 @@
 	(PLAT_MAX_PWR_LVL >= PSCI_CPU_PWR_LVL),
 	assert_platform_max_pwrlvl_check);
 
+#if PSCI_OS_INIT_MODE
+/*******************************************************************************
+ * The power state coordination mode used in CPU_SUSPEND.
+ * Defaults to platform-coordinated mode.
+ ******************************************************************************/
+suspend_mode_t psci_suspend_mode = PLAT_COORD;
+#endif
+
 /*
  * The plat_local_state used by the platform is one of these types: RUN,
  * RETENTION and OFF. The platform can define further sub-states for each type
@@ -153,8 +161,51 @@
 	psci_plat_pm_ops->get_sys_suspend_power_state(state_info);
 }
 
+#if PSCI_OS_INIT_MODE
 /*******************************************************************************
- * This function verifies that the all the other cores in the system have been
+ * This function verifies that all the other cores at the 'end_pwrlvl' have been
+ * idled and the current CPU is the last running CPU at the 'end_pwrlvl'.
+ * Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
+ * otherwise.
+ ******************************************************************************/
+static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int end_pwrlvl)
+{
+	unsigned int my_idx, lvl, parent_idx;
+	unsigned int cpu_start_idx, ncpus, cpu_idx;
+	plat_local_state_t local_state;
+
+	if (end_pwrlvl == PSCI_CPU_PWR_LVL) {
+		return true;
+	}
+
+	my_idx = plat_my_core_pos();
+
+	for (lvl = PSCI_CPU_PWR_LVL; lvl <= end_pwrlvl; lvl++) {
+		parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	}
+
+	cpu_start_idx = psci_non_cpu_pd_nodes[parent_idx].cpu_start_idx;
+	ncpus = psci_non_cpu_pd_nodes[parent_idx].ncpus;
+
+	for (cpu_idx = cpu_start_idx; cpu_idx < cpu_start_idx + ncpus;
+			cpu_idx++) {
+		local_state = psci_get_cpu_local_state_by_idx(cpu_idx);
+		if (cpu_idx == my_idx) {
+			assert(is_local_state_run(local_state) != 0);
+			continue;
+		}
+
+		if (is_local_state_run(local_state) != 0) {
+			return false;
+		}
+	}
+
+	return true;
+}
+#endif
+
+/*******************************************************************************
+ * This function verifies that all the other cores in the system have been
  * turned OFF and the current CPU is the last running CPU in the system.
  * Returns true, if the current CPU is the last ON CPU or false otherwise.
  ******************************************************************************/
@@ -179,6 +230,23 @@
 }
 
 /*******************************************************************************
+ * This function verifies that all cores in the system have been turned ON.
+ * Returns true, if all CPUs are ON or false otherwise.
+ ******************************************************************************/
+static bool psci_are_all_cpus_on(void)
+{
+	unsigned int cpu_idx;
+
+	for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
+		if (psci_get_aff_info_state_by_idx(cpu_idx) == AFF_STATE_OFF) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/*******************************************************************************
  * Routine to return the maximum power level to traverse to after a cpu has
  * been physically powered up. It is expected to be called immediately after
  * reset from assembler code.
@@ -252,6 +320,60 @@
 	} else
 		return NULL;
 }
+
+#if PSCI_OS_INIT_MODE
+/******************************************************************************
+ * Helper function to save a copy of the psci_req_local_pwr_states (prev) for a
+ * CPU (cpu_idx), and update psci_req_local_pwr_states with the new requested
+ * local power states (state_info).
+ *****************************************************************************/
+void psci_update_req_local_pwr_states(unsigned int end_pwrlvl,
+				      unsigned int cpu_idx,
+				      psci_power_state_t *state_info,
+				      plat_local_state_t *prev)
+{
+	unsigned int lvl;
+#ifdef PLAT_MAX_CPU_SUSPEND_PWR_LVL
+	unsigned int max_pwrlvl = PLAT_MAX_CPU_SUSPEND_PWR_LVL;
+#else
+	unsigned int max_pwrlvl = PLAT_MAX_PWR_LVL;
+#endif
+	plat_local_state_t req_state;
+
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= max_pwrlvl; lvl++) {
+		/* Save the previous requested local power state */
+		prev[lvl - 1U] = *psci_get_req_local_pwr_states(lvl, cpu_idx);
+
+		/* Update the new requested local power state */
+		if (lvl <= end_pwrlvl) {
+			req_state = state_info->pwr_domain_state[lvl];
+		} else {
+			req_state = state_info->pwr_domain_state[end_pwrlvl];
+		}
+		psci_set_req_local_pwr_state(lvl, cpu_idx, req_state);
+	}
+}
+
+/******************************************************************************
+ * Helper function to restore the previously saved requested local power states
+ * (prev) for a CPU (cpu_idx) to psci_req_local_pwr_states.
+ *****************************************************************************/
+void psci_restore_req_local_pwr_states(unsigned int cpu_idx,
+				       plat_local_state_t *prev)
+{
+	unsigned int lvl;
+#ifdef PLAT_MAX_CPU_SUSPEND_PWR_LVL
+	unsigned int max_pwrlvl = PLAT_MAX_CPU_SUSPEND_PWR_LVL;
+#else
+	unsigned int max_pwrlvl = PLAT_MAX_PWR_LVL;
+#endif
+
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= max_pwrlvl; lvl++) {
+		/* Restore the previous requested local power state */
+		psci_set_req_local_pwr_state(lvl, cpu_idx, prev[lvl - 1U]);
+	}
+}
+#endif
 
 /*
  * psci_non_cpu_pd_nodes can be placed either in normal memory or coherent
@@ -329,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;
@@ -352,7 +474,6 @@
 	}
 }
 
-
 /*******************************************************************************
  * PSCI helper function to get the parent nodes corresponding to a cpu_index.
  ******************************************************************************/
@@ -399,6 +520,8 @@
 }
 
 /******************************************************************************
+ * This function is used in platform-coordinated mode.
+ *
  * This function is passed the local power states requested for each power
  * domain (state_info) between the current CPU domain and its ancestors until
  * the target power level (end_pwrlvl). It updates the array of requested power
@@ -471,10 +594,95 @@
 		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
+/******************************************************************************
+ * This function is used in OS-initiated mode.
+ *
+ * This function is passed the local power states requested for each power
+ * domain (state_info) between the current CPU domain and its ancestors until
+ * the target power level (end_pwrlvl), and ensures the requested power states
+ * are valid. It updates the array of requested power states with this
+ * information.
+ *
+ * Then, for each level (apart from the CPU level) until the 'end_pwrlvl', it
+ * retrieves the states requested by all the cpus of which the power domain at
+ * that level is an ancestor. It passes this information to the platform to
+ * coordinate and return the target power state. If the requested state does
+ * not match the target state, the request is denied.
+ *
+ * The 'state_info' is not modified.
+ *
+ * This function will only be invoked with data cache enabled and while
+ * powering down a core.
+ *****************************************************************************/
+int psci_validate_state_coordination(unsigned int end_pwrlvl,
+				     psci_power_state_t *state_info)
+{
+	int rc = PSCI_E_SUCCESS;
+	unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+	unsigned int start_idx;
+	unsigned int ncpus;
+	plat_local_state_t target_state, *req_states;
+	plat_local_state_t prev[PLAT_MAX_PWR_LVL];
+
+	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
+	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
+
+	/*
+	 * Save a copy of the previous requested local power states and update
+	 * the new requested local power states.
+	 */
+	psci_update_req_local_pwr_states(end_pwrlvl, cpu_idx, state_info, prev);
+
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
+		/* Get the requested power states for this power level */
+		start_idx = psci_non_cpu_pd_nodes[parent_idx].cpu_start_idx;
+		req_states = psci_get_req_local_pwr_states(lvl, start_idx);
+
+		/*
+		 * Let the platform coordinate amongst the requested states at
+		 * this power level and return the target local power state.
+		 */
+		ncpus = psci_non_cpu_pd_nodes[parent_idx].ncpus;
+		target_state = plat_get_target_pwr_state(lvl,
+							 req_states,
+							 ncpus);
+
+		/*
+		 * Verify that the requested power state matches the target
+		 * local power state.
+		 */
+		if (state_info->pwr_domain_state[lvl] != target_state) {
+			if (target_state == PSCI_LOCAL_STATE_RUN) {
+				rc = PSCI_E_DENIED;
+			} else {
+				rc = PSCI_E_INVALID_PARAMS;
+			}
+			goto exit;
+		}
+	}
+
+	/*
+	 * Verify that the current core is the last running core at the
+	 * specified power level.
+	 */
+	lvl = state_info->last_at_pwrlvl;
+	if (!psci_is_last_cpu_to_idle_at_pwrlvl(lvl)) {
+		rc = PSCI_E_DENIED;
+	}
+
+exit:
+	if (rc != PSCI_E_SUCCESS) {
+		/* Restore the previous requested local power states. */
+		psci_restore_req_local_pwr_states(cpu_idx, prev);
+		return rc;
+	}
+
+	return rc;
 }
+#endif
 
 /******************************************************************************
  * This function validates a suspend request by making sure that if a standby
@@ -614,8 +822,11 @@
  ******************************************************************************/
 int psci_validate_mpidr(u_register_t mpidr)
 {
-	if (plat_core_pos_by_mpidr(mpidr) < 0)
+	int pos = plat_core_pos_by_mpidr(mpidr);
+
+	if ((pos < 0) || ((unsigned int)pos >= PLATFORM_CORE_COUNT)) {
 		return PSCI_E_INVALID_PARAMS;
+	}
 
 	return PSCI_E_SUCCESS;
 }
@@ -774,6 +985,9 @@
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 
+	/* Init registers that never change for the lifetime of TF-A */
+	cm_manage_extensions_el3();
+
 	/*
 	 * Verify that we have been explicitly turned ON or resumed from
 	 * suspend.
@@ -1050,3 +1264,29 @@
 
 	return true;
 }
+
+/*******************************************************************************
+ * This function verifies that all cores in the system have been turned ON.
+ * Returns true, if all CPUs are ON or false otherwise.
+ *
+ * This API has following differences with psci_are_all_cpus_on
+ *  1. PSCI states are locked
+ ******************************************************************************/
+bool psci_are_all_cpus_on_safe(void)
+{
+	unsigned int this_core = plat_my_core_pos();
+	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
+
+	psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
+
+	psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
+	if (!psci_are_all_cpus_on()) {
+		psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+		return false;
+	}
+
+	psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
+	return true;
+}
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index 6864202..c71580f 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -22,7 +22,7 @@
 
 ifeq (${ARCH}, aarch64)
 PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S	\
-				lib/cpus/aarch64/runtime_errata.S
+				lib/psci/aarch64/runtime_errata.S
 endif
 
 ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index a631f3f..326f125 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -60,6 +60,10 @@
 	entry_point_info_t ep;
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 	plat_local_state_t cpu_pd_state;
+#if PSCI_OS_INIT_MODE
+	unsigned int cpu_idx = plat_my_core_pos();
+	plat_local_state_t prev[PLAT_MAX_PWR_LVL];
+#endif
 
 	/* Validate the power_state parameter */
 	rc = psci_validate_power_state(power_state, &state_info);
@@ -95,6 +99,18 @@
 		cpu_pd_state = state_info.pwr_domain_state[PSCI_CPU_PWR_LVL];
 		psci_set_cpu_local_state(cpu_pd_state);
 
+#if PSCI_OS_INIT_MODE
+		/*
+		 * If in OS-initiated mode, save a copy of the previous
+		 * requested local power states and update the new requested
+		 * local power states for this CPU.
+		 */
+		if (psci_suspend_mode == OS_INIT) {
+			psci_update_req_local_pwr_states(target_pwrlvl, cpu_idx,
+							 &state_info, prev);
+		}
+#endif
+
 #if ENABLE_PSCI_STAT
 		plat_psci_stat_accounting_start(&state_info);
 #endif
@@ -110,6 +126,16 @@
 		/* Upon exit from standby, set the state back to RUN. */
 		psci_set_cpu_local_state(PSCI_LOCAL_STATE_RUN);
 
+#if PSCI_OS_INIT_MODE
+		/*
+		 * If in OS-initiated mode, restore the previous requested
+		 * local power states for this CPU.
+		 */
+		if (psci_suspend_mode == OS_INIT) {
+			psci_restore_req_local_pwr_states(cpu_idx, prev);
+		}
+#endif
+
 #if ENABLE_RUNTIME_INSTRUMENTATION
 		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
 		    RT_INSTR_EXIT_HW_LOW_PWR,
@@ -142,12 +168,12 @@
 	 * might return if the power down was abandoned for any reason, e.g.
 	 * arrival of an interrupt
 	 */
-	psci_cpu_suspend_start(&ep,
-			    target_pwrlvl,
-			    &state_info,
-			    is_power_down_state);
+	rc = psci_cpu_suspend_start(&ep,
+				    target_pwrlvl,
+				    &state_info,
+				    is_power_down_state);
 
-	return PSCI_E_SUCCESS;
+	return rc;
 }
 
 
@@ -187,12 +213,12 @@
 	 * might return if the power down was abandoned for any reason, e.g.
 	 * arrival of an interrupt
 	 */
-	psci_cpu_suspend_start(&ep,
-			    PLAT_MAX_PWR_LVL,
-			    &state_info,
-			    PSTATE_TYPE_POWERDOWN);
+	rc = psci_cpu_suspend_start(&ep,
+				    PLAT_MAX_PWR_LVL,
+				    &state_info,
+				    PSTATE_TYPE_POWERDOWN);
 
-	return PSCI_E_SUCCESS;
+	return rc;
 }
 
 int psci_cpu_off(void)
@@ -357,19 +383,48 @@
 	/* Format the feature flags */
 	if ((psci_fid == PSCI_CPU_SUSPEND_AARCH32) ||
 	    (psci_fid == PSCI_CPU_SUSPEND_AARCH64)) {
-		/*
-		 * The trusted firmware does not support OS Initiated Mode.
-		 */
 		unsigned int ret = ((FF_PSTATE << FF_PSTATE_SHIFT) |
-			(((FF_SUPPORTS_OS_INIT_MODE == 1U) ? 0U : 1U)
-				<< FF_MODE_SUPPORT_SHIFT));
-		return (int) ret;
+			(FF_SUPPORTS_OS_INIT_MODE << FF_MODE_SUPPORT_SHIFT));
+		return (int)ret;
 	}
 
 	/* Return 0 for all other fid's */
 	return PSCI_E_SUCCESS;
 }
 
+#if PSCI_OS_INIT_MODE
+int psci_set_suspend_mode(unsigned int mode)
+{
+	if (psci_suspend_mode == mode) {
+		return PSCI_E_SUCCESS;
+	}
+
+	if (mode == PLAT_COORD) {
+		/* Check if the current CPU is the last ON CPU in the system */
+		if (!psci_is_last_on_cpu_safe()) {
+			return PSCI_E_DENIED;
+		}
+	}
+
+	if (mode == OS_INIT) {
+		/*
+		 * Check if all CPUs in the system are ON or if the current
+		 * CPU is the last ON CPU in the system.
+		 */
+		if (!(psci_are_all_cpus_on_safe() ||
+		      psci_is_last_on_cpu_safe())) {
+			return PSCI_E_DENIED;
+		}
+	}
+
+	psci_suspend_mode = mode;
+	psci_flush_dcache_range((uintptr_t)&psci_suspend_mode,
+				sizeof(psci_suspend_mode));
+
+	return PSCI_E_SUCCESS;
+}
+#endif
+
 /*******************************************************************************
  * PSCI top level handler for servicing SMCs.
  ******************************************************************************/
@@ -452,6 +507,12 @@
 		case PSCI_FEATURES:
 			ret = (u_register_t)psci_features(r1);
 			break;
+
+#if PSCI_OS_INIT_MODE
+		case PSCI_SET_SUSPEND_MODE:
+			ret = (u_register_t)psci_set_suspend_mode(r1);
+			break;
+#endif
 
 #if ENABLE_PSCI_STAT
 		case PSCI_STAT_RESIDENCY_AARCH32:
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 637adb9..f83753f 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,6 +58,19 @@
 	psci_set_power_off_state(&state_info);
 
 	/*
+	 * Call the platform provided early CPU_OFF handler to allow
+	 * platforms to perform any housekeeping activities before
+	 * actually powering the CPU off. PSCI_E_DENIED indicates that
+	 * the CPU off sequence should be aborted at this time.
+	 */
+	if (psci_plat_pm_ops->pwr_domain_off_early) {
+		rc = psci_plat_pm_ops->pwr_domain_off_early(&state_info);
+		if (rc == PSCI_E_DENIED) {
+			return rc;
+		}
+	}
+
+	/*
 	 * Get the parent nodes here, this is important to do before we
 	 * initiate the power down sequence as after that point the core may
 	 * have exited coherency and its cache may be disabled, any access to
@@ -90,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_on.c b/lib/psci/psci_on.c
index c70b377..76eb50c 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -62,12 +62,14 @@
 	int rc;
 	aff_info_state_t target_aff_state;
 	int ret = plat_core_pos_by_mpidr(target_cpu);
-	unsigned int target_idx = (unsigned int)ret;
+	unsigned int target_idx;
 
 	/* Calling function must supply valid input arguments */
 	assert(ret >= 0);
+	assert((unsigned int)ret < PLATFORM_CORE_COUNT);
 	assert(ep != NULL);
 
+	target_idx = (unsigned int)ret;
 
 	/*
 	 * This function must only be called on platforms where the
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 6ca9ef6..04f93bd 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -163,6 +163,16 @@
 	spinlock_t cpu_lock;
 } cpu_pd_node_t;
 
+#if PSCI_OS_INIT_MODE
+/*******************************************************************************
+ * The supported power state coordination modes that can be used in CPU_SUSPEND.
+ ******************************************************************************/
+typedef enum suspend_mode {
+	PLAT_COORD = 0,
+	OS_INIT = 1
+} suspend_mode_t;
+#endif
+
 /*******************************************************************************
  * The following are helpers and declarations of locks.
  ******************************************************************************/
@@ -260,6 +270,9 @@
 extern cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
 extern unsigned int psci_caps;
 extern unsigned int psci_plat_core_count;
+#if PSCI_OS_INIT_MODE
+extern suspend_mode_t psci_suspend_mode;
+#endif
 
 /*******************************************************************************
  * SPD's power management hooks registered with PSCI
@@ -275,8 +288,18 @@
 void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info);
 int psci_validate_mpidr(u_register_t mpidr);
 void psci_init_req_local_pwr_states(void);
+#if PSCI_OS_INIT_MODE
+void psci_update_req_local_pwr_states(unsigned int end_pwrlvl,
+				      unsigned int cpu_idx,
+				      psci_power_state_t *state_info,
+				      plat_local_state_t *prev);
+void psci_restore_req_local_pwr_states(unsigned int cpu_idx,
+				       plat_local_state_t *prev);
+#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,
@@ -284,6 +307,10 @@
 				      unsigned int *node_index);
 void psci_do_state_coordination(unsigned int end_pwrlvl,
 				psci_power_state_t *state_info);
+#if PSCI_OS_INIT_MODE
+int psci_validate_state_coordination(unsigned int end_pwrlvl,
+				     psci_power_state_t *state_info);
+#endif
 void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
 				   const unsigned int *parent_nodes);
 void psci_release_pwr_domain_locks(unsigned int end_pwrlvl,
@@ -317,10 +344,10 @@
 int psci_do_cpu_off(unsigned int end_pwrlvl);
 
 /* Private exported functions from psci_suspend.c */
-void psci_cpu_suspend_start(const entry_point_info_t *ep,
-			unsigned int end_pwrlvl,
-			psci_power_state_t *state_info,
-			unsigned int is_power_down_state);
+int psci_cpu_suspend_start(const entry_point_info_t *ep,
+			   unsigned int end_pwrlvl,
+			   psci_power_state_t *state_info,
+			   unsigned int is_power_down_state);
 
 void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
 
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 3cb4f7e..1f93cc9 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -11,8 +11,8 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <context.h>
+#include <lib/cpus/errata.h>
 #include <lib/el3_runtime/context_mgmt.h>
-#include <lib/cpus/errata_report.h>
 #include <plat/common/platform.h>
 
 #include "psci_private.h"
@@ -254,6 +254,9 @@
 			psci_caps |=  define_psci_cap(PSCI_CPU_SUSPEND_AARCH64);
 		if (psci_plat_pm_ops->get_sys_suspend_power_state != NULL)
 			psci_caps |=  define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64);
+#if PSCI_OS_INIT_MODE
+		psci_caps |= define_psci_cap(PSCI_SET_SUSPEND_MODE);
+#endif
 	}
 	if (psci_plat_pm_ops->system_off != NULL)
 		psci_caps |=  define_psci_cap(PSCI_SYSTEM_OFF);
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index f71994d..d93e60d 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -75,6 +75,14 @@
 
 	PUBLISH_EVENT(psci_suspend_pwrdown_start);
 
+#if PSCI_OS_INIT_MODE
+#ifdef PLAT_MAX_CPU_SUSPEND_PWR_LVL
+	end_pwrlvl = PLAT_MAX_CPU_SUSPEND_PWR_LVL;
+#else
+	end_pwrlvl = PLAT_MAX_PWR_LVL;
+#endif
+#endif
+
 	/* Save PSCI target power level for the suspend finisher handler */
 	psci_set_suspend_pwrlvl(end_pwrlvl);
 
@@ -151,12 +159,13 @@
  * the state transition has been done, no further error is expected and it is
  * not possible to undo any of the actions taken beyond that point.
  ******************************************************************************/
-void psci_cpu_suspend_start(const entry_point_info_t *ep,
-			    unsigned int end_pwrlvl,
-			    psci_power_state_t *state_info,
-			    unsigned int is_power_down_state)
+int psci_cpu_suspend_start(const entry_point_info_t *ep,
+			   unsigned int end_pwrlvl,
+			   psci_power_state_t *state_info,
+			   unsigned int is_power_down_state)
 {
-	int skip_wfi = 0;
+	int rc = PSCI_E_SUCCESS;
+	bool skip_wfi = false;
 	unsigned int idx = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 
@@ -183,16 +192,45 @@
 	 * detection that a wake-up interrupt has fired.
 	 */
 	if (read_isr_el1() != 0U) {
-		skip_wfi = 1;
+		skip_wfi = true;
 		goto exit;
 	}
 
-	/*
-	 * This function is passed the requested state info and
-	 * it returns the negotiated state info for each power level upto
-	 * the end level specified.
-	 */
-	psci_do_state_coordination(end_pwrlvl, state_info);
+#if PSCI_OS_INIT_MODE
+	if (psci_suspend_mode == OS_INIT) {
+		/*
+		 * This function validates the requested state info for
+		 * OS-initiated mode.
+		 */
+		rc = psci_validate_state_coordination(end_pwrlvl, state_info);
+		if (rc != PSCI_E_SUCCESS) {
+			skip_wfi = true;
+			goto exit;
+		}
+	} else {
+#endif
+		/*
+		 * This function is passed the requested state info and
+		 * it returns the negotiated state info for each power level upto
+		 * the end level specified.
+		 */
+		psci_do_state_coordination(end_pwrlvl, state_info);
+#if PSCI_OS_INIT_MODE
+	}
+#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 */
@@ -208,6 +246,7 @@
 	 * platform defined mailbox with the psci entrypoint,
 	 * program the power controller etc.
 	 */
+
 	psci_plat_pm_ops->pwr_domain_suspend(state_info);
 
 #if ENABLE_PSCI_STAT
@@ -221,8 +260,9 @@
 	 */
 	psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes);
 
-	if (skip_wfi == 1)
-		return;
+	if (skip_wfi) {
+		return rc;
+	}
 
 	if (is_power_down_state != 0U) {
 #if ENABLE_RUNTIME_INSTRUMENTATION
@@ -269,6 +309,8 @@
 	 * context retaining suspend finisher.
 	 */
 	psci_suspend_to_standby_finisher(idx, end_pwrlvl);
+
+	return rc;
 }
 
 /*******************************************************************************
diff --git a/lib/xlat_tables/aarch32/nonlpae_tables.c b/lib/xlat_tables/aarch32/nonlpae_tables.c
index 5646f34..f582404 100644
--- a/lib/xlat_tables/aarch32/nonlpae_tables.c
+++ b/lib/xlat_tables/aarch32/nonlpae_tables.c
@@ -272,7 +272,7 @@
 	/* Make room for new region by moving other regions up by one place */
 	(void)memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm);
 
-	/* Check we haven't lost the empty sentinal from the end of the array */
+	/* Check we haven't lost the empty sentinel from the end of the array */
 	assert(mm_last->size == 0U);
 
 	mm->base_pa = base_pa;
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index 71273cb..e2c8370 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -161,7 +161,7 @@
 	/* Make room for new region by moving other regions up by one place */
 	(void)memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm);
 
-	/* Check we haven't lost the empty sentinal from the end of the array */
+	/* Check we haven't lost the empty sentinel from the end of the array */
 	assert(mm_last->size == 0U);
 
 	mm->base_pa = base_pa;
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 719110a..c847a9e 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,22 +22,23 @@
  */
 bool xlat_arch_is_granule_size_supported(size_t size)
 {
-	u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
+	unsigned int tgranx;
 
 	if (size == PAGE_SIZE_4KB) {
-		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
-			 ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
+		tgranx = read_id_aa64mmfr0_el0_tgran4_field();
+		/* MSB of TGRAN4 field will be '1' for unsupported feature */
+		return ((tgranx >= ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED) &&
+			(tgranx < 8U));
 	} else if (size == PAGE_SIZE_16KB) {
-		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
-			 ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
+		tgranx = read_id_aa64mmfr0_el0_tgran16_field();
+		return (tgranx >= ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED);
 	} else if (size == PAGE_SIZE_64KB) {
-		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
-			 ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
+		tgranx = read_id_aa64mmfr0_el0_tgran64_field();
+		/* MSB of TGRAN64 field will be '1' for unsupported feature */
+		return ((tgranx >= ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED) &&
+			(tgranx < 8U));
 	} else {
-		return 0;
+		return false;
 	}
 }
 
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index de57184..3a9c058 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -988,7 +988,7 @@
 		     (uintptr_t)mm_last - (uintptr_t)mm_cursor);
 
 	/*
-	 * Check we haven't lost the empty sentinal from the end of the array.
+	 * Check we haven't lost the empty sentinel from the end of the array.
 	 * This shouldn't happen as we have checked in mmap_add_region_check
 	 * that there is free space.
 	 */
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index 38a375e..f3a53cc 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -585,7 +585,7 @@
 		base_va += PAGE_SIZE;
 	}
 
-	/* Ensure that the last descriptor writen is seen by the system. */
+	/* Ensure that the last descriptor written is seen by the system. */
 	dsbish();
 
 	return 0;
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 01e3e09..b799697 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -13,6 +13,11 @@
 ENABLE_FEAT_VHE		=	1
 endif
 
+# Enable the features which are mandatory from ARCH version 8.2 and upwards.
+ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_RAS		=	1
+endif
+
 # Enable the features which are mandatory from ARCH version 8.4 and upwards.
 ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
 ENABLE_FEAT_DIT		=	1
diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk
index eec85cc..a8e9d50 100644
--- a/make_helpers/armv7-a-cpus.mk
+++ b/make_helpers/armv7-a-cpus.mk
@@ -15,9 +15,9 @@
 # armClang requires -march=armv7-a for all ARMv7 Cortex-A. To comply with
 # all, just drop -march and supply only -mcpu.
 
-# Platform can override march32-directive through MARCH32_DIRECTIVE
-ifdef MARCH32_DIRECTIVE
-march32-directive		:= $(MARCH32_DIRECTIVE)
+# Platform can override march-directive through MARCH_DIRECTIVE
+ifdef MARCH_DIRECTIVE
+march-directive		:= $(MARCH_DIRECTIVE)
 else
 march32-set-${ARM_CORTEX_A5}	:= -mcpu=cortex-a5
 march32-set-${ARM_CORTEX_A7}	:= -mcpu=cortex-a7
@@ -29,7 +29,7 @@
 
 # default to -march=armv7-a as target directive
 march32-set-yes			?= -march=armv7-a
-march32-directive		:= ${march32-set-yes} ${march32-neon-yes}
+march-directive		:= ${march32-set-yes} ${march32-neon-yes}
 endif
 
 # Platform may override these extension support directives:
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 89f43f2..3bce3a5 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -38,6 +38,18 @@
 $(eval uppercase_result:=$(call uppercase_internal,$(uppercase_table),$(1)))$(uppercase_result)
 endef
 
+# Convenience function for setting a variable to 0 if not previously set
+# $(eval $(call default_zero,FOO))
+define default_zero
+	$(eval $(1) ?= 0)
+endef
+
+# Convenience function for setting a list of variables to 0 if not previously set
+# $(eval $(call default_zeros,FOO BAR))
+define default_zeros
+	$(foreach var,$1,$(eval $(call default_zero,$(var))))
+endef
+
 # Convenience function for adding build definitions
 # $(eval $(call add_define,FOO)) will have:
 # -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
@@ -45,7 +57,6 @@
     DEFINES			+=	-D$(1)$(if $(value $(1)),=$(value $(1)),)
 endef
 
-
 # Convenience function for addding multiple build definitions
 # $(eval $(call add_defines,FOO BOO))
 define add_defines
@@ -62,6 +73,7 @@
 # Convenience function for verifying option has a boolean value
 # $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1
 define assert_boolean
+    $(if $($(1)),,$(error $(1) must not be empty))
     $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean))
 endef
 
@@ -93,6 +105,12 @@
 	$(shell if $(LD) $(1) -v >/dev/null 2>&1; then echo $(1); fi )
 endef
 
+# Convenience function to check for a given compiler option. A call to
+# $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
+define cc_option
+	$(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
+endef
+
 # CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
 # $(2) and assign the sequence to $(1)
 define CREATE_SEQ
@@ -315,7 +333,10 @@
 
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
+
+$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
 $(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
@@ -335,7 +356,10 @@
 
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
+
+$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
 $(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
@@ -354,7 +378,10 @@
 define MAKE_LD
 
 $(eval DEP := $(1).d)
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
+
+$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
 
 $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
 	$$(ECHO) "  PP      $$<"
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index d8c6210..f9077eb 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -133,9 +133,6 @@
 # Use BRANCH_PROTECTION to enable PAUTH.
 ENABLE_PAUTH			:= 0
 
-# Flag to enable access to the HAFGRTR_EL2 register
-ENABLE_FEAT_AMUv1		:= 0
-
 # Flag to enable AMUv1p1 extension.
 ENABLE_FEAT_AMUv1p1		:= 0
 
@@ -179,6 +176,21 @@
 # Flag to enable access to TCR2 (FEAT_TCR2)
 ENABLE_FEAT_TCR2		:= 0
 
+# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE)
+ENABLE_FEAT_S2PIE		:= 0
+
+# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE)
+ENABLE_FEAT_S1PIE		:= 0
+
+# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE)
+ENABLE_FEAT_S2POE		:= 0
+
+# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
+ENABLE_FEAT_S1POE		:= 0
+
+# Flag to enable access to Guarded Control Stack (FEAT_GCS)
+ENABLE_FEAT_GCS			:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
@@ -231,6 +243,9 @@
 # operations.
 HW_ASSISTED_COHERENCY		:= 0
 
+# Flag to enable trapping of implementation defined sytem registers
+IMPDEF_SYSREG_TRAP		:= 0
+
 # Set the default algorithm for the generation of Trusted Board Boot keys
 KEY_ALG				:= rsa
 
@@ -258,15 +273,16 @@
 # Flag used to choose the power state format: Extended State-ID or Original
 PSCI_EXTENDED_STATE_ID		:= 0
 
-# Enable RAS support
-RAS_EXTENSION			:= 0
+# Enable PSCI OS-initiated mode support
+PSCI_OS_INIT_MODE		:= 0
+
+# Enable RAS Support
+ENABLE_FEAT_RAS			:= 0
+RAS_FFH_SUPPORT			:= 0
 
 # By default, BL1 acts as the reset handler, not BL31
 RESET_TO_BL31			:= 0
 
-# By default, clear the input registers when RESET_TO_BL31 is enabled
-RESET_TO_BL31_WITH_PARAMS	:= 0
-
 # For Chain of Trust
 SAVE_KEYS			:= 0
 
@@ -276,6 +292,12 @@
 # True Random Number firmware Interface support
 TRNG_SUPPORT			:= 0
 
+# Check to see if Errata ABI is supported
+ERRATA_ABI_SUPPORT		:= 0
+
+# Check to enable Errata ABI for platforms with non-arm interconnect
+ERRATA_NON_ARM_INTERCONNECT	:= 0
+
 # SMCCC PCI support
 SMC_PCI_SUPPORT			:= 0
 
@@ -355,11 +377,11 @@
 WARMBOOT_ENABLE_DCACHE_EARLY	:= 0
 
 # Build option to enable/disable the Statistical Profiling Extensions
-ENABLE_SPE_FOR_LOWER_ELS	:= 1
+ENABLE_SPE_FOR_NS		:= 2
 
 # SPE is only supported on AArch64 so disable it on AArch32.
 ifeq (${ARCH},aarch32)
-	override ENABLE_SPE_FOR_LOWER_ELS := 0
+	override ENABLE_SPE_FOR_NS := 0
 endif
 
 # Include Memory Tagging Extension registers in cpu context. This must be set
@@ -367,13 +389,13 @@
 # enabled at ELX.
 CTX_INCLUDE_MTE_REGS		:= 0
 
-ENABLE_AMU			:= 0
+ENABLE_FEAT_AMU			:= 0
 ENABLE_AMU_AUXILIARY_COUNTERS	:= 0
 ENABLE_AMU_FCONF		:= 0
 AMU_RESTRICT_COUNTERS		:= 0
 
 # Enable SVE for non-secure world by default
-ENABLE_SVE_FOR_NS		:= 1
+ENABLE_SVE_FOR_NS		:= 2
 # SVE is only supported on AArch64 so disable it on AArch32.
 ifeq (${ARCH},aarch32)
 	override ENABLE_SVE_FOR_NS	:= 0
@@ -386,12 +408,7 @@
 # SME defaults to disabled
 ENABLE_SME_FOR_NS		:= 0
 ENABLE_SME_FOR_SWD		:= 0
-
-# If SME is enabled then force SVE off
-ifeq (${ENABLE_SME_FOR_NS},1)
-	override ENABLE_SVE_FOR_NS	:= 0
-	override ENABLE_SVE_FOR_SWD	:= 0
-endif
+ENABLE_SME2_FOR_NS		:= 0
 
 SANITIZE_UB := off
 
diff --git a/make_helpers/march.mk b/make_helpers/march.mk
new file mode 100644
index 0000000..2417709
--- /dev/null
+++ b/make_helpers/march.mk
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This build helper makefile is used to determine a suitable march build
+# option to be used, based on platform provided ARM_ARCH_MAJOR/MINOR
+# data and compiler supported march version.
+
+# Set the compiler's target architecture profile based on
+# ARM_ARCH_MAJOR and ARM_ARCH_MINOR options.
+
+
+# This is used to collect available march values from compiler.
+# Example on a gcc-12.2 arm64 toolchain it will look like:
+# [...]
+#./aarch64-none-elf-gcc --target-help -march=foo
+# cc1: error: unknown value 'foo' for '-march'
+# cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a
+# armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
+# [...]
+#
+GCC_MARCH_OUTPUT := $(shell $(CC) -march=foo -Q --help=target -v 2>&1)
+
+# This function is used to find the best march value supported by the given compiler.
+# We try to use `GCC_MARCH_OUTPUT` which has verbose message with supported march values we filter that
+# to find armvX.Y-a or armvX-a values, then filter the best supported arch based on ARM_ARCH_MAJOR.
+#
+# Example on a gcc-12.2 arm64 toolchain this will return armv9-a if platform requested for armv9.2-a
+# Similarly on gcc 11.3 it would return armv8.6-a if platform requested armv8.8-a
+define major_best_avail_march
+$(1) := $(lastword $(filter armv$(ARM_ARCH_MAJOR)% ,$(filter armv%-a, $(GCC_MARCH_OUTPUT))))
+endef
+
+# This function is used to just return latest march value supported by the given compiler.
+#
+# Example: this would return armv8.6-a on a gcc-11.3 when platform requested for armv9.0-a
+#
+# Thus this function should be used in conjunction with major_best_avail_march, when best match
+# is not found it should be ok to try with lastest known supported march value from the
+# compiler.
+define latest_match_march
+$(1) := $(lastword $(filter armv%-a, $(GCC_MARCH_OUTPUT)))
+endef
+
+ifdef MARCH_DIRECTIVE
+    march-directive		:= $(MARCH_DIRECTIVE)
+else
+
+ifeq (${ARM_ARCH_MINOR},0)
+    provided-march = armv${ARM_ARCH_MAJOR}-a
+else
+    provided-march = armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+endif
+
+ifeq ($(findstring clang,$(notdir $(CC))),)
+
+# We expect from Platform to provide a correct Major/Minor value but expecting something
+# from compiler with unsupported march means we shouldn't fail without trying anything,
+# so here we try to find best supported march value and use that for compilation.
+# If we don't support current march version from gcc compiler, try with lower arch based on
+# availability. In TF-A there is no hard rule for need of higher version march for basic
+# functionality, denying a build on only this fact doesn't look correct, so try with best
+# or latest march values from whats available from compiler.
+ifeq (,$(findstring $(provided-march), $(GCC_MARCH_OUTPUT)))
+    $(eval $(call major_best_avail_march, available-march))
+
+ifeq (, $(available-march))
+    $(eval $(call latest_match_march, available-march))
+endif
+
+# If we fail to come up with any available-march value so far, don't update
+# provided-march and thus allow the build to fail using the provided-march
+# which is derived based on arch_major and arch_minor values.
+ifneq (,$(available-march))
+    provided-march := ${available-march}
+endif
+
+endif # provided-march supported
+endif # not clang
+
+march-directive := -march=${provided-march}
+
+endif # MARCH_DIRECTIVE
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 8605bae..a3351eb 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -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
 #
@@ -43,10 +43,14 @@
 # Default non-volatile counter values (overridable by the platform)
 TFW_NVCTR_VAL		?=	0
 NTFW_NVCTR_VAL		?=	0
+CCAFW_NVCTR_VAL		?=	0
 
 # Pass the non-volatile counters to the cert_create tool
 $(eval $(call CERT_ADD_CMD_OPT,${TFW_NVCTR_VAL},--tfw-nvctr))
 $(eval $(call CERT_ADD_CMD_OPT,${NTFW_NVCTR_VAL},--ntfw-nvctr))
+ifeq (${COT},cca)
+$(eval $(call CERT_ADD_CMD_OPT,${CCAFW_NVCTR_VAL},--ccafw-nvctr))
+endif
 
 # Add Trusted Key certificate to the fiptool and cert_create command line options
 ifneq (${COT},cca)
diff --git a/package-lock.json b/package-lock.json
index a3e0ff9..89ebd51 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.8.0",
+  "version": "2.9.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "trusted-firmware-a",
-      "version": "2.8.0",
+      "version": "2.9.0",
       "hasInstallScript": true,
       "license": "BSD-3-Clause",
       "devDependencies": {
diff --git a/package.json b/package.json
index 8d4dd54..8b724dae 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.8.0",
+  "version": "2.9.0",
   "license": "BSD-3-Clause",
   "private": true,
   "scripts": {
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 61c1dbe..3164a25 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -87,7 +87,7 @@
 COLD_BOOT_SINGLE_CPU		:=	1
 
 # Do not enable SPE (not supported on ARM v8.0).
-ENABLE_SPE_FOR_LOWER_ELS	:=	0
+ENABLE_SPE_FOR_NS		:=	0
 
 # Do not enable SVE (not supported on ARM v8.0).
 ENABLE_SVE_FOR_NS		:=	0
diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h
new file mode 100644
index 0000000..22828c2
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
+/* The T507 datasheet does not mention this register. */
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_C0_CPU_CTRL_REG(n)	(SUNXI_CPUCFG_BASE + 0x0060 + (n) * 4)
+
+#define SUNXI_CPU_CTRL_REG(n)		(SUNXI_CPUSUBSYS_BASE + 0x20 + (n) * 4)
+#define SUNXI_ALT_RVBAR_LO_REG(n)	(SUNXI_CPUSUBSYS_BASE + 0x40 + (n) * 8)
+#define SUNXI_ALT_RVBAR_HI_REG(n)	(SUNXI_CPUSUBSYS_BASE + 0x44 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+#define SUNXI_CPU_UNK_REG(n)		(SUNXI_R_CPUCFG_BASE + 0x0070 + (n) * 4)
+
+#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
+#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
+#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
+#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		24
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
new file mode 100644
index 0000000..d4aec19
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		4
+
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index c17ef95..20f6c49 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -20,6 +20,7 @@
 #define SUNXI_SOC_H616			0x1823
 #define SUNXI_SOC_R329			0x1851
 
+#define SUNXI_VER_BITS_MASK		0xffU
 #define JEDEC_ALLWINNER_BKID		9U
 #define JEDEC_ALLWINNER_MFID		0x9eU
 
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 092659c..62f4fcb 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -183,5 +183,5 @@
 {
 	uint32_t reg = mmio_read_32(SRAM_VER_REG);
 
-	return reg & GENMASK_32(7, 0);
+	return reg & SUNXI_VER_BITS_MASK;
 }
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 46e7090..30841e2 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -19,6 +19,12 @@
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
+#ifndef SUNXI_C0_CPU_CTRL_REG
+#define SUNXI_C0_CPU_CTRL_REG(n)	0
+#define SUNXI_CPU_UNK_REG(n)		0
+#define SUNXI_CPU_CTRL_REG(n)		0
+#endif
+
 static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
 {
 	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
@@ -53,15 +59,30 @@
 
 	VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core);
 
-	/* Deassert DBGPWRDUP */
-	mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
-	/* Activate the core output clamps, but not for core 0. */
-	if (core != 0)
-		mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
-	/* Assert CPU power-on reset */
-	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Remove power from the CPU */
-	sunxi_cpu_disable_power(cluster, core);
+	if (sunxi_cpucfg_has_per_cluster_regs()) {
+		/* Deassert DBGPWRDUP */
+		mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+		/* Activate the core output clamps, but not for core 0. */
+		if (core != 0) {
+			mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster),
+					BIT(core));
+		}
+		/* Assert CPU power-on reset */
+		mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Remove power from the CPU */
+		sunxi_cpu_disable_power(cluster, core);
+	} else {
+		/* power down(?) debug core */
+		mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8));
+		/* ??? Activate the core output clamps, but not for core 0 */
+		if (core != 0) {
+			mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(1));
+		}
+		/* ??? Assert CPU power-on reset ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+		/* Remove power from the CPU */
+		sunxi_cpu_disable_power(cluster, core);
+	}
 }
 
 void sunxi_cpu_on(u_register_t mpidr)
@@ -71,23 +92,45 @@
 
 	VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core);
 
+	if (sunxi_cpucfg_has_per_cluster_regs()) {
+		/* Assert CPU core reset */
+		mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+		/* Assert CPU power-on reset */
+		mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Set CPU to start in AArch64 mode */
+		mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
+				BIT(SUNXI_AA64nAA32_OFFSET + core));
+		/* Apply power to the CPU */
+		sunxi_cpu_enable_power(cluster, core);
+		/* Release the core output clamps */
+		mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
+		/* Deassert CPU power-on reset */
+		mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Deassert CPU core reset */
+		mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+		/* Assert DBGPWRDUP */
+		mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+	} else {
+		/* Assert CPU core reset */
+		mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0));
+		/* ??? Assert CPU power-on reset ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+
+		/* Set CPU to start in AArch64 mode */
+		mmio_setbits_32(SUNXI_CPU_CTRL_REG(core), BIT(0));
+
+		/* Apply power to the CPU */
+		sunxi_cpu_enable_power(cluster, core);
+
-	/* Assert CPU core reset */
-	mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
-	/* Assert CPU power-on reset */
-	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Set CPU to start in AArch64 mode */
-	mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
-			BIT(SUNXI_AA64nAA32_OFFSET + core));
-	/* Apply power to the CPU */
-	sunxi_cpu_enable_power(cluster, core);
-	/* Release the core output clamps */
-	mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
-	/* Deassert CPU power-on reset */
-	mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Deassert CPU core reset */
-	mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
-	/* Assert DBGPWRDUP */
-	mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+		/* ??? Release the core output clamps ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(1));
+		/* ??? Deassert CPU power-on reset ??? */
+		mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+		/* Deassert CPU core reset */
+		mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0));
+		/* power up(?) debug core */
+		mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8));
+	}
 }
 
 void sunxi_cpu_power_off_others(void)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 3772b4a..ebc406b 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -25,6 +25,11 @@
 }
 #endif
 
+#ifndef SUNXI_ALT_RVBAR_LO_REG
+#define SUNXI_ALT_RVBAR_LO_REG(n)	0
+#define SUNXI_ALT_RVBAR_HI_REG(n)	0
+#endif
+
 int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
 {
 	/* The non-secure entry point must be in DRAM */
@@ -42,10 +47,17 @@
 
 	/* Program all CPU entry points. */
 	for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) {
-		mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
-			      sec_entrypoint & 0xffffffff);
-		mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
-			      sec_entrypoint >> 32);
+		if (sunxi_cpucfg_has_per_cluster_regs()) {
+			mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
+				      sec_entrypoint & 0xffffffff);
+			mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
+				      sec_entrypoint >> 32);
+		} else {
+			mmio_write_32(SUNXI_ALT_RVBAR_LO_REG(cpu),
+				      sec_entrypoint & 0xffffffff);
+			mmio_write_32(SUNXI_ALT_RVBAR_HI_REG(cpu),
+				      sec_entrypoint >> 32);
+		}
 	}
 
 	if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
index aed3585..ddd53ba 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
@@ -36,4 +36,9 @@
 #define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
 #define SUNXI_AA64nAA32_OFFSET		24
 
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
+
 #endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
index 5bfda5d..585c51b 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
@@ -1,35 +1,6 @@
-/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
-#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
-#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
-#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		24
+#include <sunxi_cpucfg_ncat.h>
 
-#endif /* SUNXI_CPUCFG_H */
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index 58216d8..43133be 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -59,5 +59,6 @@
 #define SUNXI_R_RSB_BASE		0x07083000
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_PIO_BASE		0x07022000
+#define SUNXI_CPUSUBSYS_BASE		0x08100000
 
 #endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
index dab663b..5c590e4 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
@@ -1,35 +1,8 @@
-/*
- * Copyright (c) 2017-2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
+#include <plat/common/platform.h>
 
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
-#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
-#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
-#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		24
+#include <sunxi_cpucfg_ncat.h>
 
-#endif /* SUNXI_CPUCFG_H */
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return (plat_get_soc_revision() != 2);
+}
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
index 3b4f4a0..24a4ba8 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
@@ -41,6 +41,7 @@
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_I2C_BASE		0x07081400
 #define SUNXI_R_RSB_BASE		0x07083000
+#define SUNXI_CPUSUBSYS_BASE		0x08100000
 #define SUNXI_CPUCFG_BASE		0x09010000
 
 #endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
index 9478f32..3c3530f 100644
--- a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
@@ -1,31 +1 @@
-/*
- * Copyright (c) 2021 Sipeed
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
-#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		4
-
-#endif /* SUNXI_CPUCFG_H */
+#include <sunxi_cpucfg_ncat2.h>
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index 4f87306..6fcf080 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -100,6 +100,8 @@
 
 MULTI_CONSOLE_API		:=	1
 
+ARM_DISABLE_TRUSTED_WDOG	:=	1
+
 PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/aarch32/nonlpae_tables.c
 
 # Use translation tables library v1 when using Cortex-A5
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index e1b3abb..1a38f25 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <errno.h>
 
+#include <arch_features.h>
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv3.h>
@@ -364,7 +365,7 @@
 	fpga_dtb_update_clock(fdt, system_freq);
 
 	/* Check whether we support the SPE PMU. Remove the DT node if not. */
-	if (!spe_supported()) {
+	if (!is_feat_spe_supported()) {
 		int node = fdt_node_offset_by_compatible(fdt, 0,
 				     "arm,statistical-profiling-extension-v1");
 
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index a14a0d8..c9425c5 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -33,7 +33,7 @@
 FPGA_PRELOADED_CMD_LINE := 0x1000
 $(eval $(call add_define,FPGA_PRELOADED_CMD_LINE))
 
-ENABLE_AMU		:=	1
+ENABLE_FEAT_AMU		:=	2
 
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
@@ -58,23 +58,19 @@
 				lib/cpus/aarch64/cortex_a73.S
 else
 # AArch64-only cores
-	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a76.S		\
-				lib/cpus/aarch64/cortex_a76ae.S		\
-				lib/cpus/aarch64/cortex_a77.S		\
-				lib/cpus/aarch64/cortex_a78.S		\
-				lib/cpus/aarch64/neoverse_n_common.S	\
-				lib/cpus/aarch64/neoverse_n1.S		\
-				lib/cpus/aarch64/neoverse_n2.S		\
-				lib/cpus/aarch64/neoverse_e1.S		\
-				lib/cpus/aarch64/neoverse_v1.S		\
-				lib/cpus/aarch64/cortex_a78_ae.S	\
-				lib/cpus/aarch64/cortex_a65.S		\
-				lib/cpus/aarch64/cortex_a65ae.S		\
-				lib/cpus/aarch64/cortex_a510.S		\
-				lib/cpus/aarch64/cortex_a710.S		\
-				lib/cpus/aarch64/cortex_a715.S		\
-				lib/cpus/aarch64/cortex_x3.S 		\
-				lib/cpus/aarch64/cortex_a78c.S
+	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a510.S			\
+				lib/cpus/aarch64/cortex_a520.S			\
+				lib/cpus/aarch64/cortex_a710.S			\
+				lib/cpus/aarch64/cortex_a715.S			\
+				lib/cpus/aarch64/cortex_a720.S			\
+				lib/cpus/aarch64/cortex_x3.S 			\
+				lib/cpus/aarch64/cortex_x4.S			\
+				lib/cpus/aarch64/neoverse_n_common.S		\
+				lib/cpus/aarch64/neoverse_n1.S			\
+				lib/cpus/aarch64/neoverse_n2.S			\
+				lib/cpus/aarch64/neoverse_v1.S			\
+				lib/cpus/aarch64/cortex_chaberton.S		\
+				lib/cpus/aarch64/cortex_blackhawk.S
 
 # AArch64/AArch32 cores
 	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S	\
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index d73c2e3..777784d 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -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
 #
@@ -67,11 +67,16 @@
 # ARM development platforms
 TFW_NVCTR_VAL	?=	31
 NTFW_NVCTR_VAL	?=	223
+# The CCA Non-Volatile Counter only exists on some Arm development platforms.
+# On others, we mock it by aliasing it to the Trusted Firmware Non-Volatile counter,
+# hence we set both counters to the same default value.
+CCAFW_NVCTR_VAL	?=	31
 else
 # Certificate NV-Counters when CryptoCell is integrated. For development
 # platforms we set the counter to first valid value.
 TFW_NVCTR_VAL	?=	0
 NTFW_NVCTR_VAL	?=	0
+CCAFW_NVCTR_VAL	?=	0
 endif
 BL1_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c \
 				${ARM_ROTPK_S}
diff --git a/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c b/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c
new file mode 100644
index 0000000..2549d35
--- /dev/null
+++ b/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index d891691..3edffe0 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -56,6 +56,7 @@
 			plat/arm/board/corstone1000/common/corstone1000_security.c		\
 			plat/arm/board/corstone1000/common/corstone1000_plat.c		\
 			plat/arm/board/corstone1000/common/corstone1000_pm.c		\
+			plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c	\
 			${CORSTONE1000_CPU_LIBS}					\
 			${CORSTONE1000_GIC_SOURCES}
 
diff --git a/plat/arm/board/fvp/aarch64/fvp_ea.c b/plat/arm/board/fvp/aarch64/fvp_ea.c
new file mode 100644
index 0000000..07053a9
--- /dev/null
+++ b/plat/arm/board/fvp/aarch64/fvp_ea.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <bl31/ea_handle.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <plat/common/platform.h>
+
+/*
+ * This source file with custom plat_ea_handler function is compiled only when
+ * building TF-A with compile option PLATFORM_TEST_EA_FFH
+ */
+
+/* Test address(non-existent) used in tftf to cause External aborts */
+#define TEST_ADDRESS	UL(0x7FFFF000)
+
+void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
+		void *handle, uint64_t flags)
+{
+#ifdef PLATFORM_TEST_EA_FFH
+	u_register_t elr_el3;
+	u_register_t fault_address;
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	el3_state_t *el3_ctx = get_el3state_ctx(ctx);
+	gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx);
+	unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
+
+	fault_address = read_ctx_reg(gpregs_ctx, CTX_GPREG_X0);
+
+	if ((level < MODE_EL3) && (fault_address == TEST_ADDRESS)) {
+		if (ea_reason == ERROR_EA_SYNC) {
+			INFO("Handled sync EA from lower EL at address 0x%lx\n", fault_address);
+			/* To avoid continuous faults, forward return address */
+			elr_el3 = read_ctx_reg(el3_ctx, CTX_ELR_EL3);
+			elr_el3 += 4;
+			write_ctx_reg(el3_ctx, CTX_ELR_EL3, elr_el3);
+			return;
+		} else if (ea_reason == ERROR_EA_ASYNC) {
+			INFO("Handled Serror from lower EL at address 0x%lx\n", fault_address);
+			return;
+		}
+	}
+#endif
+	plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
+}
diff --git a/plat/arm/board/fvp/aarch64/fvp_ras.c b/plat/arm/board/fvp/aarch64/fvp_ras.c
index 759f6d0..f9b9634 100644
--- a/plat/arm/board/fvp/aarch64/fvp_ras.c
+++ b/plat/arm/board/fvp/aarch64/fvp_ras.c
@@ -4,12 +4,63 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <lib/extensions/ras.h>
+#include <services/sdei.h>
+
+#ifdef PLATFORM_TEST_RAS_FFH
+static int injected_fault_handler(const struct err_record_info *info,
+		int probe_data, const struct err_handler_data *const data)
+{
+	uint64_t status;
+	int ret;
+
+	/*
+	 * The faulting error record is already selected by the SER probe
+	 * function.
+	 */
+	status = read_erxstatus_el1();
+
+	ERROR("Fault reported by system error record %d on 0x%lx: status=0x%" PRIx64 "\n",
+			probe_data, read_mpidr_el1(), status);
+	ERROR(" exception reason=%u syndrome=0x%" PRIx64 "\n", data->ea_reason,
+			data->flags);
+
+	/* Clear error */
+	write_erxstatus_el1(status);
+
+	ret = sdei_dispatch_event(5000);
+	if (ret < 0) {
+		ERROR("Can't dispatch event to SDEI\n");
+		panic();
+	} else {
+		INFO("SDEI event dispatched\n");
+	}
+
+	return 0;
+}
+
+void plat_handle_uncontainable_ea(void)
+{
+	/* Do not change the string, CI expects it. Wait forever */
+	INFO("Injected Uncontainable Error\n");
+	while (true) {
+		wfe();
+	}
+}
+#endif
 
 struct ras_interrupt fvp_ras_interrupts[] = {
 };
 
 struct err_record_info fvp_err_records[] = {
+#ifdef PLATFORM_TEST_RAS_FFH
+	/* Record for injected fault */
+	ERR_RECORD_SYSREG_V1(0, 2, ras_err_ser_probe_sysreg,
+			injected_fault_handler, NULL),
+#endif
 };
 
 REGISTER_ERR_RECORD_INFO(fvp_err_records);
diff --git a/plat/arm/board/fvp/fdts/event_log.dtsi b/plat/arm/board/fvp/fdts/event_log.dtsi
index 47af672..8e26542 100644
--- a/plat/arm/board/fvp/fdts/event_log.dtsi
+++ b/plat/arm/board/fvp/fdts/event_log.dtsi
@@ -9,4 +9,5 @@
 	compatible = "arm,tpm_event_log";
 	tpm_event_log_addr = <0x0 0x0>;
 	tpm_event_log_size = <0x0>;
+	tpm_event_log_max_size = <0x0>;
 };
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 4543671..4f97339 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -78,9 +78,17 @@
 		CPU_1
 	};
 
-	memory@6000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+		reg = <0x0 0xfd000000 0x0 0x2000000>,
+		      <0x0 0x7000000 0x0 0x1000000>,
+		      <0x0 0xff000000 0x0 0x1000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x0 0x10000000>;
 	};
 
 #if MEASURED_BOOT
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 6fd334d..6ba76db 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,7 +59,7 @@
 			soc_fw_content_cert_uuid = "e2b20c20-5e63-e411-9ce8-abccf92bb666";
 			tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d";
 			nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7";
-			sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f";
+			plat_sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f";
 		};
 	};
 #endif /* ARM_IO_IN_DTB */
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index 76cd918..b8431c5 100644
--- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,7 +54,7 @@
 	event_log_init(event_log, event_log + sizeof(event_log));
 	event_log_write_header();
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(fvp_rss_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
@@ -63,7 +63,8 @@
 
 	event_log_cur_size = event_log_get_cur_size(event_log);
 	int rc = arm_set_tb_fw_info((uintptr_t)event_log,
-				    event_log_cur_size);
+				    event_log_cur_size,
+				    PLAT_ARM_EVENT_LOG_MAX_SIZE);
 	if (rc != 0) {
 		/*
 		 * It is a fatal error because on FVP platform, BL2 software
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 7b0673a..564118e 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -90,9 +90,11 @@
 	uint8_t *event_log_start;
 	uint8_t *event_log_finish;
 	size_t bl1_event_log_size;
+	size_t event_log_max_size;
 	int rc;
 
-	rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size);
+	rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size,
+				&event_log_max_size);
 	if (rc != 0) {
 		ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n",
 		      __func__);
@@ -111,11 +113,11 @@
 	event_log_start = (uint8_t *)((uintptr_t)event_log_base +
 				      bl1_event_log_size);
 	event_log_finish = (uint8_t *)((uintptr_t)event_log_base +
-				       PLAT_ARM_EVENT_LOG_MAX_SIZE);
+				       event_log_max_size);
 
 	event_log_init((uint8_t *)event_log_start, event_log_finish);
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(fvp_rss_mboot_metadata);
 }
 
 int plat_mboot_measure_critical_data(unsigned int critical_data_id,
diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c
index b5b8f10..7419e5e 100644
--- a/plat/arm/board/fvp/fvp_common_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_common_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,11 +16,6 @@
 extern event_log_metadata_t fvp_event_log_metadata[];
 extern struct rss_mboot_metadata fvp_rss_mboot_metadata[];
 
-struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
-{
-	return fvp_rss_mboot_metadata;
-}
-
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
@@ -38,7 +33,8 @@
 	}
 
 	/* Calculate image hash and record data in RSS */
-	err = rss_mboot_measure_and_record(image_data->image_base,
+	err = rss_mboot_measure_and_record(fvp_rss_mboot_metadata,
+					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
 	if (err != 0) {
diff --git a/plat/arm/board/fvp/fvp_cpu_errata.mk b/plat/arm/board/fvp/fvp_cpu_errata.mk
new file mode 100644
index 0000000..944571d
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_errata.mk
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+#/*
+# * TODO: below lines of code to be removed
+# * after abi and framework are synchronized
+# */
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+# enable the cpu macros for errata abi interface
+ifeq (${ARCH}, aarch64)
+ifeq (${HW_ASSISTED_COHERENCY}, 0)
+CORTEX_A35_H_INC	:= 1
+CORTEX_A53_H_INC	:= 1
+CORTEX_A57_H_INC	:= 1
+CORTEX_A72_H_INC	:= 1
+CORTEX_A73_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A35_H_INC))
+$(eval $(call add_define, CORTEX_A53_H_INC))
+$(eval $(call add_define, CORTEX_A57_H_INC))
+$(eval $(call add_define, CORTEX_A72_H_INC))
+$(eval $(call add_define, CORTEX_A73_H_INC))
+else
+ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0)
+CORTEX_A76_H_INC	:= 1
+CORTEX_A77_H_INC	:= 1
+CORTEX_A78_H_INC	:= 1
+NEOVERSE_N1_H_INC	:= 1
+NEOVERSE_V1_H_INC	:= 1
+CORTEX_A78_AE_H_INC	:= 1
+CORTEX_A510_H_INC	:= 1
+CORTEX_A710_H_INC	:= 1
+CORTEX_A715_H_INC 	:= 1
+CORTEX_A78C_H_INC	:= 1
+CORTEX_X2_H_INC		:= 1
+$(eval $(call add_define, CORTEX_A76_H_INC))
+$(eval $(call add_define, CORTEX_A77_H_INC))
+$(eval $(call add_define, CORTEX_A78_H_INC))
+$(eval $(call add_define, NEOVERSE_N1_H_INC))
+$(eval $(call add_define, NEOVERSE_V1_H_INC))
+$(eval $(call add_define, CORTEX_A78_AE_H_INC))
+$(eval $(call add_define, CORTEX_A510_H_INC))
+$(eval $(call add_define, CORTEX_A710_H_INC))
+$(eval $(call add_define, CORTEX_A715_H_INC))
+$(eval $(call add_define, CORTEX_A78C_H_INC))
+$(eval $(call add_define, CORTEX_X2_H_INC))
+endif
+CORTEX_A55_H_INC	:= 1
+CORTEX_A75_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A55_H_INC))
+$(eval $(call add_define, CORTEX_A75_H_INC))
+endif
+else
+CORTEX_A32_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A32_H_INC))
+endif
+endif
diff --git a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
index b9e4f86..72dfa30 100644
--- a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
+++ b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
@@ -27,6 +27,7 @@
 					  void *handle, uint64_t flags)
 {
 	uint64_t ret;
+	uint32_t src_dst;
 
 	/* Determine if we have a 64 or 32 direct request. */
 	if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) {
@@ -36,18 +37,22 @@
 	} else {
 		panic(); /* Unknown SMC. */
 	}
+
 	/*
 	 * Handle the incoming request. For testing purposes we echo the
 	 * incoming message.
 	 */
-	INFO("Logical Partition: Received Direct Request from %s world!\n",
-	     secure_origin ? "Secure" : "Normal");
+	INFO("LSP: Received Direct Request from %s world (0x%x)\n",
+	     secure_origin ? "Secure" : "Normal", ffa_endpoint_source(x1));
 
+	/* Populate the source and destination IDs. */
+	src_dst = (uint32_t) LP_PARTITION_ID << FFA_DIRECT_MSG_SOURCE_SHIFT |
+		  ffa_endpoint_source(x1) << FFA_DIRECT_MSG_DESTINATION_SHIFT;
 	/*
 	 * Logical SP's must always send a direct response so we can populate
 	 * our response directly.
 	 */
-	SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0);
+	SMC_RET8(handle, ret, src_dst, 0, x4, 0, 0, 0, 0);
 }
 
 /* Register logical partition  */
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index dda2156..5af2405 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -1,113 +1,26 @@
 /*
- * 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
  */
 
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
+#include <delegated_attestation.h>
+#include <psa/error.h>
 
-/* Using hardcoded token values for AEM FVP */
-static uint8_t platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
-	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
-	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
-	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
-};
-
+/*
+ * Get the platform attestation token through the PSA delegated attestation
+ * layer.
+ *
+ * FVP cannot support RSS hardware at the moment, but it can still mock the
+ * RSS implementation of the PSA interface (see PLAT_RSS_NOT_SUPPORTED).
+ */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
 				   uintptr_t hash, size_t hash_size)
 {
-	(void)hash;
-	(void)hash_size;
+	psa_status_t ret;
 
-	if (*len < sizeof(platform_token)) {
-		return -EINVAL;
-	}
-
-	(void)memcpy((void *)buf, platform_token, sizeof(platform_token));
-	*len = sizeof(platform_token);
+	ret = rss_delegated_attest_get_token((const uint8_t *)hash, hash_size,
+					     (uint8_t *)buf, *len, len);
 
-	return 0;
+	return ret;
 }
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 6b9d618..b8c97f8 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv3.h>
@@ -53,13 +54,13 @@
 {
 	uint64_t mpidr = read_mpidr_el1();
 
-#if ENABLE_SPE_FOR_LOWER_ELS
 	/*
 	 * On power down we need to disable statistical profiling extensions
 	 * before exiting coherency.
 	 */
-	spe_disable();
-#endif
+	if (is_feat_spe_supported()) {
+		spe_disable();
+	}
 
 	/* Disable coherency if this cluster is to be turned off */
 	fvp_interconnect_disable();
@@ -269,6 +270,8 @@
 
 	/* Program the power controller to power off this cpu. */
 	fvp_pwrc_write_ppoffr(read_mpidr_el1());
+
+	return;
 }
 
 /*******************************************************************************
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
index 1af1f0d..26354f4 100644
--- a/plat/arm/board/fvp/fvp_realm_attest_key.c
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -1,36 +1,30 @@
 /*
- * 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
  */
 
 #include <assert.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
+#include <delegated_attestation.h>
+#include <psa/error.h>
 #include <services/rmmd_svc.h>
 
-static uint8_t sample_attest_priv_key[] = {
-	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
-	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
-	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
-	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
-	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
-};
-
+/*
+ * Get the delegated realm attestation key through the PSA delegated
+ * attestation layer.
+ *
+ * FVP cannot support RSS hardware at the moment, but it can still mock
+ * the RSS implementation of the PSA interface (see PLAT_RSS_NOT_SUPPORTED).
+ */
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type)
 {
-	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
+	psa_status_t ret;
 
-	if (*len < sizeof(sample_attest_priv_key)) {
-		return -EINVAL;
-	}
+	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
 
-	(void)memcpy((void *)buf, sample_attest_priv_key,
-		     sizeof(sample_attest_priv_key));
-	*len = sizeof(sample_attest_priv_key);
+	ret = rss_delegated_attest_get_delegated_key(0U, 0U, (uint8_t *)buf,
+						     *len, len, 0U);
 
-	return 0;
+	return ret;
 }
diff --git a/plat/arm/board/fvp/fvp_spmd.c b/plat/arm/board/fvp/fvp_spmd.c
new file mode 100644
index 0000000..8213e5e
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_spmd.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/*
+	 * As of now, there are no sources of Group0 secure interrupt enabled
+	 * for FVP.
+	 */
+	(void)intid;
+	return -1;
+}
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index 1ea37f7..4c3201e 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 #include <plat/arm/common/fconf_nv_cntr_getter.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
-#include <tools_share/tbbr_oid.h>
+#include <tools_share/cca_oid.h>
 
 /*
  * Return the ROTPK hash in the following ASN.1 structure in DER format:
@@ -36,6 +36,33 @@
 }
 
 /*
+ * 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
+ */
+static int plat_get_nv_ctr_addr(void *cookie, uintptr_t *nv_ctr_addr)
+{
+	const char *oid = (const char *)cookie;
+
+	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+		*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,
+						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,
+						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
@@ -45,20 +72,14 @@
  */
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
 {
-	const char *oid;
 	uintptr_t nv_ctr_addr;
+	int rc;
 
 	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,
-						TRUSTED_NV_CTR_ID);
-	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
-						NON_TRUSTED_NV_CTR_ID);
-	} else {
-		return 1;
+	rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr);
+	if (rc != 0) {
+		return rc;
 	}
 
 	mmio_write_32(nv_ctr_addr, nv_ctr);
@@ -69,3 +90,27 @@
 	 */
 	return (mmio_read_32(nv_ctr_addr) == nv_ctr) ? 0 : 1;
 }
+
+/*
+ * Return the non-volatile counter value stored in the platform. The cookie
+ * will contain the OID of the counter in the certificate.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+	uintptr_t nv_ctr_addr;
+	int rc;
+
+	assert(cookie != NULL);
+	assert(nv_ctr != NULL);
+
+	rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr);
+	if (rc != 0) {
+		return rc;
+	}
+
+	*nv_ctr = *((unsigned int *)nv_ctr_addr);
+
+	return 0;
+}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 039f8e2..99dd6c7 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -30,6 +30,10 @@
 
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
 
+#if PSCI_OS_INIT_MODE
+#define PLAT_MAX_CPU_SUSPEND_PWR_LVL	ARM_PWR_LVL1
+#endif
+
 /*
  * Other platform porting definitions are provided by included headers
  */
@@ -39,7 +43,7 @@
  */
 #define PLAT_ARM_CLUSTER_COUNT		U(FVP_CLUSTER_COUNT)
 
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	UL(0x00040000)	/* 256 KB */
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	(FVP_TRUSTED_SRAM_SIZE * UL(1024))
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	UL(0x00000000)
 #define PLAT_ARM_TRUSTED_ROM_SIZE	UL(0x04000000)	/* 64 MB */
@@ -226,9 +230,12 @@
 /*
  * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
  * calculated using the current BL31 PROGBITS debug size plus the sizes of
- * BL2 and BL1-RW
+ * BL2 and BL1-RW.
+ * Size of the BL31 PROGBITS increases as the SRAM size increases.
  */
-#define PLAT_ARM_MAX_BL31_SIZE		(UL(0x3D000) - ARM_L0_GPT_SIZE)
+#define PLAT_ARM_MAX_BL31_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
+					 ARM_SHARED_RAM_SIZE - \
+					 ARM_FW_CONFIGS_SIZE - ARM_L0_GPT_SIZE)
 #endif /* RESET_TO_BL31 */
 
 #ifndef __aarch64__
@@ -393,14 +400,24 @@
 #define PLAT_SDEI_DP_EVENT_MAX_CNT	ARM_SDEI_DP_EVENT_MAX_CNT
 #define PLAT_SDEI_DS_EVENT_MAX_CNT	ARM_SDEI_DS_EVENT_MAX_CNT
 #else
-#define PLAT_ARM_PRIVATE_SDEI_EVENTS	ARM_SDEI_PRIVATE_EVENTS
+  #if PLATFORM_TEST_RAS_FFH
+  #define PLAT_ARM_PRIVATE_SDEI_EVENTS \
+	ARM_SDEI_PRIVATE_EVENTS, \
+	SDEI_EXPLICIT_EVENT(5000, SDEI_MAPF_NORMAL), \
+	SDEI_EXPLICIT_EVENT(5001, SDEI_MAPF_NORMAL), \
+	SDEI_EXPLICIT_EVENT(5002, SDEI_MAPF_NORMAL), \
+	SDEI_EXPLICIT_EVENT(5003, SDEI_MAPF_CRITICAL), \
+	SDEI_EXPLICIT_EVENT(5004, SDEI_MAPF_CRITICAL)
+  #else
+  #define PLAT_ARM_PRIVATE_SDEI_EVENTS	ARM_SDEI_PRIVATE_EVENTS
+  #endif
 #define PLAT_ARM_SHARED_SDEI_EVENTS	ARM_SDEI_SHARED_EVENTS
 #endif
 
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
 
-#define PLAT_SP_PRI			PLAT_RAS_PRI
+#define PLAT_SP_PRI			0x20
 
 /*
  * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
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 207e0d7..436cab3 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -24,6 +24,75 @@
 
 FVP_DT_PREFIX		:= fvp-base-gicv3-psci
 
+# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
+# the FVP platform. This option defaults to 256.
+FVP_TRUSTED_SRAM_SIZE	:= 256
+
+# This is a very trickly TEMPORARY fix. Enabling ALL features exceeds BL31's
+# progbits limit. We need a way to build all useful configurations while waiting
+# on the fvp to increase its SRAM size. The problem is twofild:
+#  1. the cleanup that introduced these enables cleaned up tf-a a little too
+#     well and things that previously (incorrectly) were enabled, no longer are.
+#     A bunch of CI configs build subtly incorrectly and this combo makes it
+#     necessary to forcefully and unconditionally enable them here.
+#  2. the progbits limit is exceeded only when the tsp is involved. However,
+#     there are tsp CI configs that run on very high architecture revisions so
+#     disabling everything isn't an option.
+# The fix is to enable everything, as before. When the tsp is included, though,
+# we need to slim the size down. In that case, disable all optional features,
+# that will not be present in CI when the tsp is.
+# Similarly, DRTM support is only tested on v8.0 models. Disable everything just
+# for it.
+# TODO: make all of this unconditional (or only base the condition on
+# ARM_ARCH_* when the makefile supports it).
+ifneq (${DRTM_SUPPORT}, 1)
+ifneq (${SPD}, tspd)
+	ENABLE_FEAT_AMU			:= 2
+	ENABLE_FEAT_AMUv1p1		:= 2
+	ENABLE_FEAT_HCX			:= 2
+	ENABLE_MPAM_FOR_LOWER_ELS	:= 2
+	ENABLE_FEAT_RNG			:= 2
+	ENABLE_FEAT_TWED		:= 2
+	ENABLE_FEAT_GCS			:= 2
+	ENABLE_FEAT_RAS			:= 2
+ifeq (${ARCH}, aarch64)
+ifneq (${SPD}, spmd)
+ifeq (${SPM_MM}, 0)
+ifeq (${ENABLE_RME}, 0)
+ifeq (${CTX_INCLUDE_FPREGS}, 0)
+	ENABLE_SME_FOR_NS		:= 2
+	ENABLE_SME2_FOR_NS		:= 2
+endif
+endif
+endif
+endif
+endif
+endif
+
+# enable unconditionally for all builds
+ifeq (${ARCH}, aarch64)
+ifeq (${ENABLE_RME},0)
+	ENABLE_BRBE_FOR_NS		:= 2
+endif
+endif
+ENABLE_TRBE_FOR_NS		:= 2
+ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
+ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_DIT			:= 2
+ENABLE_FEAT_PAN			:= 2
+ENABLE_FEAT_VHE			:= 2
+CTX_INCLUDE_NEVE_REGS		:= 2
+ENABLE_FEAT_SEL2		:= 2
+ENABLE_TRF_FOR_NS		:= 2
+ENABLE_FEAT_ECV			:= 2
+ENABLE_FEAT_FGT			:= 2
+ENABLE_FEAT_TCR2		:= 2
+ENABLE_FEAT_S2PIE		:= 2
+ENABLE_FEAT_S1PIE		:= 2
+ENABLE_FEAT_S2POE		:= 2
+ENABLE_FEAT_S1POE		:= 2
+endif
+
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
 
@@ -39,6 +108,9 @@
 # Pass FVP_GICR_REGION_PROTECTION to the build system.
 $(eval $(call add_define,FVP_GICR_REGION_PROTECTION))
 
+# Pass FVP_TRUSTED_SRAM_SIZE to the build system.
+$(eval $(call add_define,FVP_TRUSTED_SRAM_SIZE))
+
 # Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2,
 # choose the CCI driver , else the CCN driver
 ifeq ($(FVP_CLUSTER_COUNT), 0)
@@ -102,7 +174,8 @@
 				plat/arm/common/arm_tzc400.c
 
 
-PLAT_INCLUDES		:=	-Iplat/arm/board/fvp/include
+PLAT_INCLUDES		:=	-Iplat/arm/board/fvp/include		\
+				-Iinclude/lib/psa
 
 
 PLAT_BL_COMMON_SOURCES	:=	plat/arm/board/fvp/fvp_common.c
@@ -124,29 +197,22 @@
 # Cores used with DSU only
 	ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0)
 	# AArch64-only cores
-		FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a76.S		\
+	# TODO: add all cores to the appropriate lists
+		FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a65.S		\
+					lib/cpus/aarch64/cortex_a65ae.S		\
+					lib/cpus/aarch64/cortex_a76.S		\
 					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	\
 					lib/cpus/aarch64/neoverse_n1.S		\
 					lib/cpus/aarch64/neoverse_n2.S		\
-					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
-					lib/cpus/aarch64/neoverse_v2.S	\
-					lib/cpus/aarch64/cortex_a78_ae.S	\
-					lib/cpus/aarch64/cortex_a510.S		\
-					lib/cpus/aarch64/cortex_a710.S		\
-					lib/cpus/aarch64/cortex_a715.S		\
-					lib/cpus/aarch64/cortex_x3.S 		\
-					lib/cpus/aarch64/cortex_a65.S		\
-					lib/cpus/aarch64/cortex_a65ae.S		\
-					lib/cpus/aarch64/cortex_a78c.S		\
-					lib/cpus/aarch64/cortex_hayes.S		\
-					lib/cpus/aarch64/cortex_hunter.S	\
-					lib/cpus/aarch64/cortex_hunter_elp_arm.S \
-					lib/cpus/aarch64/cortex_x2.S		\
-					lib/cpus/aarch64/neoverse_poseidon.S
+					lib/cpus/aarch64/neoverse_e1.S		\
+					lib/cpus/aarch64/cortex_x2.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
@@ -154,7 +220,8 @@
 endif
 
 else
-FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S
+FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S			\
+				lib/cpus/aarch32/cortex_a57.S
 endif
 
 BL1_SOURCES		+=	drivers/arm/smmu/smmu_v3.c			\
@@ -195,8 +262,14 @@
 
 ifeq (${ENABLE_RME},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S
+
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
 				plat/arm/board/fvp/fvp_realm_attest_key.c
+
+# FVP platform does not support RSS, but it can leverage RSS APIs to
+# provide hardcoded token/key on request.
+BL31_SOURCES		+=	lib/psa/delegated_attestation.c
+
 endif
 
 ifeq (${ENABLE_FEAT_RNG_TRAP},1)
@@ -310,13 +383,10 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 endif
 
-# Enable Activity Monitor Unit extensions by default
-ENABLE_AMU			:=	1
-
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
-ifeq (${ENABLE_AMU},1)
+ifneq (${ENABLE_FEAT_AMU},0)
 BL31_SOURCES		+=	lib/cpus/aarch64/cpuamu.c		\
 				lib/cpus/aarch64/cpuamu_helpers.S
 
@@ -326,7 +396,7 @@
 endif
 endif
 
-ifeq (${RAS_EXTENSION},1)
+ifeq (${RAS_FFH_SUPPORT},1)
 BL31_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_ras.c
 endif
 
@@ -369,6 +439,10 @@
     override BL1_SOURCES =
 endif
 
+# RSS is not supported on FVP right now. Thus, we use the mocked version
+# of the provided PSA APIs. They return with success and hard-coded token/key.
+PLAT_RSS_NOT_SUPPORTED	:= 1
+
 # Include Measured Boot makefile before any Crypto library makefile.
 # Crypto library makefile may need default definitions of Measured Boot build
 # flags present in Measured Boot makefile.
@@ -397,17 +471,6 @@
 				plat/arm/board/fvp/fvp_bl2_measured_boot.c	\
 				lib/psa/measured_boot.c
 
-# Note that attestation code does not depend on measured boot interfaces per se,
-# but the two features go together - attestation without boot measurements is
-# pretty much pointless...
-BL31_SOURCES		+=	lib/psa/delegated_attestation.c
-
-PLAT_INCLUDES		+=	-Iinclude/lib/psa
-
-# RSS is not supported on FVP right now. Thus, we use the mocked version
-# of the provided PSA APIs. They return with success and hard-coded data.
-PLAT_RSS_NOT_SUPPORTED	:= 1
-
 # Even though RSS is not supported on FVP (see above), we support overriding
 # PLAT_RSS_NOT_SUPPORTED from the command line, just for the purpose of building
 # the code to detect any build regressions. The resulting firmware will not be
@@ -417,8 +480,7 @@
     include drivers/arm/rss/rss_comms.mk
     BL1_SOURCES		+=	${RSS_COMMS_SOURCES}
     BL2_SOURCES		+=	${RSS_COMMS_SOURCES}
-    BL31_SOURCES	+=	${RSS_COMMS_SOURCES}		\
-				lib/psa/delegated_attestation.c
+    BL31_SOURCES	+=	${RSS_COMMS_SOURCES}
 
     BL1_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
     BL2_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
@@ -446,29 +508,32 @@
 DYN_DISABLE_AUTH	:=	1
 endif
 
-# enable trace buffer control registers access to NS by default
-ENABLE_TRBE_FOR_NS		:= 2
-
-# enable branch record buffer control registers access in NS by default
-# only enable for aarch64
-# do not enable when ENABLE_RME=1
-ifeq (${ARCH}, aarch64)
-ifeq (${ENABLE_RME},0)
-	ENABLE_BRBE_FOR_NS		:= 2
-endif
+ifeq (${SPMC_AT_EL3}, 1)
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_el3_spmc.c
 endif
 
-# enable trace system registers access to NS by default
-ENABLE_SYS_REG_TRACE_FOR_NS	:= 1
+PSCI_OS_INIT_MODE	:=	1
 
-# enable trace filter control registers access to NS by default
-ENABLE_TRF_FOR_NS		:= 2
+ifeq (${SPD},spmd)
+BL31_SOURCES	+=	plat/arm/board/fvp/fvp_spmd.c
+endif
 
-# Linux relies on EL3 enablement if those features are present
-ENABLE_FEAT_FGT			:= 2
-ENABLE_FEAT_HCX			:= 2
-ENABLE_FEAT_TCR2		:= 2
+# Test specific macros, keep them at bottom of this file
+$(eval $(call add_define,PLATFORM_TEST_EA_FFH))
+ifeq (${PLATFORM_TEST_EA_FFH}, 1)
+    ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
+         $(error "PLATFORM_TEST_EA_FFH expects HANDLE_EA_EL3_FIRST_NS to be 1")
+    endif
+BL31_SOURCES	+= plat/arm/board/fvp/aarch64/fvp_ea.c
+endif
 
-ifeq (${SPMC_AT_EL3}, 1)
-PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_el3_spmc.c
+$(eval $(call add_define,PLATFORM_TEST_RAS_FFH))
+ifeq (${PLATFORM_TEST_RAS_FFH}, 1)
+    ifeq (${RAS_EXTENSION}, 0)
+         $(error "PLATFORM_TEST_RAS_FFH expects RAS_EXTENSION to be 1")
+    endif
+endif
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+include plat/arm/board/fvp/fvp_cpu_errata.mk
 endif
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index b961da9..705ec38 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -84,7 +84,7 @@
 	     (void *)hw_config_info->config_addr);
 
 	/*
-	 * Preferrably we expect this address and size are page aligned,
+	 * Preferably we expect this address and size are page aligned,
 	 * but if they are not then align it.
 	 */
 	hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
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/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
index 841a176..252fc31 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_main.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
@@ -15,7 +15,7 @@
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/console.h>
-#include <lib/cpus/errata_report.h>
+#include <lib/cpus/errata.h>
 #include <lib/utils.h>
 #include <smccc_helpers.h>
 #include <tools_share/uuid.h>
diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk
index 93b5cf2..f14ea54 100644
--- a/plat/arm/board/fvp_r/platform.mk
+++ b/plat/arm/board/fvp_r/platform.mk
@@ -69,7 +69,7 @@
 endif
 
 # Enable Activity Monitor Unit extensions by default
-ENABLE_AMU			:=	1
+ENABLE_FEAT_AMU			:=	2
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)
 FVP_R_BL_COMMON_SOURCES	+=	plat/arm/board/fvp_r/fvp_r_stack_protector.c
@@ -83,6 +83,7 @@
 				drivers/io/io_storage.c				\
 				drivers/io/io_semihosting.c			\
 				lib/cpus/aarch64/cpu_helpers.S			\
+				lib/cpus/errata_report.c			\
 				lib/fconf/fconf_dyn_cfg_getter.c		\
 				lib/semihosting/semihosting.c			\
 				lib/semihosting/${ARCH}/semihosting_call.S	\
diff --git a/plat/arm/board/juno/cert_create_tbbr.mk b/plat/arm/board/juno/cert_create_tbbr.mk
new file mode 100644
index 0000000..c092fe0
--- /dev/null
+++ b/plat/arm/board/juno/cert_create_tbbr.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_DEF_OID := 1
+
+ifeq (${PLAT_DEF_OID},1)
+  ifeq (${ARM_ETHOSN_NPU_DRIVER},1)
+    $(eval $(call add_define, PLAT_DEF_OID))
+    $(eval $(call add_define, PDEF_CERTS))
+    $(eval $(call add_define, PDEF_EXTS))
+    $(eval $(call add_define, PDEF_KEYS))
+
+    PLAT_INCLUDE			+=	-I ${PLAT_DIR}/certificate/include \
+						-I ../../include/drivers/arm
+
+    PLAT_OBJECTS			+=	${PLAT_DIR}certificate/src/juno_tbb_cert.o \
+						${PLAT_DIR}certificate/src/juno_tbb_ext.o \
+						${PLAT_DIR}certificate/src/juno_tbb_key.o
+
+    OBJECTS				+=	${PLAT_OBJECTS}
+  endif
+endif
diff --git a/plat/arm/board/juno/certificate/include/juno_tbb_cert.h b/plat/arm/board/juno/certificate/include/juno_tbb_cert.h
new file mode 100644
index 0000000..9799405
--- /dev/null
+++ b/plat/arm/board/juno/certificate/include/juno_tbb_cert.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_TBB_CERT_H
+#define JUNO_TBB_CERT_H
+
+#include <tbbr/tbb_cert.h>
+
+/*
+ * Juno platform certificates that are used to establish the COT
+ */
+enum {
+	ETHOSN_NPU_FW_KEY_CERT = FWU_CERT + 1,
+	ETHOSN_NPU_FW_CONTENT_CERT,
+};
+
+#endif /* JUNO_TBB_CERT_H */
diff --git a/plat/arm/board/juno/certificate/include/juno_tbb_ext.h b/plat/arm/board/juno/certificate/include/juno_tbb_ext.h
new file mode 100644
index 0000000..ec38227
--- /dev/null
+++ b/plat/arm/board/juno/certificate/include/juno_tbb_ext.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_TBB_EXT_H
+#define JUNO_TBB_EXT_H
+
+#include <tbbr/tbb_ext.h>
+
+/* Juno platform defined TBBR extensions */
+enum {
+	ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT = FWU_HASH_EXT + 1,
+	ETHOSN_NPU_FW_HASH_EXT,
+};
+
+#endif /* JUNO_TBB_EXT_H */
diff --git a/plat/arm/board/juno/certificate/include/juno_tbb_key.h b/plat/arm/board/juno/certificate/include/juno_tbb_key.h
new file mode 100644
index 0000000..9576b9d
--- /dev/null
+++ b/plat/arm/board/juno/certificate/include/juno_tbb_key.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_TBB_KEY_H
+#define JUNO_TBB_KEY_H
+
+#include <tbbr/tbb_key.h>
+
+/*
+ * Juno platform keys that are used to establish the COT
+ */
+enum {
+	ETHOSN_NPU_FW_CONTENT_CERT_KEY =
+		NON_TRUSTED_FW_CONTENT_CERT_KEY + 1,
+};
+#endif /* JUNO_TBB_KEY_H */
diff --git a/plat/arm/board/juno/certificate/include/platform_oid.h b/plat/arm/board/juno/certificate/include/platform_oid.h
new file mode 100644
index 0000000..22173c1
--- /dev/null
+++ b/plat/arm/board/juno/certificate/include/platform_oid.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_PLATFORM_OID_H
+#define JUNO_PLATFORM_OID_H
+
+#include <ethosn_oid.h>
+
+#endif /* JUNO_PLATFORM_OID_H */
diff --git a/plat/arm/board/juno/certificate/src/juno_tbb_cert.c b/plat/arm/board/juno/certificate/src/juno_tbb_cert.c
new file mode 100644
index 0000000..3cb8304
--- /dev/null
+++ b/plat/arm/board/juno/certificate/src/juno_tbb_cert.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ethosn_cert.h>
+
+#include <juno_tbb_cert.h>
+#include <juno_tbb_ext.h>
+#include <juno_tbb_key.h>
+
+static cert_t juno_plat_tbb_certificates[] = {
+	ETHOSN_NPU_FW_KEY_CERT_DEF,
+	ETHOSN_NPU_FW_CONTENT_CERT_DEF,
+};
+
+PLAT_REGISTER_COT(juno_plat_tbb_certificates);
diff --git a/plat/arm/board/juno/certificate/src/juno_tbb_ext.c b/plat/arm/board/juno/certificate/src/juno_tbb_ext.c
new file mode 100644
index 0000000..d8fe9e9
--- /dev/null
+++ b/plat/arm/board/juno/certificate/src/juno_tbb_ext.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ethosn_cert.h>
+
+#include <juno_tbb_ext.h>
+#include <juno_tbb_key.h>
+
+static ext_t juno_plat_tbb_extensions[] = {
+	ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT_DEF,
+	ETHOSN_NPU_FW_HASH_EXT_DEF,
+};
+
+PLAT_REGISTER_EXTENSIONS(juno_plat_tbb_extensions);
diff --git a/plat/arm/board/juno/certificate/src/juno_tbb_key.c b/plat/arm/board/juno/certificate/src/juno_tbb_key.c
new file mode 100644
index 0000000..470755f
--- /dev/null
+++ b/plat/arm/board/juno/certificate/src/juno_tbb_key.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ethosn_cert.h>
+
+#include <juno_tbb_key.h>
+
+static key_t juno_plat_tbb_keys[] = {
+	ETHOSN_NPU_FW_CONTENT_CERT_KEY_DEF
+};
+
+PLAT_REGISTER_KEYS(juno_plat_tbb_keys);
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
index 4b88efe..2d79ac7 100644
--- a/plat/arm/board/juno/fdts/juno_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 
 		tb_fw-config {
 			load-address = <0x0 0x4001300>;
-			max-size = <0x200>;
+			max-size = <0xA00>;
 			id = <TB_FW_CONFIG_ID>;
 		};
 
diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
index 80cfa3e..986299e 100644
--- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,4 +23,41 @@
 		mbedtls_heap_addr = <0x0 0x0>;
 		mbedtls_heap_size = <0x0>;
 	};
+
+#if ARM_IO_IN_DTB
+	arm-io_policies {
+		fip-handles {
+			compatible = "arm,io-fip-handle";
+			scp_bl2_uuid = "9766fd3d-89be-e849-ae5d-78a140608213";
+			bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
+			bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
+			bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
+			bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
+			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
+			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+			soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
+			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
+			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+			cca_cert_uuid = "36d83d85-761d-4daf-96f1-cd99d6569b00";
+			core_swd_cert_uuid = "52222d31-820f-494d-8bbc-ea6825d3c35a";
+			plat_cert_uuid = "d43cd902-5b9f-412e-8ac6-92b6d18be60d";
+			t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
+			scp_fw_key_uuid = "024221a1-f860-e411-8d9b-f33c0e15a014";
+			soc_fw_key_uuid = "8ab8becc-f960-e411-9ad0-eb4822d8dcf8";
+			tos_fw_key_cert_uuid = "9477d603-fb60-e411-85dd-b7105b8cee04";
+			nt_fw_key_cert_uuid = "8ad5832a-fb60-e411-8aaf-df30bbc49859";
+			scp_fw_content_cert_uuid = "44be6f04-5e63-e411-b28b-73d8eaae9656";
+			soc_fw_content_cert_uuid = "e2b20c20-5e63-e411-9ce8-abccf92bb666";
+			tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d";
+			nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7";
+			plat_sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f";
+#if ARM_ETHOSN_NPU_TZMP1
+			arm_ethosn_npu_fw_uuid = "cfd499b5-a3bc-4a7e-98cb-48a41cb8dae1";
+			arm_ethosn_npu_fw_key_cert_uuid = "5666d004-ab98-40aa-8988-b72a03a256e2";
+			arm_ethosn_npu_fw_content_cert_uuid = "a5c418da-430f-48b1-88cd-93f67889d9ed";
+#endif
+		};
+	};
+#endif /* ARM_IO_IN_DTB */
+
 };
diff --git a/plat/arm/board/juno/fip/plat_def_fip_uuid.h b/plat/arm/board/juno/fip/plat_def_fip_uuid.h
new file mode 100644
index 0000000..0f0d11d
--- /dev/null
+++ b/plat/arm/board/juno/fip/plat_def_fip_uuid.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_FIP_UUID_H
+#define PLAT_DEF_FIP_UUID_H
+
+#ifdef ARM_ETHOSN_NPU_TZMP1
+#include <drivers/arm/ethosn_fip.h>
+#endif
+
+#endif /* PLAT_DEF_FIP_UUID_H */
diff --git a/plat/arm/board/juno/fip/plat_def_uuid_config.c b/plat/arm/board/juno/fip/plat_def_uuid_config.c
new file mode 100644
index 0000000..8133927
--- /dev/null
+++ b/plat/arm/board/juno/fip/plat_def_uuid_config.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <firmware_image_package.h>
+#include <tbbr_config.h>
+
+#include "plat_def_fip_uuid.h"
+
+toc_entry_t plat_def_toc_entries[] = {
+#ifdef ARM_ETHOSN_NPU_TZMP1
+	ETHOSN_FW_KEY_CERTIFICATE_DEF,
+	ETHOSN_FW_CONTENT_CERTIFICATE_DEF,
+	ETHOSN_FW_DEF,
+#endif
+	{
+		.name = NULL,
+		.uuid = { { 0 } },
+		.cmdline_name = NULL,
+	}
+};
diff --git a/plat/arm/board/juno/include/plat_tbbr_img_def.h b/plat/arm/board/juno/include/plat_tbbr_img_def.h
new file mode 100644
index 0000000..3e17ed3
--- /dev/null
+++ b/plat/arm/board/juno/include/plat_tbbr_img_def.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_IMG_DEF_H
+#define JUNO_IMG_DEF_H
+
+#if ARM_ETHOSN_NPU_TZMP1
+/* Arm(R) Ethos(TM)-N NPU images */
+#define ARM_ETHOSN_NPU_FW_KEY_CERT_ID		U(MAX_IMG_IDS_WITH_SPMDS + 1)
+#define ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID	U(MAX_IMG_IDS_WITH_SPMDS + 2)
+#define ARM_ETHOSN_NPU_FW_IMAGE_ID		U(MAX_IMG_IDS_WITH_SPMDS + 3)
+#define MAX_NUMBER_IDS				U(MAX_IMG_IDS_WITH_SPMDS + 4)
+#endif
+
+#endif	/* JUNO_IMG_DEF_H */
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 409d7a6..47258cb 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +19,9 @@
 #include <plat/common/common_def.h>
 
 #include "../juno_def.h"
+#ifdef JUNO_ETHOSN_TZMP1
+#include "../juno_ethosn_tzmp1_def.h"
+#endif
 
 /* Required platform porting definitions */
 /* Juno supports system power domain */
@@ -62,6 +65,18 @@
 					JUNO_DTB_DRAM_MAP_SIZE,		\
 					MT_MEMORY | MT_RO | MT_NS)
 
+#ifdef JUNO_ETHOSN_TZMP1
+#define JUNO_ETHOSN_PROT_FW_RO MAP_REGION_FLAT(     \
+		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \
+		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE, \
+		MT_RO_DATA | MT_SECURE)
+
+#define JUNO_ETHOSN_PROT_FW_RW MAP_REGION_FLAT(     \
+		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \
+		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE, \
+		MT_MEMORY | MT_RW | MT_SECURE)
+#endif
+
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
 
@@ -102,11 +117,11 @@
 
 #ifdef IMAGE_BL2
 #ifdef SPD_opteed
-# define PLAT_ARM_MMAP_ENTRIES		11
+# define PLAT_ARM_MMAP_ENTRIES		13
 # define MAX_XLAT_TABLES		5
 #else
-# define PLAT_ARM_MMAP_ENTRIES		10
-# define MAX_XLAT_TABLES		4
+# define PLAT_ARM_MMAP_ENTRIES		11
+# define MAX_XLAT_TABLES		5
 #endif
 #endif
 
@@ -116,8 +131,8 @@
 #endif
 
 #ifdef IMAGE_BL31
-#  define PLAT_ARM_MMAP_ENTRIES		7
-#  define MAX_XLAT_TABLES		5
+# define PLAT_ARM_MMAP_ENTRIES		8
+# define MAX_XLAT_TABLES		6
 #endif
 
 #ifdef IMAGE_BL32
@@ -310,4 +325,18 @@
 /* Number of SCMI channels on the platform */
 #define PLAT_ARM_SCMI_CHANNEL_COUNT	U(1)
 
+/* Protected NSAIDs and memory regions for the Arm(R) Ethos(TM)-N NPU driver */
+#ifdef JUNO_ETHOSN_TZMP1
+#define ARM_ETHOSN_NPU_PROT_FW_NSAID		JUNO_ETHOSN_TZC400_NSAID_FW_PROT
+#define ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID	JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT
+#define ARM_ETHOSN_NPU_PROT_RO_DATA_NSAID	JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT
+
+#define ARM_ETHOSN_NPU_NS_RW_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RW_NS
+#define ARM_ETHOSN_NPU_NS_RO_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS
+
+#define ARM_ETHOSN_NPU_FW_IMAGE_BASE		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE
+#define ARM_ETHOSN_NPU_FW_IMAGE_LIMIT \
+	(JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE)
+#endif
+
 #endif /* PLATFORM_DEF_H */
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/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 451c7df..02614da 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -53,6 +53,9 @@
 #if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
+#ifdef JUNO_ETHOSN_TZMP1
+	JUNO_ETHOSN_PROT_FW_RW,
+#endif
 	{0}
 };
 #endif
@@ -76,6 +79,9 @@
 #endif
 	SOC_CSS_MAP_DEVICE,
 	ARM_DTB_DRAM_NS,
+#ifdef JUNO_ETHOSN_TZMP1
+	JUNO_ETHOSN_PROT_FW_RO,
+#endif
 	{0}
 };
 #endif
diff --git a/plat/arm/board/juno/juno_ethosn_tzmp1_def.h b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h
new file mode 100644
index 0000000..c3e816a
--- /dev/null
+++ b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_ETHOSN_TZMP1_DEF_H
+#define JUNO_ETHOSN_TZMP1_DEF_H
+
+#define JUNO_ETHOSN_TZC400_NSAID_FW_PROT	7
+#define JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT	8
+#define JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT	13
+
+/* 0 is the default NSAID and is included in PLAT_ARM_TZC_NS_DEV_ACCESS */
+#define JUNO_ETHOSN_TZC400_NSAID_DATA_RW_NS	0
+#define JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS	14
+
+#define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE      UL(0x000400000) /* 4 MB */
+#define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE      (ARM_DRAM2_BASE)
+#define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END       (ARM_DRAM2_BASE +		    \
+						 JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE \
+						 - 1U)
+
+#define JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_SIZE    UL(0x004000000) /* 64 MB */
+#define JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE    ( \
+		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END + 1)
+#define JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END     (      \
+		JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE + \
+		JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_SIZE - 1U)
+
+#define JUNO_ETHOSN_NS_DRAM2_BASE       (JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END + \
+					 1)
+#define JUNO_ETHOSN_NS_DRAM2_END        (ARM_DRAM2_END)
+#define JUNO_ETHOSN_NS_DRAM2_SIZE       (ARM_DRAM2_SIZE - \
+					 JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END)
+
+#define JUNO_FW_TZC_PROT_ACCESS	\
+	(TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_FW_PROT))
+#define JUNO_DATA_TZC_PROT_ACCESS \
+	(TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT) | \
+	 TZC_REGION_ACCESS_RD(JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT))
+#define JUNO_DATA_TZC_NS_ACCESS \
+	(PLAT_ARM_TZC_NS_DEV_ACCESS | \
+	 TZC_REGION_ACCESS_RD(JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS))
+
+#define JUNO_ETHOSN_TZMP_REGIONS_DEF					  \
+	{ ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE, \
+	  TZC_REGION_S_RDWR, 0 },					  \
+	{ ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END,				  \
+	  ARM_TZC_NS_DRAM_S_ACCESS, JUNO_DATA_TZC_NS_ACCESS},		  \
+	{ JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE,				  \
+	  JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END,				  \
+	  TZC_REGION_S_RDWR, JUNO_FW_TZC_PROT_ACCESS },			  \
+	{ JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE,				  \
+	  JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END,				  \
+	  TZC_REGION_S_NONE, JUNO_DATA_TZC_PROT_ACCESS },		  \
+	{ JUNO_ETHOSN_NS_DRAM2_BASE, JUNO_ETHOSN_NS_DRAM2_END,		  \
+	  ARM_TZC_NS_DRAM_S_ACCESS, JUNO_DATA_TZC_NS_ACCESS}
+
+#endif /* JUNO_ETHOSN_TZMP1_DEF_H */
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index 654a7f1..72e7e78 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <plat/arm/soc/common/soc_css.h>
 #include <plat/common/platform.h>
 
+#include "juno_ethosn_tzmp1_def.h"
 #include "juno_tzmp1_def.h"
 
 #ifdef JUNO_TZMP1
@@ -78,6 +79,15 @@
 
 #endif /* JUNO_TZMP1 */
 
+#ifdef JUNO_ETHOSN_TZMP1
+
+static const arm_tzc_regions_info_t juno_ethosn_tzmp1_tzc_regions[] = {
+	JUNO_ETHOSN_TZMP_REGIONS_DEF,
+	{},
+};
+
+#endif /* JUNO_ETHOSN_TZMP1 */
+
 /*******************************************************************************
  * Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs
  * assigned to Non-Secure except some for the DMA-330. Assign those back to the
@@ -140,6 +150,17 @@
 	     (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE);
 	INFO("TZC protected shared memory end address for TZMP usecase: %p\n",
 	     (void *)JUNO_AP_TZC_SHARE_DRAM1_END);
+#elif defined(JUNO_ETHOSN_TZMP1)
+	arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_ethosn_tzmp1_tzc_regions);
+	INFO("TZC protected shared memory range for NPU TZMP usecase: %p - %p\n",
+	     (void *)JUNO_ETHOSN_NS_DRAM2_BASE,
+	     (void *)JUNO_ETHOSN_NS_DRAM2_END);
+	INFO("TZC protected Data memory range for NPU TZMP usecase: %p - %p\n",
+	     (void *)JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE,
+	     (void *)JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END);
+	INFO("TZC protected FW memory range for NPU TZMP usecase: %p - %p\n",
+	     (void *)JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE,
+	     (void *)JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END);
 #else
 	arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
 #endif
diff --git a/plat/arm/board/juno/juno_tbbr_cot_bl2.c b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
new file mode 100644
index 0000000..d48d2e6
--- /dev/null
+++ b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
@@ -0,0 +1,789 @@
+/*
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <mbedtls/version.h>
+
+#include <drivers/auth/auth_mod.h>
+#include <drivers/auth/tbbr_cot_common.h>
+
+#if USE_TBBR_DEFS
+#include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
+#include <platform_def.h>
+
+static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
+static unsigned char trusted_world_pk_buf[PK_DER_LEN];
+static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
+static unsigned char content_pk_buf[PK_DER_LEN];
+static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#if defined(SPD_spmd)
+static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
+#endif /* SPD_spmd */
+#if ARM_ETHOSN_NPU_TZMP1
+static unsigned char npu_fw_image_hash_buf[HASH_DER_LEN];
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
+
+
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
+static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
+static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_FW_HASH_OID);
+static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
+static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
+static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID);
+static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID);
+static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
+static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+#if defined(SPD_spmd)
+static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
+static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
+static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
+static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
+static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
+static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
+static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
+static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
+#endif /* SPD_spmd */
+#if ARM_ETHOSN_NPU_TZMP1
+static auth_param_type_desc_t npu_fw_cert_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, ETHOSN_NPU_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t npu_fw_image_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, ETHOSN_NPU_FW_BINARY_OID);
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
+
+/*
+ * Trusted key certificate
+ */
+static const auth_img_desc_t trusted_key_cert = {
+	.img_id = TRUSTED_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &trusted_world_pk,
+			.data = {
+				.ptr = (void *)trusted_world_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &non_trusted_world_pk,
+			.data = {
+				.ptr = (void *)non_trusted_world_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+/*
+ * SCP Firmware
+ */
+static const auth_img_desc_t scp_fw_key_cert = {
+	.img_id = SCP_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t scp_fw_content_cert = {
+	.img_id = SCP_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &scp_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &scp_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_fw_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t scp_bl2_image = {
+	.img_id = SCP_BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &scp_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_fw_hash
+			}
+		}
+	}
+};
+/*
+ * SoC Firmware
+ */
+static const auth_img_desc_t soc_fw_key_cert = {
+	.img_id = SOC_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &soc_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t soc_fw_content_cert = {
+	.img_id = SOC_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &soc_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &soc_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &soc_fw_hash,
+			.data = {
+				.ptr = (void *)soc_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &soc_fw_config_hash,
+			.data = {
+				.ptr = (void *)soc_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl31_image = {
+	.img_id = BL31_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &soc_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_hash
+			}
+		}
+	}
+};
+/* SOC FW Config */
+static const auth_img_desc_t soc_fw_config = {
+	.img_id = SOC_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &soc_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_config_hash
+			}
+		}
+	}
+};
+/*
+ * Trusted OS Firmware
+ */
+static const auth_img_desc_t trusted_os_fw_key_cert = {
+	.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t trusted_os_fw_content_cert = {
+	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_os_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &tos_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_hash,
+			.data = {
+				.ptr = (void *)tos_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tos_fw_extra1_hash,
+			.data = {
+				.ptr = (void *)tos_fw_extra1_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &tos_fw_extra2_hash,
+			.data = {
+				.ptr = (void *)tos_fw_extra2_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &tos_fw_config_hash,
+			.data = {
+				.ptr = (void *)tos_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl32_image = {
+	.img_id = BL32_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_hash
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl32_extra1_image = {
+	.img_id = BL32_EXTRA1_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_extra1_hash
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl32_extra2_image = {
+	.img_id = BL32_EXTRA2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_extra2_hash
+			}
+		}
+	}
+};
+/* TOS FW Config */
+static const auth_img_desc_t tos_fw_config = {
+	.img_id = TOS_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_config_hash
+			}
+		}
+	}
+};
+/*
+ * Non-Trusted Firmware
+ */
+static const auth_img_desc_t non_trusted_fw_key_cert = {
+	.img_id = NON_TRUSTED_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &non_trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &non_trusted_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &nt_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_world_bl_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &nt_fw_config_hash,
+			.data = {
+				.ptr = (void *)nt_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl33_image = {
+	.img_id = BL33_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_world_bl_hash
+			}
+		}
+	}
+};
+/* NT FW Config */
+static const auth_img_desc_t nt_fw_config = {
+	.img_id = NT_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_fw_config_hash
+			}
+		}
+	}
+};
+/* Secure Partitions */
+#if defined(SPD_spmd)
+static const auth_img_desc_t sip_sp_content_cert = {
+	.img_id = SIP_SP_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &sp_pkg1_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[0],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &sp_pkg2_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[1],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &sp_pkg3_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[2],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &sp_pkg4_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[3],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[4] = {
+			.type_desc = &sp_pkg5_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[4],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[5] = {
+			.type_desc = &sp_pkg6_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[5],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[6] = {
+			.type_desc = &sp_pkg7_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[6],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[7] = {
+			.type_desc = &sp_pkg8_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[7],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+DEFINE_SIP_SP_PKG(1);
+DEFINE_SIP_SP_PKG(2);
+DEFINE_SIP_SP_PKG(3);
+DEFINE_SIP_SP_PKG(4);
+DEFINE_SIP_SP_PKG(5);
+DEFINE_SIP_SP_PKG(6);
+DEFINE_SIP_SP_PKG(7);
+DEFINE_SIP_SP_PKG(8);
+#endif /* SPD_spmd */
+
+#if ARM_ETHOSN_NPU_TZMP1
+static const auth_img_desc_t npu_fw_key_cert = {
+	.img_id = ARM_ETHOSN_NPU_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &non_trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &npu_fw_cert_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t npu_fw_content_cert = {
+	.img_id = ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &npu_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &npu_fw_cert_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &npu_fw_image_hash,
+			.data = {
+				.ptr = (void *)npu_fw_image_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+	}
+};
+
+static const auth_img_desc_t npu_fw_image = {
+	.img_id = ARM_ETHOSN_NPU_FW_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &npu_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &npu_fw_image_hash
+			}
+		}
+	}
+};
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
+
+
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[TRUSTED_KEY_CERT_ID]			=	&trusted_key_cert,
+	[SCP_FW_KEY_CERT_ID]			=	&scp_fw_key_cert,
+	[SCP_FW_CONTENT_CERT_ID]		=	&scp_fw_content_cert,
+	[SCP_BL2_IMAGE_ID]			=	&scp_bl2_image,
+	[SOC_FW_KEY_CERT_ID]			=	&soc_fw_key_cert,
+	[SOC_FW_CONTENT_CERT_ID]		=	&soc_fw_content_cert,
+	[BL31_IMAGE_ID]				=	&bl31_image,
+	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
+	[TRUSTED_OS_FW_KEY_CERT_ID]		=	&trusted_os_fw_key_cert,
+	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
+	[BL32_IMAGE_ID]				=	&bl32_image,
+	[BL32_EXTRA1_IMAGE_ID]			=	&bl32_extra1_image,
+	[BL32_EXTRA2_IMAGE_ID]			=	&bl32_extra2_image,
+	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
+	[NON_TRUSTED_FW_KEY_CERT_ID]		=	&non_trusted_fw_key_cert,
+	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
+	[BL33_IMAGE_ID]				=	&bl33_image,
+	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
+#if defined(SPD_spmd)
+	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
+	[SP_PKG1_ID]				=	&sp_pkg1,
+	[SP_PKG2_ID]				=	&sp_pkg2,
+	[SP_PKG3_ID]				=	&sp_pkg3,
+	[SP_PKG4_ID]				=	&sp_pkg4,
+	[SP_PKG5_ID]				=	&sp_pkg5,
+	[SP_PKG6_ID]				=	&sp_pkg6,
+	[SP_PKG7_ID]				=	&sp_pkg7,
+	[SP_PKG8_ID]				=       &sp_pkg8,
+#endif
+#if ARM_ETHOSN_NPU_TZMP1
+	[ARM_ETHOSN_NPU_FW_KEY_CERT_ID]		=	&npu_fw_key_cert,
+	[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID]	=	&npu_fw_content_cert,
+	[ARM_ETHOSN_NPU_FW_IMAGE_ID]		=	&npu_fw_image,
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
+};
+
+/* Register the CoT in the authentication module */
+REGISTER_COT(cot_desc);
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 2c84eb3..a4e6407 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -43,7 +43,11 @@
 JUNO_TZMP1		:=	0
 $(eval $(call assert_boolean,JUNO_TZMP1))
 ifeq (${JUNO_TZMP1}, 1)
-$(eval $(call add_define,JUNO_TZMP1))
+  ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
+    $(error JUNO_TZMP1 cannot be used together with ARM_ETHOSN_NPU_TZMP1)
+  else
+    $(eval $(call add_define,JUNO_TZMP1))
+  endif
 endif
 
 TRNG_SUPPORT		:=	1
@@ -102,8 +106,16 @@
 endif
 
 ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES		+=	plat/arm/board/juno/juno_trusted_boot.c
-BL2_SOURCES		+=	plat/arm/board/juno/juno_trusted_boot.c
+   # Enable Juno specific TBBR images
+   $(eval $(call add_define,PLAT_TBBR_IMG_DEF))
+   DTC_CPPFLAGS += ${PLAT_INCLUDES}
+
+   BL1_SOURCES		+=	plat/arm/board/juno/juno_trusted_boot.c
+   BL2_SOURCES		+=	plat/arm/board/juno/juno_trusted_boot.c
+
+   ifeq (${COT_DESC_IN_DTB},0)
+      BL2_SOURCES	+=	plat/arm/board/juno/juno_tbbr_cot_bl2.c
+   endif
 endif
 
 endif
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
index 76e63aa..993aa46 100644
--- a/plat/arm/board/morello/include/platform_def.h
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -163,7 +163,59 @@
 #define PLAT_MHUV2_BASE				PLAT_CSS_MHU_BASE
 #define PLAT_MAX_PWR_LVL			U(2)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
+/* Interrupt handling constants */
+#define MORELLO_IRQ_SEC_UART			U(87)
+#define MORELLO_IRQ_DISPLAY_TCU_EVENT_Q		U(107)
+#define MORELLO_IRQ_DISPLAY_TCU_CMD_SYNC	U(111)
+#define MORELLO_IRQ_DISPLAY_TCU_GLOBAL		U(113)
+#define MORELLO_IRQ_MMU_TCU1_EVENT_Q		U(257)
+#define MORELLO_IRQ_MMU_TCU1_CMD_SYNC		U(258)
+#define MORELLO_IRQ_MMU_TCU1_GLOBAL		U(259)
+#define MORELLO_IRQ_MMU_TCU2_EVENT_Q		U(264)
+#define MORELLO_IRQ_MMU_TCU2_CMD_SYNC		U(265)
+#define MORELLO_IRQ_MMU_TCU2_GLOBAL		U(266)
+#define MORELLO_IRQ_CLUSTER0_MHU		U(349)
+#define MORELLO_IRQ_CLUSTER1_MHU		U(351)
+#define MORELLO_IRQ_P0_REFCLK			U(412)
+#define MORELLO_IRQ_P1_REFCLK			U(413)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+	ARM_G1S_IRQ_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_SEC_UART, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_DISPLAY_TCU_EVENT_Q, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_DISPLAY_TCU_CMD_SYNC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_DISPLAY_TCU_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU1_EVENT_Q, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU1_CMD_SYNC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU1_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU2_EVENT_Q, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU2_CMD_SYNC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU2_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_CLUSTER0_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_CLUSTER1_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_P0_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_P1_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL)
+
 #define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
 
 #define MORELLO_DEVICE_BASE			ULL(0x08000000)
diff --git a/plat/arm/board/morello/morello_bl2_setup.c b/plat/arm/board/morello/morello_bl2_setup.c
index ec87a8e..39020e2 100644
--- a/plat/arm/board/morello/morello_bl2_setup.c
+++ b/plat/arm/board/morello/morello_bl2_setup.c
@@ -13,42 +13,6 @@
 #include "morello_def.h"
 #include <platform_def.h>
 
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size
- *	- Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- *	- Remote DDR size in bytes, DDR memory in remote board
- *	- remote_chip_count
- *	- multichip mode
- *	- scc configuration
- *	- silicon revision
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-	uint64_t remote_ddr_size;
-	uint8_t remote_chip_count;
-	bool multichip_mode;
-	uint32_t scc_config;
-	uint32_t silicon_revision;
-} __packed;
-#endif
-
-/* Compile time assertion to ensure the size of structure is 18 bytes */
-CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
-		assert_invalid_plat_info_size);
-
 #ifdef TARGET_PLATFORM_SOC
 /*
  * Morello platform supports RDIMMs with ECC capability. To use the ECC
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index 8f01592..8469cd1 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -12,46 +12,13 @@
 #include <services/arm_arch_svc.h>
 
 #include "morello_def.h"
+#include "morello_private.h"
 #include <platform_def.h>
 
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size
- *	- Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- *	- Remote DDR size in bytes, DDR memory in remote board
- *	- remote_chip_count
- *	- multichip mode
- *	- scc configuration
- *	- silicon revision
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-	uint64_t remote_ddr_size;
-	uint8_t remote_chip_count;
-	bool multichip_mode;
-	uint32_t scc_config;
-	uint32_t silicon_revision;
-} __packed;
-
+#ifdef TARGET_PLATFORM_SOC
 struct morello_plat_info plat_info;
 #endif
 
-/* Compile time assertion to ensure the size of structure is of the required bytes */
-CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
-		assert_invalid_plat_info_size);
-
 static scmi_channel_plat_info_t morello_scmi_plat_info = {
 	.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
 	.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
@@ -67,6 +34,7 @@
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
+	ops->pwr_domain_off = morello_pwr_domain_off;
 	return css_scmi_override_pm_ops(ops);
 }
 
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
index 2898774..e42a03c 100644
--- a/plat/arm/board/morello/morello_def.h
+++ b/plat/arm/board/morello/morello_def.h
@@ -89,4 +89,41 @@
 #define MORELLO_DMC_MEMC_CMD_CONFIG		U(0)
 #define MORELLO_DMC_MEMC_CMD_READY		U(3)
 
+/* SDS Platform information struct definition */
+#ifdef TARGET_PLATFORM_FVP
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size
+ *	- Local DDR size in bytes, DDR memory in main board
+ */
+struct morello_plat_info {
+	uint64_t local_ddr_size;
+} __packed;
+#else
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which is an information about multichip setup
+ *	- Local DDR size in bytes, DDR memory in main board
+ *	- Remote DDR size in bytes, DDR memory in remote board
+ *	- remote_chip_count
+ *	- multichip mode
+ *	- scc configuration
+ *	- silicon revision
+ */
+struct morello_plat_info {
+	uint64_t local_ddr_size;
+	uint64_t remote_ddr_size;
+	uint8_t remote_chip_count;
+	bool multichip_mode;
+	uint32_t scc_config;
+	uint32_t silicon_revision;
+} __packed;
+#endif
+
+/* Compile time assertion to ensure the size of structure is of the required bytes */
+CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
+		assert_invalid_plat_info_size);
+
 #endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index 5fc87a0..b5d9bd5 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -14,38 +14,6 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- *	- Remote DDR size in bytes, DDR memory in remote board
- *	- remote_chip_count
- *	- multichip mode
- *	- scc configuration
- *	- silicon revision
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-	uint64_t remote_ddr_size;
-	uint8_t remote_chip_count;
-	bool multichip_mode;
-	uint32_t scc_config;
-	uint32_t silicon_revision;
-} __packed;
-#endif
-
 /* In client mode, a part of the DDR memory is reserved for Tag bits.
  * Calculate the usable memory size after subtracting the Tag memory.
  */
diff --git a/plat/arm/board/morello/morello_pm.c b/plat/arm/board/morello/morello_pm.c
new file mode 100644
index 0000000..fa7bd1d
--- /dev/null
+++ b/plat/arm/board/morello/morello_pm.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+#include "morello_private.h"
+
+/*******************************************************************************
+ * Morello specific function called when turning off a power domain.
+ * Additionally disables the GIC redistributor interface as cores are disabled
+ * to let cluster-PPU state transition to completion when a cluster is
+ * powered down.
+ ******************************************************************************/
+void morello_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	css_pwr_domain_off(target_state);
+	plat_arm_gic_redistif_off();
+}
diff --git a/plat/arm/board/morello/morello_private.h b/plat/arm/board/morello/morello_private.h
new file mode 100644
index 0000000..dea70fb
--- /dev/null
+++ b/plat/arm/board/morello/morello_private.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MORELLO_PRIVATE_H
+#define MORELLO_PRIVATE_H
+
+#include <lib/psci/psci.h>
+
+void morello_pwr_domain_off(const psci_power_state_t *target_state);
+
+#endif /* MORELLO_PRIVATE_H */
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 0f0cabb..0ae7693 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -49,6 +49,7 @@
 				${INTERCONNECT_SOURCES}			\
 				${MORELLO_GIC_SOURCES}			\
 				${MORELLO_BASE}/morello_bl31_setup.c	\
+				${MORELLO_BASE}/morello_pm.c		\
 				${MORELLO_BASE}/morello_topology.c	\
 				${MORELLO_BASE}/morello_security.c	\
 				drivers/arm/css/sds/sds.c
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index b3799a7..74d0c91 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -190,11 +190,47 @@
 #define PLAT_CSS_MHU_BASE			0x45000000
 #define PLAT_MAX_PWR_LVL			2
 
-#define PLAT_ARM_G1S_IRQS			ARM_G1S_IRQS,			\
-						CSS_IRQ_MHU
-#define PLAT_ARM_G0_IRQS			ARM_G0_IRQS
+/* Interrupt handling constants */
+#define N1SDP_IRQ_MMU_TCU1_EVENT_Q_SEC		U(257)
+#define N1SDP_IRQ_MMU_TCU1_CMD_SYNC_SEC		U(258)
+#define N1SDP_IRQ_MMU_TCU1_GLOBAL		U(259)
+#define N1SDP_IRQ_MMU_TCU2_EVENT_Q_SEC		U(264)
+#define N1SDP_IRQ_MMU_TCU2_CMD_SYNC_SEC		U(265)
+#define N1SDP_IRQ_MMU_TCU2_GLOBAL		U(266)
+#define N1SDP_IRQ_CLUSTER0_MHU			U(349)
+#define N1SDP_IRQ_CLUSTER1_MHU			U(351)
+#define N1SDP_IRQ_P0_REFCLK			U(412)
+#define N1SDP_IRQ_P1_REFCLK			U(413)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+	ARM_G1S_IRQ_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU1_EVENT_Q_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU1_CMD_SYNC_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU1_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU2_EVENT_Q_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU2_CMD_SYNC_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU2_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_CLUSTER0_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_CLUSTER1_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_P0_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_P1_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
 #define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
 
 
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index ad6c1f8..430aab6 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <plat/arm/common/plat_arm.h>
 
 #include "n1sdp_def.h"
+#include "n1sdp_private.h"
 #include <platform_def.h>
 
 /*
@@ -51,8 +52,8 @@
 		PLAT_ARM_GICD_BASE >> 16
 	},
 	.spi_ids = {
-		{32, 479},
-		{512, 959}
+		{PLAT_ARM_GICD_BASE, 32, 511},
+		{PLAT_ARM_GICD_BASE, 512, 991}
 	}
 };
 
@@ -69,6 +70,7 @@
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
+	ops->pwr_domain_off = n1sdp_pwr_domain_off;
 	return css_scmi_override_pm_ops(ops);
 }
 
@@ -159,3 +161,14 @@
 	if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
 		remote_dmc_ecc_setup(plat_info.remote_ddr_size);
 }
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
diff --git a/plat/arm/board/n1sdp/n1sdp_pm.c b/plat/arm/board/n1sdp/n1sdp_pm.c
new file mode 100644
index 0000000..8d45354
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_pm.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+#include "n1sdp_private.h"
+
+/*******************************************************************************
+ * N1SDP specific function called when turning off a power domain. Additionally
+ * disables the GIC redistributor interface as cores are disabled to
+ * let cluster-PPU state transition to completion when a cluster is powered
+ * down.
+ ******************************************************************************/
+void n1sdp_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	css_pwr_domain_off(target_state);
+	plat_arm_gic_redistif_off();
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_private.h b/plat/arm/board/n1sdp/n1sdp_private.h
new file mode 100644
index 0000000..4e48c0f
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_private.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef N1SDP_PRIVATE_H
+#define N1SDP_PRIVATE_H
+
+#include <lib/psci/psci.h>
+
+void n1sdp_pwr_domain_off(const psci_power_state_t *target_state);
+
+#endif /* N1SDP_PRIVATE_H */
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 9c0cc02..bd62614 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -47,6 +47,7 @@
 				${INTERCONNECT_SOURCES}			\
 				${N1SDP_GIC_SOURCES}			\
 				${N1SDP_BASE}/n1sdp_bl31_setup.c	\
+				${N1SDP_BASE}/n1sdp_pm.c		\
 				${N1SDP_BASE}/n1sdp_topology.c	        \
 				${N1SDP_BASE}/n1sdp_security.c		\
 				drivers/arm/css/sds/sds.c
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index 0f9dd49..4a9a467 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -1,9 +1,12 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+$(warning Platform ${PLAT} is deprecated. \
+  Some of the features might not work as expected)
+
 include plat/arm/css/sgi/sgi-common.mk
 
 RDE1EDGE_BASE		=	plat/arm/board/rde1edge
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c
index 045c316..6da8bcd 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c
@@ -27,8 +27,8 @@
 		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
 	},
 	.spi_ids = {
-		{32, 255},
-		{0, 0}
+		{PLAT_ARM_GICD_BASE, 32, 255},
+		{0, 0, 0}
 	}
 };
 
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 8e63de5..ff1a437 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -8,7 +8,7 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
-
+#include <sgi_sdei.h>
 #include <sgi_soc_platform_def_v2.h>
 
 #if (CSS_SGI_PLATFORM_VARIANT == 1)
diff --git a/plat/arm/board/rdn2/include/rdn2_ras.h b/plat/arm/board/rdn2/include/rdn2_ras.h
new file mode 100644
index 0000000..1d9af60
--- /dev/null
+++ b/plat/arm/board/rdn2/include/rdn2_ras.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDN2_RAS_H
+#define RDN2_RAS_H
+
+#include <sgi_ras.h>
+
+extern struct plat_sgi_ras_config ras_config;
+
+#endif /* RDN2_RAS_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index b30e3fc..9ebca23 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -69,6 +69,12 @@
 BL31_CFLAGS		+=	-DPLAT_XLAT_TABLES_DYNAMIC
 endif
 
+ifeq (${RAS_FFH_SUPPORT},1)
+BL31_SOURCES		+=	${RDN2_BASE}/rdn2_ras.c			\
+				${CSS_ENT_BASE}/ras/sgi_ras_common.c	\
+				${CSS_ENT_BASE}/ras/sgi_ras_sram.c
+endif
+
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${RDN2_BASE}/fdts/${PLAT}_fw_config.dts	\
 				${RDN2_BASE}/fdts/${PLAT}_tb_fw_config.dts
@@ -87,4 +93,4 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_AMU			:= 1
+override ENABLE_FEAT_AMU		:= 1
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index 2506f9d..e8a967e 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -8,6 +8,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <rdn2_ras.h>
 #include <sgi_soc_platform_def_v2.h>
 #include <sgi_plat.h>
 
@@ -47,15 +48,15 @@
 #endif
 	},
 	.spi_ids = {
-		{32, 511},
+		{PLAT_ARM_GICD_BASE, 32, 511},
 	#if CSS_SGI_CHIP_COUNT > 1
-		{512, 991},
+		{PLAT_ARM_GICD_BASE, 512, 991},
 	#endif
 	#if CSS_SGI_CHIP_COUNT > 2
-		{4096, 4575},
+		{PLAT_ARM_GICD_BASE, 4096, 4575},
 	#endif
 	#if CSS_SGI_CHIP_COUNT > 3
-		{4576, 5055},
+		{PLAT_ARM_GICD_BASE, 4576, 5055},
 	#endif
 	}
 };
@@ -134,5 +135,9 @@
 #endif
 
 	sgi_bl31_common_platform_setup();
+
+#if RAS_FFH_SUPPORT
+	sgi_ras_platform_setup(&ras_config);
+#endif
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn2/rdn2_ras.c b/plat/arm/board/rdn2/rdn2_ras.c
new file mode 100644
index 0000000..c1e5ab6
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_ras.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+#include <sgi_ras.h>
+#include <sgi_sdei.h>
+
+struct sgi_ras_ev_map plat_ras_map[] = {
+	/* Non Secure base RAM ECC CE interrupt */
+	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_CE_INT, SGI_RAS_INTR_TYPE_SPI},
+
+	/* Non Secure base RAM ECC UE interrupt */
+	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_UE_INT, SGI_RAS_INTR_TYPE_SPI},
+};
+
+/* RAS error record list definition, used by the common RAS framework. */
+struct err_record_info plat_err_records[] = {
+	/* Base element RAM Non-secure error record. */
+	ERR_RECORD_MEMMAP_V1(SOC_NS_RAM_ERR_REC_BASE, 4, NULL,
+				&sgi_ras_sram_intr_handler, 0),
+};
+
+/* RAS error interrupt list definition, used by the common RAS framework. */
+struct ras_interrupt plat_ras_interrupts[] = {
+	{
+		.intr_number = NS_RAM_ECC_CE_INT,
+		.err_record = &plat_err_records[0],
+	}, {
+		.intr_number = NS_RAM_ECC_UE_INT,
+		.err_record = &plat_err_records[0],
+	},
+};
+
+/* Registers the RAS error record list with common RAS framework. */
+REGISTER_ERR_RECORD_INFO(plat_err_records);
+/* Registers the RAS error interrupt info list with common RAS framework. */
+REGISTER_RAS_INTERRUPTS(plat_ras_interrupts);
+
+/* Platform RAS handling config data definition */
+struct plat_sgi_ras_config ras_config = {
+	plat_ras_map,
+	ARRAY_SIZE(plat_ras_map)
+};
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
index dff6a19..b836a7f 100644
--- a/plat/arm/board/rdn2/rdn2_security.c
+++ b/plat/arm/board/rdn2/rdn2_security.c
@@ -8,8 +8,16 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
+#define RDN2_TZC_CPER_REGION					\
+	{CSS_SGI_SP_CPER_BUF_BASE, (CSS_SGI_SP_CPER_BUF_BASE +	\
+	CSS_SGI_SP_CPER_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+	PLAT_ARM_TZC_NS_DEV_ACCESS}
+
 static const arm_tzc_regions_info_t tzc_regions[] = {
 	ARM_TZC_REGIONS_DEF,
+#if RAS_FFH_SUPPORT
+	RDN2_TZC_CPER_REGION,
+#endif
 	{}
 };
 
diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk
index 11f5212..a5fba67 100644
--- a/plat/arm/board/rdv1/platform.mk
+++ b/plat/arm/board/rdv1/platform.mk
@@ -57,7 +57,7 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_AMU			:= 1
+override ENABLE_FEAT_AMU		:= 1
 
 ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
  $(error "CSS_SGI_PLATFORM_VARIANT for RD-V1 should always be 0, \
diff --git a/plat/arm/board/rdv1mc/platform.mk b/plat/arm/board/rdv1mc/platform.mk
index df0b09a..92f7c10 100644
--- a/plat/arm/board/rdv1mc/platform.mk
+++ b/plat/arm/board/rdv1mc/platform.mk
@@ -68,7 +68,7 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_AMU			:= 1
+override ENABLE_FEAT_AMU		:= 1
 
 ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
  $(error "CSS_SGI_PLATFORM_VARIANT for RD-V1-MC should always be 0, \
diff --git a/plat/arm/board/rdv1mc/rdv1mc_plat.c b/plat/arm/board/rdv1mc/rdv1mc_plat.c
index d859400..e4469dc 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_plat.c
+++ b/plat/arm/board/rdv1mc/rdv1mc_plat.c
@@ -43,13 +43,13 @@
 #endif
 	},
 	.spi_ids = {
-		{32, 255},
-		{0, 0},
+		{PLAT_ARM_GICD_BASE, 32, 255},
+		{0, 0, 0},
 #if (CSS_SGI_CHIP_COUNT > 2)
-		{0, 0},
+		{0, 0, 0},
 #endif
 #if (CSS_SGI_CHIP_COUNT > 3)
-		{0, 0},
+		{0, 0, 0},
 #endif
 	}
 };
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
index d3a5e1a..b64e076 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -117,9 +117,16 @@
 		};
 	};
 
-	/* 32MB of TC_TZC_DRAM1_BASE */
-	memory@fd000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0xfd000000 0x2000000>;
+		reg = <0x0 0xfd000000 0x0 0x2000000>,
+		      <0x0 0x7000000 0x0 0x1000000>,
+		      <0x0 0xff000000 0x0 0x1000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x1 0x00000000>;
 	};
 };
diff --git a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
index 92e2ddd..382f0e1 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -116,9 +116,14 @@
 		};
 	};
 
-	/* 32MB of TC_TZC_DRAM1_BASE */
-	memory@fd000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0xfd000000 0x2000000>;
+		reg = <0x0 0xfd000000 0x0 0x2000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x0 0x80000000 0x0 0x79000000>,
+		      <0x80 0x80000000 0x1 0x80000000>;
 	};
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index eea1be6..59fff6e 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -212,8 +212,11 @@
 #define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
-#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_INT_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp),	\
+					INTR_PROP_DESC(SBSA_SECURE_WDOG_INTID,	\
+						GIC_HIGHEST_SEC_PRIORITY, grp, \
+						GIC_INTR_CFG_LEVEL)
 
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
@@ -229,9 +232,11 @@
 #define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
-/*Secure Watchdog Constants */
-#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_CONTROL_BASE	UL(0x2A480000)
+#define SBSA_SECURE_WDOG_REFRESH_BASE	UL(0x2A490000)
 #define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
+#define SBSA_SECURE_WDOG_INTID		86
 
 #define PLAT_ARM_SCMI_CHANNEL_COUNT	1
 
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index ba1831f..117fbb4 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -9,9 +9,12 @@
 
 void tc_bl31_common_platform_setup(void);
 
-#ifdef PLATFORM_TEST
-void run_platform_tests(void);
-void nv_counter_test(void);
+#ifdef PLATFORM_TEST_TFM_TESTSUITE
+int run_platform_tests(void);
+#endif
+
+#ifdef PLATFORM_TEST_NV_COUNTERS
+int nv_counter_test(void);
 #endif
 
 #endif /* TC_PLAT_H */
diff --git a/plat/arm/board/tc/nv_counter_test.c b/plat/arm/board/tc/nv_counter_test.c
index 76c9915..f9e001e 100644
--- a/plat/arm/board/tc/nv_counter_test.c
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -13,7 +13,7 @@
 
 #include <platform_def.h>
 
-void nv_counter_test(void)
+int nv_counter_test(void)
 {
 	psa_status_t status;
 	uint32_t old_val;
@@ -23,7 +23,7 @@
 	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
 		printf("Failed to initialize RSS communication channel\n");
-		plat_error_handler(-1);
+		return -1;
 	}
 
 	for (id = 0; id < 3; id++) {
@@ -31,28 +31,30 @@
 		if (status != PSA_SUCCESS) {
 			printf("Failed during first id=(%d) rss_platform_nv_counter_read\n",
 				       id);
-			plat_error_handler(-1);
+			return -1;
 		}
 
 		status = rss_platform_nv_counter_increment(id);
 		if (status != PSA_SUCCESS) {
 			printf("Failed during id=(%d) rss_platform_nv_counter_increment\n",
 					id);
-			plat_error_handler(-1);
+			return -1;
 		}
 
 		status = rss_platform_nv_counter_read(id, sizeof(new_val), (uint8_t *)&new_val);
 		if (status != PSA_SUCCESS) {
 			printf("Failed during second id=(%d) rss_platform_nv_counter_read\n",
 					id);
-			plat_error_handler(-1);
+			return -1;
 		}
 
 		if (old_val + 1 != new_val) {
 			printf("Failed nv_counter_test: old_val (%d) + 1 != new_val (%d)\n",
 					old_val, new_val);
-			plat_error_handler(-1);
+			return -1;
 		}
 	}
 	printf("Passed nv_counter_test\n");
+
+	return 0;
 }
diff --git a/plat/arm/board/tc/plat_fiptool.mk b/plat/arm/board/tc/plat_fiptool.mk
deleted file mode 100644
index 0e13556..0000000
--- a/plat/arm/board/tc/plat_fiptool.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2021, NXP. All rights reserved.
-# Copyright (c) 2022, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# Name of the platform defined source file name,
-# which contains platform defined UUID entries populated
-# in the plat_def_toc_entries[].
-PLAT_DEF_UUID_CONFIG_FILE_NAME	:= plat_def_uuid_config
-
-PLAT_DEF_UUID_CONFIG_FILE_PATH := ../../plat/arm/board/tc
-
-PLAT_DEF_UUID := yes
-PLAT_DEF_UUID_OID_CONFIG_PATH := ../../plat/arm/board/tc
-
-
-INCLUDE_PATHS += -I${PLAT_DEF_UUID_OID_CONFIG_PATH} \
-		 -I./
-# Clean the stale object file.
-$(shell rm ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o)
-
-ifeq (${PLAT_DEF_OID},yes)
-HOSTCCFLAGS += -DPLAT_DEF_OID
-endif
-
-ifeq (${PLAT_DEF_UUID},yes)
-HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
-PLAT_OBJECTS += ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o
-endif
-
-OBJECTS += ${PLAT_OBJECTS}
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
index d776b63..f0aa60b 100644
--- a/plat/arm/board/tc/plat_tc_mbedtls_config.h
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Ltd. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,8 @@
 #ifndef PLAT_TC_MBEDTLS_CONFIG_H
 #define PLAT_TC_MBEDTLS_CONFIG_H
 
-#include <mbedtls_config.h>
 #include <export/lib/utils_def_exp.h>
+#include <mbedtls_config-3.h>
 
 #ifndef TF_MBEDTLS_HEAP_SIZE
 #error TF_MBEDTLS_HEAP_SIZE is not defined
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 05dca91..5a1d83a 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -6,8 +6,7 @@
 include common/fdt_wrappers.mk
 
 ifeq ($(TARGET_PLATFORM), 0)
-$(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
-Some of the features might not work as expected)
+	$(error Platform ${PLAT}$(TARGET_PLATFORM) is deprecated.)
 endif
 
 ifeq ($(shell expr $(TARGET_PLATFORM) \<= 2), 0)
@@ -20,7 +19,9 @@
 
 CSS_USE_SCMI_SDS_DRIVER	:=	1
 
-RAS_EXTENSION		:=	0
+ENABLE_FEAT_RAS		:=	1
+
+RAS_FFH_SUPPORT		:=	0
 
 SDEI_SUPPORT		:=	0
 
@@ -41,7 +42,7 @@
 GICV3_SUPPORT_GIC600	:=	1
 
 # Enable SVE
-ENABLE_SVE_FOR_NS	:=	1
+ENABLE_SVE_FOR_NS	:=	2
 ENABLE_SVE_FOR_SWD	:=	1
 
 # enable trace buffer control registers access to NS by default
@@ -53,9 +54,6 @@
 # enable trace filter control registers access to NS by default
 ENABLE_TRF_FOR_NS               := 1
 
-# Enable RSS-required FIP UUIDs
-$(shell cp plat/arm/board/tc/plat_fiptool.mk ${PLAT_DIR})
-
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
@@ -71,13 +69,6 @@
 
 PLAT_INCLUDES		+=	-I${TC_BASE}/include/
 
-# CPU libraries for TARGET_PLATFORM=0
-ifeq (${TARGET_PLATFORM}, 0)
-TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a510.S	\
-			lib/cpus/aarch64/cortex_a710.S	\
-			lib/cpus/aarch64/cortex_x2.S
-endif
-
 # CPU libraries for TARGET_PLATFORM=1
 ifeq (${TARGET_PLATFORM}, 1)
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a510.S \
@@ -87,9 +78,9 @@
 
 # CPU libraries for TARGET_PLATFORM=2
 ifeq (${TARGET_PLATFORM}, 2)
-TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_hayes.S \
-			lib/cpus/aarch64/cortex_hunter.S \
-			lib/cpus/aarch64/cortex_hunter_elp_arm.S
+TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
+			lib/cpus/aarch64/cortex_a720.S \
+			lib/cpus/aarch64/cortex_x4.S
 endif
 
 INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c
@@ -121,7 +112,8 @@
 				lib/fconf/fconf_dyn_cfg_getter.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
+				plat/arm/common/arm_nor_psci_mem_protect.c	\
+				drivers/arm/sbsa/sbsa.c
 
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
@@ -161,9 +153,9 @@
 
 override CTX_INCLUDE_PAUTH_REGS	:= 1
 
-override ENABLE_SPE_FOR_LOWER_ELS	:= 0
+override ENABLE_SPE_FOR_NS	:= 0
 
-override ENABLE_AMU := 1
+override ENABLE_FEAT_AMU := 1
 override ENABLE_AMU_AUXILIARY_COUNTERS := 1
 override ENABLE_AMU_FCONF := 1
 
@@ -196,28 +188,32 @@
 
 endif
 
-ifeq (${PLATFORM_TEST},rss-nv-counters)
-    include drivers/arm/rss/rss_comms.mk
+ifneq (${PLATFORM_TEST},)
+    $(eval $(call add_define,PLATFORM_TESTS))
 
-    # Test code.
-    BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
+    ifeq (${PLATFORM_TEST},rss-nv-counters)
+        include drivers/arm/rss/rss_comms.mk
 
-    # Code under testing.
-    BL31_SOURCES	+=	lib/psa/rss_platform.c \
+        # Test code.
+        BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
+
+        # Code under testing.
+        BL31_SOURCES	+=	lib/psa/rss_platform.c \
 				drivers/arm/rss/rss_comms.c \
 				${RSS_COMMS_SOURCES}
 
-    PLAT_INCLUDES	+=	-Iinclude/lib/psa
+        PLAT_INCLUDES	+=	-Iinclude/lib/psa
 
-    $(eval $(call add_define,PLATFORM_TEST))
-else ifeq (${PLATFORM_TEST},tfm-testsuite)
-    # Add this include as first, before arm_common.mk. This is necessary
-    # because arm_common.mk builds Mbed TLS, and platform_test.mk can
-    # change the list of Mbed TLS files that are to be compiled
-    # (LIBMBEDTLS_SRCS).
-    include plat/arm/board/tc/platform_test.mk
-else ifneq (${PLATFORM_TEST},)
-    $(error "Unsupported PLATFORM_TEST value")
+        $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
+    else ifeq (${PLATFORM_TEST},tfm-testsuite)
+        # Add this include as first, before arm_common.mk. This is necessary
+        # because arm_common.mk builds Mbed TLS, and platform_test.mk can
+        # change the list of Mbed TLS files that are to be compiled
+        # (LIBMBEDTLS_SRCS).
+        include plat/arm/board/tc/platform_test.mk
+    else
+        $(error "Unsupported PLATFORM_TEST value")
+    endif
 endif
 
 
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index 5cdbb86..e974855 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -76,5 +76,5 @@
     $(eval $(call add_define,MEASURED_BOOT_HASH_ALG))
     $(eval $(call add_define,DELEG_ATTEST_DUMP_TOKEN_AND_KEY))
 
-    $(eval $(call add_define,PLATFORM_TEST))
+    $(eval $(call add_define,PLATFORM_TEST_TFM_TESTSUITE))
 endif
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rss_ap_tests.c
index b62043e..8c40271 100644
--- a/plat/arm/board/tc/rss_ap_tests.c
+++ b/plat/arm/board/tc/rss_ap_tests.c
@@ -19,21 +19,28 @@
 	{.freg = register_testsuite_measured_boot},
 };
 
-static void run_tests(void)
+/*
+ * Return 0 if we could run all tests.
+ * Note that this does not mean that all tests passed - only that they all run.
+ * One should then look at each individual test result inside the
+ * test_suites[].val field.
+ */
+static int run_tests(void)
 {
 	enum test_suite_err_t ret;
 	psa_status_t status;
 	size_t i;
 
+	/* Initialize test environment. */
 	rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
 	mbedtls_init();
 	status = psa_crypto_init();
 	if (status != PSA_SUCCESS) {
 		printf("\n\npsa_crypto_init failed (status = %d)\n", status);
-		assert(false);
-		plat_error_handler(-1);
+		return -1;
 	}
 
+	/* Run all tests. */
 	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
 		struct test_suite_t *suite = &(test_suites[i]);
 
@@ -41,22 +48,33 @@
 		ret = run_testsuite(suite);
 		if (ret != TEST_SUITE_ERR_NO_ERROR) {
 			printf("\n\nError during executing testsuite '%s'.\n", suite->name);
-			assert(false);
-			plat_error_handler(-1);
+			return -1;
 		}
 	}
 	printf("\nAll tests are run.\n");
+
+	return 0;
 }
 
 void run_platform_tests(void)
 {
 	size_t i;
+	int ret;
+	int failures = 0;
 
-	run_tests();
+	ret = run_tests();
+	if (ret != 0) {
+		/* For some reason, we could not run all tests. */
+		return ret;
+	}
 
 	printf("\n\n");
 
-	/* Print a summary of all the tests that had been run. */
+	/*
+	 * Print a summary of all the tests that had been run.
+	 * Also count the number of tests failure and report that back to the
+	 * caller.
+	 */
 	printf("SUMMARY:\n");
 	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
 
@@ -67,6 +85,7 @@
 			printf("    %s PASSED.\n", suite->name);
 			break;
 		case TEST_FAILED:
+			failures++;
 			printf("    %s FAILED.\n", suite->name);
 			break;
 		case TEST_SKIPPED:
@@ -79,4 +98,6 @@
 	}
 
 	printf("\n\n");
+
+	return failures;
 }
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
index 0d29c51..6d4bb07 100644
--- a/plat/arm/board/tc/tc_bl1_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,7 +46,7 @@
 	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
 			     PLAT_RSS_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(tc_rss_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index 7ea2c2e..9039853 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,7 +45,7 @@
 	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
 			     PLAT_RSS_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(tc_rss_mboot_metadata);
 }
 
 void bl2_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 1c1e2fb..ca3a032 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
+#include <drivers/arm/sbsa.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
@@ -49,18 +50,34 @@
 	fconf_populate("FW_CONFIG", arg1);
 }
 
-void tc_bl31_common_platform_setup(void)
+#ifdef PLATFORM_TESTS
+static __dead2 void tc_run_platform_tests(void)
 {
-	arm_bl31_platform_setup();
+	int tests_failed;
 
-#ifdef PLATFORM_TEST
-#if PLATFORM_TEST == rss-nv-counters
-	nv_counter_test();
-#elif PLATFORM_TEST == tfm-testsuite
-	run_platform_tests()
+	printf("\nStarting platform tests...\n");
+
+#ifdef PLATFORM_TEST_NV_COUNTERS
+	tests_failed = nv_counter_test();
+#elif PLATFORM_TEST_TFM_TESTSUITE
+	tests_failed = run_platform_tests();
 #endif
-	/* Suspend booting */
+
+	printf("Platform tests %s.\n",
+	       (tests_failed != 0) ? "failed" : "succeeded");
+
+	/* Suspend booting, no matter the tests outcome. */
+	printf("Suspend booting...\n");
 	plat_error_handler(-1);
+}
+#endif
+
+void tc_bl31_common_platform_setup(void)
+{
+	arm_bl31_platform_setup();
+
+#ifdef PLATFORM_TESTS
+	tc_run_platform_tests();
 #endif
 }
 
@@ -81,3 +98,37 @@
 
 	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
 }
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+void tc_bl31_plat_runtime_setup(void)
+{
+	arm_bl31_plat_runtime_setup();
+
+	/* Start secure watchdog timer. */
+	plat_arm_secure_wdt_start();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	tc_bl31_plat_runtime_setup();
+}
+
+/*
+ * Platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/* Trusted Watchdog timer is the only source of Group0 interrupt now. */
+	if (intid == SBSA_SECURE_WDOG_INTID) {
+		INFO("Watchdog restarted\n");
+		/* Refresh the timer. */
+		plat_arm_secure_wdt_refresh();
+
+		/* Deactivate the corresponding interrupt. */
+		plat_ic_end_of_interrupt(intid);
+		return 0;
+	}
+
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
diff --git a/plat/arm/board/tc/tc_common_measured_boot.c b/plat/arm/board/tc/tc_common_measured_boot.c
index fe71899..eddcc81 100644
--- a/plat/arm/board/tc/tc_common_measured_boot.c
+++ b/plat/arm/board/tc/tc_common_measured_boot.c
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,17 +12,13 @@
 
 extern struct rss_mboot_metadata tc_rss_mboot_metadata[];
 
-struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
-{
-	return tc_rss_mboot_metadata;
-}
-
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
 
 	/* Calculate image hash and record data in RSS */
-	err = rss_mboot_measure_and_record(image_data->image_base,
+	err = rss_mboot_measure_and_record(tc_rss_mboot_metadata,
+					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
 	if (err != 0) {
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 228f2fa..766bfb5 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -147,10 +147,15 @@
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(SBSA_SECURE_WDOG_CONTROL_BASE, SBSA_SECURE_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_CONTROL_BASE);
+}
+
+void plat_arm_secure_wdt_refresh(void)
+{
+	sbsa_wdog_refresh(SBSA_SECURE_WDOG_REFRESH_BASE);
 }
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index 3d7b361..e512192 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -220,8 +220,20 @@
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
 			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
 		.next_handoff_image_id = INVALID_IMAGE_ID,
-	}
+	},
 #endif /* EL3_PAYLOAD_BASE */
+
+# if ARM_ETHOSN_NPU_TZMP1
+	{
+		.image_id = ARM_ETHOSN_NPU_FW_IMAGE_ID,
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t, 0),
+		.image_info.image_base = ARM_ETHOSN_NPU_FW_IMAGE_BASE,
+		.image_info.image_max_size = ARM_ETHOSN_NPU_FW_IMAGE_LIMIT -
+			ARM_ETHOSN_NPU_FW_IMAGE_BASE,
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+# endif
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 19efdd3..cfd1aac 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,6 +43,7 @@
 #pragma weak bl31_platform_setup
 #pragma weak bl31_plat_arch_setup
 #pragma weak bl31_plat_get_next_image_ep_info
+#pragma weak bl31_plat_runtime_setup
 
 #define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
 					BL31_START,			\
@@ -294,7 +295,7 @@
 	/* Initialize power controller before setting up topology */
 	plat_arm_pwrc_setup();
 
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	ras_init();
 #endif
 
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 4d5a56a..647a9d9 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -119,6 +119,43 @@
 $(eval $(call assert_boolean,ARM_ETHOSN_NPU_DRIVER))
 $(eval $(call add_define,ARM_ETHOSN_NPU_DRIVER))
 
+# Arm(R) Ethos(TM)-N NPU TZMP1
+ARM_ETHOSN_NPU_TZMP1			:=	0
+$(eval $(call assert_boolean,ARM_ETHOSN_NPU_TZMP1))
+$(eval $(call add_define,ARM_ETHOSN_NPU_TZMP1))
+ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
+  ifeq (${ARM_ETHOSN_NPU_DRIVER},0)
+    $(error ARM_ETHOSN_NPU_TZMP1 is only available if ARM_ETHOSN_NPU_DRIVER=1)
+  endif
+  ifeq (${PLAT},juno)
+    $(eval $(call add_define,JUNO_ETHOSN_TZMP1))
+  else
+    $(error ARM_ETHOSN_NPU_TZMP1 only supported on Juno platform, not ${PLAT})
+  endif
+
+  ifeq (${TRUSTED_BOARD_BOOT},0)
+    # We rely on TRUSTED_BOARD_BOOT to prevent the firmware code from being
+    # tampered with, which is required to protect the confidentiality of protected
+    # inference data.
+    $(error ARM_ETHOSN_NPU_TZMP1 is only available if TRUSTED_BOARD_BOOT is enabled)
+  endif
+
+  # We need the FW certificate and key certificate
+  $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_key.crt,--npu-fw-key-cert))
+  $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_content.crt,--npu-fw-cert))
+  # Needed for our OIDs to be available in tbbr_cot_bl2.c
+  $(eval $(call add_define, PLAT_DEF_OID))
+  PLAT_INCLUDES	+=	-I${PLAT_DIR}certificate/include
+  PLAT_INCLUDES	+=	-Iinclude/drivers/arm/
+
+  # We need the firmware to be built into the FIP
+  $(eval $(call TOOL_ADD_IMG,ARM_ETHOSN_NPU_FW,--npu-fw))
+
+  # Needed so that UUIDs from the FIP are available in BL2
+  $(eval $(call add_define,PLAT_DEF_FIP_UUID))
+  PLAT_INCLUDES		+=	-I${PLAT_DIR}fip
+endif # ARM_ETHOSN_NPU_TZMP1
+
 # Use an implementation of SHA-256 with a smaller memory footprint but reduced
 # speed.
 $(eval $(call add_define,MBEDTLS_SHA256_SMALLER))
@@ -322,6 +359,9 @@
 ARM_SVC_HANDLER_SRCS	+=	plat/arm/common/fconf/fconf_ethosn_getter.c	\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/arm/ethosn/ethosn_smc.c
+ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
+ARM_SVC_HANDLER_SRCS	+=	drivers/arm/ethosn/ethosn_big_fw.c
+endif
 endif
 
 ifeq (${ARCH}, aarch64)
@@ -346,15 +386,14 @@
 endif
 
 # RAS sources
-ifeq (${RAS_EXTENSION},1)
+ifeq (${RAS_FFH_SUPPORT},1)
 BL31_SOURCES		+=	lib/extensions/ras/std_err_record.c		\
 				lib/extensions/ras/ras_common.c
 endif
 
 # Pointer Authentication sources
 ifeq (${ENABLE_PAUTH}, 1)
-PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c	\
-				lib/extensions/pauth/pauth_helpers.S
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
 endif
 
 ifeq (${SPD},spmd)
@@ -382,8 +421,11 @@
         ifneq (${COT_DESC_IN_DTB},0)
             BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
         else
-            BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c	\
-				drivers/auth/tbbr/tbbr_cot_bl2.c
+            BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
+	    # Juno has its own TBBR CoT file for BL2
+            ifneq (${PLAT},juno)
+                BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_bl2.c
+            endif
         endif
     else ifeq (${COT},dualroot)
         AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index e88ea65..5dc1115 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,12 +28,15 @@
  * Currently OP-TEE does not support reading DTBs from Secure memory
  * and this property should be removed when this feature is supported.
  */
-#define DTB_PROP_HW_SM_LOG_ADDR	"tpm_event_log_sm_addr"
+#define DTB_PROP_HW_SM_LOG_ADDR		"tpm_event_log_sm_addr"
 #endif /* SPD_opteed */
-#define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
-#define DTB_PROP_HW_LOG_SIZE    "tpm_event_log_size"
+#define DTB_PROP_HW_LOG_ADDR		"tpm_event_log_addr"
+#define DTB_PROP_HW_LOG_SIZE    	"tpm_event_log_size"
+#define DTB_PROP_HW_LOG_MAX_SIZE	"tpm_event_log_max_size"
 #endif /* MEASURED_BOOT */
 
+static size_t event_log_max_size __unused;
+
 /*******************************************************************************
  * Validate the tb_fw_config is a valid DTB file and returns the node offset
  * to "arm,tb_fw" property.
@@ -180,6 +183,16 @@
 		return err;
 	}
 
+	assert(event_log_max_size != 0U);
+	err = fdtw_write_inplace_cells(dtb, node,
+				       DTB_PROP_HW_LOG_MAX_SIZE, 1,
+				       &event_log_max_size);
+	if (err < 0) {
+		ERROR("%sDTB property '%s'\n",
+		      "Unable to write ", DTB_PROP_HW_LOG_MAX_SIZE);
+		return err;
+	}
+
 	err = fdtw_write_inplace_cells(dtb, node,
 		DTB_PROP_HW_LOG_SIZE, 1, &log_size);
 	if (err < 0) {
@@ -294,7 +307,7 @@
  *     0 = success
  *   < 0 = error
  */
-int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size)
+int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size, size_t log_max_size)
 {
 	/*
 	 * Read tb_fw_config device tree for Event Log properties
@@ -309,6 +322,8 @@
 
 	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
 
+	event_log_max_size = log_max_size;
+
 	err = arm_set_event_log_info(tb_fw_cfg_dtb,
 #ifdef SPD_opteed
 				     0UL,
@@ -329,7 +344,8 @@
  * Alongside returns Event Log address and its size.
  */
 
-int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size)
+int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
+		       size_t *log_max_size)
 {
 	/* As libfdt uses void *, we can't avoid this cast */
 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
@@ -362,6 +378,17 @@
 	if (rc != 0) {
 		ERROR("%s%s", DTB_PROP_HW_LOG_SIZE,
 		      " not specified in TB_FW config.\n");
+		return rc;
+	}
+
+	rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_MAX_SIZE,
+			     (uint32_t *)log_max_size);
+	if (rc != 0) {
+		ERROR("%s%s", DTB_PROP_HW_LOG_MAX_SIZE,
+		      " not specified in TB_FW config.\n");
+		return rc;
+	} else {
+		event_log_max_size = *log_max_size;
 	}
 
 	return rc;
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 62cc8bb..055ab36 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -79,7 +79,12 @@
 	 *  search if the number of entries justify the additional complexity.
 	 */
 	for (i = 0; !!arm_pm_idle_states[i]; i++) {
+#if PSCI_OS_INIT_MODE
+		if ((power_state & ~ARM_LAST_AT_PLVL_MASK) ==
+					arm_pm_idle_states[i])
+#else
 		if (power_state == arm_pm_idle_states[i])
+#endif /* __PSCI_OS_INIT_MODE__ */
 			break;
 	}
 
@@ -91,11 +96,14 @@
 	state_id = psci_get_pstate_id(power_state);
 
 	/* Parse the State ID and populate the state info parameter */
-	while (state_id) {
-		req_state->pwr_domain_state[i++] = state_id &
+	for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = state_id &
 						ARM_LOCAL_PSTATE_MASK;
 		state_id >>= ARM_LOCAL_PSTATE_WIDTH;
 	}
+#if PSCI_OS_INIT_MODE
+	req_state->last_at_pwrlvl = state_id & ARM_LOCAL_PSTATE_MASK;
+#endif /* __PSCI_OS_INIT_MODE__ */
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 6456c78..af8a02f 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019,2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,6 +34,14 @@
 
 #endif /* USE_DEBUGFS */
 
+#if ARM_ETHOSN_NPU_DRIVER
+
+	if (ethosn_smc_setup() != 0) {
+		return 1;
+	}
+
+#endif /* ARM_ETHOSN_NPU_DRIVER */
+
 	return 0;
 }
 
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 6c32331..743cc90 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -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
  */
@@ -68,6 +68,9 @@
 	[TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG},
 	[NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG},
 	[RMM_IMAGE_ID] = {UUID_REALM_MONITOR_MGMT_FIRMWARE},
+#if ARM_ETHOSN_NPU_TZMP1
+	[ARM_ETHOSN_NPU_FW_IMAGE_ID] = {UUID_ETHOSN_FW},
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
@@ -88,6 +91,10 @@
 	[SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
 	[PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT},
 #endif
+#if ARM_ETHOSN_NPU_TZMP1
+	[ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = {UUID_ETHOSN_FW_KEY_CERTIFICATE},
+	[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = {UUID_ETHOSN_FW_CONTENT_CERTIFICATE},
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
 };
@@ -191,6 +198,13 @@
 		(uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID],
 		open_fip
 	},
+#if ARM_ETHOSN_NPU_TZMP1
+	[ARM_ETHOSN_NPU_FW_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_IMAGE_ID],
+		open_fip
+	},
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {
@@ -271,18 +285,56 @@
 		open_fip
 	},
 #endif
+#if ARM_ETHOSN_NPU_TZMP1
+	[ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_KEY_CERT_ID],
+		open_fip
+	},
+	[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID],
+		open_fip
+	},
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
 #ifdef IMAGE_BL2
 
-#if TRUSTED_BOARD_BOOT
-#define FCONF_ARM_IO_UUID_NUMBER	U(24)
+#define FCONF_ARM_IO_UUID_NUM_BASE	U(10)
+
+#if ARM_ETHOSN_NPU_TZMP1
+#define FCONF_ARM_IO_UUID_NUM_NPU	U(1)
 #else
-#define FCONF_ARM_IO_UUID_NUMBER	U(10)
+#define FCONF_ARM_IO_UUID_NUM_NPU	U(0)
 #endif
 
+#if TRUSTED_BOARD_BOOT
+#define FCONF_ARM_IO_UUID_NUM_TBB	U(12)
+#else
+#define FCONF_ARM_IO_UUID_NUM_TBB	U(0)
+#endif /* TRUSTED_BOARD_BOOT */
+
+#if TRUSTED_BOARD_BOOT && defined(SPD_spmd)
+#define FCONF_ARM_IO_UUID_NUM_SPD	U(2)
+#else
+#define FCONF_ARM_IO_UUID_NUM_SPD	U(0)
+#endif /* TRUSTED_BOARD_BOOT && defined(SPD_spmd) */
+
+#if TRUSTED_BOARD_BOOT && ARM_ETHOSN_NPU_TZMP1
+#define FCONF_ARM_IO_UUID_NUM_NPU_TBB	U(2)
+#else
+#define FCONF_ARM_IO_UUID_NUM_NPU_TBB	U(0)
+#endif /* TRUSTED_BOARD_BOOT && ARM_ETHOSN_NPU_TZMP1 */
+
+#define FCONF_ARM_IO_UUID_NUMBER	FCONF_ARM_IO_UUID_NUM_BASE + \
+					FCONF_ARM_IO_UUID_NUM_NPU + \
+					FCONF_ARM_IO_UUID_NUM_TBB + \
+					FCONF_ARM_IO_UUID_NUM_SPD + \
+					FCONF_ARM_IO_UUID_NUM_NPU_TBB
+
 static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER];
 static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids);
 
@@ -303,6 +355,9 @@
 	{SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
 	{TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
 	{NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
+#if ARM_ETHOSN_NPU_TZMP1
+	{ARM_ETHOSN_NPU_FW_IMAGE_ID, "arm_ethosn_npu_fw_uuid"},
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
 #if TRUSTED_BOARD_BOOT
 	{CCA_CONTENT_CERT_ID, "cca_cert_uuid"},
 	{CORE_SWD_KEY_CERT_ID, "core_swd_cert_uuid"},
@@ -320,6 +375,10 @@
 	{SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"},
 	{PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"},
 #endif
+#if ARM_ETHOSN_NPU_TZMP1
+	{ARM_ETHOSN_NPU_FW_KEY_CERT_ID, "arm_ethosn_npu_fw_key_cert_uuid"},
+	{ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID, "arm_ethosn_npu_fw_content_cert_uuid"},
+#endif /* ARM_ETHOSN_NPU_TZMP1 */
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 251471e..7394e42 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,38 @@
 	uint32_t stream_id;
 };
 
+static int fdt_node_read_reserved_memory_addr(const void *fdt,
+					      int dev_node,
+					      uint64_t *reserved_mem_addrs)
+{
+	uintptr_t addr;
+	uint32_t phandle;
+	int err;
+	int mem_node;
+
+	err = fdt_read_uint32(fdt, dev_node, "memory-region", &phandle);
+	if (err != 0) {
+		ERROR("FCONF: Failed to get reserved memory phandle\n");
+		return err;
+	}
+
+	mem_node = fdt_node_offset_by_phandle(fdt, phandle);
+	if (mem_node < 0) {
+		ERROR("FCONF: Failed to find reserved memory node from phandle\n");
+		return mem_node;
+	}
+
+	err = fdt_get_reg_props_by_index(fdt, mem_node, 0U, &addr, NULL);
+	if (err != 0) {
+		ERROR("FCONF: Failed to read reserved memory address\n");
+		return err;
+	}
+
+	*reserved_mem_addrs = addr;
+
+	return 0;
+}
+
 static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node)
 {
 	return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL;
@@ -233,8 +265,10 @@
 		struct ethosn_device_t *dev = &ethosn_config.devices[dev_count];
 		uint32_t dev_asset_alloc_count = 0U;
 		uint32_t dev_core_count = 0U;
+		uint64_t reserved_memory_addr = 0U;
 		bool has_reserved_memory;
 		int sub_node;
+		int err;
 
 		if (!fdt_node_is_enabled(hw_conf_dtb, ethosn_node)) {
 			continue;
@@ -246,8 +280,16 @@
 		}
 
 		has_reserved_memory = fdt_node_has_reserved_memory(hw_conf_dtb, ethosn_node);
+		if (has_reserved_memory) {
+			err = fdt_node_read_reserved_memory_addr(hw_conf_dtb,
+								 ethosn_node,
+								 &reserved_memory_addr);
+			if (err != 0) {
+				return err;
+			}
+		}
+
 		fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
-			int err;
 
 			if (!fdt_node_is_enabled(hw_conf_dtb, sub_node)) {
 				/* Ignore disabled sub node */
@@ -323,6 +365,7 @@
 		dev->num_cores = dev_core_count;
 		dev->num_allocators = dev_asset_alloc_count;
 		dev->has_reserved_memory = has_reserved_memory;
+		dev->reserved_memory_addr = reserved_memory_addr;
 		++dev_count;
 	}
 
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index a4da8c3..df3488b 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -62,7 +62,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the MMU
+ * moment this is only initializes the MMU
  ******************************************************************************/
 void tsp_plat_arch_setup(void)
 {
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index c1fadc6..b9c785f 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -204,9 +204,13 @@
 					SOC_CSS_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#if RAS_FFH_SUPPORT
 #define PLAT_SP_PRI				PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI				0x10
+#endif
 
-#if SPM_MM && RAS_EXTENSION
+#if SPM_MM && RAS_FFH_SUPPORT
 /*
  * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
  * memory shared between EL3 and S-EL0.
@@ -235,7 +239,7 @@
  */
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#endif /* SPM_MM && RAS_EXTENSION */
+#endif /* SPM_MM && RAS_FFH_SUPPORT */
 
 /* Platform ID address */
 #define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/css/sgi/include/sgi_ras.h
index e69a684..24bbfa7 100644
--- a/plat/arm/css/sgi/include/sgi_ras.h
+++ b/plat/arm/css/sgi/include/sgi_ras.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,15 +7,57 @@
 #ifndef SGI_RAS_H
 #define SGI_RAS_H
 
+#include <lib/extensions/ras.h>
+#include <plat/common/platform.h>
+
+/*
+ * Interrupt type supported.
+ * - SGI_RAS_INTR_TYPE_SPI: Denotes a SPI interrupt
+ * - SGI_RAS_INTR_TYPE_PPI: Denotes a PPI interrupt
+ */
+#define SGI_RAS_INTR_TYPE_SPI 0
+#define SGI_RAS_INTR_TYPE_PPI 1
+
 /*
- * Mapping the RAS interrupt with SDEI event number and the event
- * id used with Standalone MM code
+ * MM Communicate information structure. Required to generate MM Communicate
+ * payload to be shared with Standalone MM.
  */
+typedef struct mm_communicate_header {
+	struct efi_guid	header_guid;
+	size_t		message_len;
+	uint8_t		data[1];
+} mm_communicate_header_t;
+
+/* RAS error info data structure. */
 struct sgi_ras_ev_map {
 	int sdei_ev_num;	/* SDEI Event number */
 	int intr;		/* Physical intr number */
+	int intr_type;          /* Interrupt Type (SPI or PPI)*/
+};
+
+/* RAS config data structure. Must be defined by each platform. */
+struct plat_sgi_ras_config {
+	struct sgi_ras_ev_map *ev_map;
+	int ev_map_size;
 };
 
-int sgi_ras_intr_handler_setup(void);
+/*
+ * Find event map for a given interrupt number. On success, returns pointer
+ * to the event map. On error, returns NULL.
+ */
+struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num);
+
+/*
+ * Initialization function for the framework.
+ *
+ * Registers RAS config provided by the platform and then configures and
+ * enables interrupt for each registered error. On success, return 0.
+ */
+int sgi_ras_platform_setup(struct plat_sgi_ras_config *config);
+
+/* Base element RAM RAS interrupt handler function. */
+int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data);
 
 #endif /* SGI_RAS_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
index acf31eb..d659ae5 100644
--- a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
@@ -58,6 +58,11 @@
 #define END_KEY_BASE			(SOC_KEYS_BASE + 0x0044)
 #define END_KEY_SIZE			U(32)
 
+/* Base Element RAM error definitions */
+#define SOC_NS_RAM_ERR_REC_BASE		UL(0x2A4C0000)
+#define NS_RAM_ECC_CE_INT		U(87)
+#define NS_RAM_ECC_UE_INT		U(88)
+
 #define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
 						SOC_PLATFORM_PERIPH_BASE, 	\
 						SOC_PLATFORM_PERIPH_SIZE, 	\
diff --git a/plat/arm/css/sgi/ras/sgi_ras_common.c b/plat/arm/css/sgi/ras/sgi_ras_common.c
new file mode 100644
index 0000000..9789670
--- /dev/null
+++ b/plat/arm/css/sgi/ras/sgi_ras_common.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <bl31/interrupt_mgmt.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <sgi_ras.h>
+
+static struct plat_sgi_ras_config *sgi_ras_config;
+
+/*
+ * Find event map for a given interrupt number. On success, returns pointer to
+ * the event map. On error, returns NULL.
+ */
+struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
+{
+	struct sgi_ras_ev_map *map;
+	int size;
+	int i;
+
+	if (sgi_ras_config == NULL) {
+		ERROR("RAS config is NULL\n");
+		return NULL;
+	}
+
+	map = sgi_ras_config->ev_map;
+	size = sgi_ras_config->ev_map_size;
+
+	for (i = 0; i < size; i++) {
+		if (map->intr == intr_num)
+			return map;
+
+		map++;
+	}
+
+	return NULL;
+}
+
+/*
+ * Programs GIC registers and configures interrupt ID's as Group0 EL3
+ * interrupts. Current support is to register PPI and SPI interrupts.
+ */
+static void sgi_ras_intr_configure(int intr, int intr_type)
+{
+	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
+	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
+	plat_ic_clear_interrupt_pending(intr);
+
+	/* Routing mode option available only for SPI interrupts */
+	if (intr_type == SGI_RAS_INTR_TYPE_SPI) {
+		plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
+					(u_register_t)read_mpidr_el1());
+	}
+	plat_ic_enable_interrupt(intr);
+}
+
+/*
+ * Initialization function for the framework.
+ *
+ * Registers RAS config provided by the platform and then configures and
+ * enables interrupt for each registered error. On success, return 0.
+ */
+int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
+{
+	struct sgi_ras_ev_map *map;
+	int size;
+	int i;
+
+	/* Check if parameter is valid. */
+	if (config == NULL) {
+		ERROR("SGI: Failed to register RAS config\n");
+		return -1;
+	}
+
+	/*
+	 * Maintain a reference to the platform RAS config data for later
+	 * use.
+	 */
+	sgi_ras_config = config;
+
+	map = sgi_ras_config->ev_map;
+	size = sgi_ras_config->ev_map_size;
+
+	for (i = 0; i < size; i++) {
+		sgi_ras_intr_configure(map->intr, map->intr_type);
+		map++;
+	}
+
+	INFO("SGI: Platform RAS setup successful\n");
+
+	return 0;
+}
diff --git a/plat/arm/css/sgi/ras/sgi_ras_sram.c b/plat/arm/css/sgi/ras/sgi_ras_sram.c
new file mode 100644
index 0000000..b100700
--- /dev/null
+++ b/plat/arm/css/sgi/ras/sgi_ras_sram.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <plat/common/platform.h>
+#include <services/sdei.h>
+#include <services/spm_mm_svc.h>
+
+#include <platform_def.h>
+#include <sgi_ras.h>
+
+/* Base Element RAM Error Record offsets. */
+#define ERRSTATUS	U(0)
+#define ERRCODE		U(8)
+#define ERRADDR		U(12)
+
+/*
+ * Base Element RAM error information data structure communicated as part of MM
+ * Communication data payload.
+ */
+typedef struct sgi_sram_err_info {
+	uint32_t err_status;
+	uint32_t err_code;
+	uint32_t err_addr;
+} sgi_sram_err_info_t;
+
+/*
+ * MM Communicate message header GUID to indicate the payload is intended for
+ * base element RAM MM driver.
+ */
+struct efi_guid sram_ecc_event_guid = {
+	0x7312db4f, 0xd0c4, 0x4fb5,
+	{ 0x81, 0x2c, 0xb7, 0x4b, 0xc6, 0xc4, 0xa9, 0x38 }
+};
+
+/* Base element RAM RAS error interrupt handler */
+int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data)
+{
+	struct sgi_ras_ev_map *ras_map;
+	mm_communicate_header_t *header;
+	sgi_sram_err_info_t sram_info;
+	uintptr_t base_addr;
+	uint32_t clear_status, intr;
+	int ret;
+
+	cm_el1_sysregs_context_save(NON_SECURE);
+	intr = data->interrupt;
+
+	INFO("SGI: Base element RAM interrupt [%d] handler\n", intr);
+
+	/* Determine error record base address to read. */
+	base_addr = 0;
+	if (intr == NS_RAM_ECC_CE_INT || intr == NS_RAM_ECC_UE_INT) {
+		base_addr = SOC_NS_RAM_ERR_REC_BASE;
+	}
+	sram_info.err_status = mmio_read_32(base_addr + ERRSTATUS);
+	sram_info.err_code = mmio_read_32(base_addr + ERRCODE);
+	sram_info.err_addr = mmio_read_32(base_addr + ERRADDR);
+
+	/* Clear the interrupt. */
+	clear_status = mmio_read_32(base_addr + ERRSTATUS);
+	mmio_write_32((base_addr + ERRSTATUS), clear_status);
+
+	/*
+	 * Prepare the MM Communication buffer to pass the base element RAM
+	 * error information to Secure Partition.
+	 */
+	header = (void *)PLAT_SPM_BUF_BASE;
+	memset(header, 0, sizeof(*header));
+	memcpy(&header->data, &sram_info, sizeof(sram_info));
+	header->message_len = sizeof(sram_info);
+	memcpy(&header->header_guid, (void *)&sram_ecc_event_guid,
+		sizeof(struct efi_guid));
+
+	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+			plat_my_core_pos());
+
+	plat_ic_end_of_interrupt(intr);
+
+	/*
+	 * Find if this is a RAS interrupt. There must be an event against
+	 * this interrupt
+	 */
+	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	if (ras_map == NULL) {
+		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+			intr);
+		return -1;
+	}
+
+	/* Dispatch the event to the SDEI client */
+	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+	if (ret != 0) {
+		/*
+		 * sdei_dispatch_event() may return failing result in some
+		 * cases, for example kernel may not have registered a handler
+		 * or RAS event may happen early during boot. We restore the NS
+		 * context when sdei_dispatch_event() returns failing result.
+		 */
+		ERROR("SDEI dispatch failed: %d", ret);
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+	}
+
+	return ret;
+}
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 282a5f0..358316c 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -8,7 +8,9 @@
 
 CSS_ENT_BASE			:=	plat/arm/css/sgi
 
-RAS_EXTENSION			:=	0
+ENABLE_FEAT_RAS			:=	1
+
+RAS_FFH_SUPPORT			:=	0
 
 SDEI_SUPPORT			:=	0
 
@@ -52,10 +54,6 @@
 				${CSS_ENT_BASE}/sgi_bl31_setup.c	\
 				${CSS_ENT_BASE}/sgi_topology.c
 
-ifeq (${RAS_EXTENSION},1)
-BL31_SOURCES		+=	${CSS_ENT_BASE}/sgi_ras.c
-endif
-
 ifneq (${RESET_TO_BL31},0)
   $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
   Please set RESET_TO_BL31 to 0.")
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index df2ce38..7aa7b34 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -106,10 +106,6 @@
 {
 	arm_bl31_platform_setup();
 
-#if RAS_EXTENSION
-	sgi_ras_intr_handler_setup();
-#endif
-
 	/* Configure the warm reboot SGI for primary core */
 	css_setup_cpu_pwr_down_intr();
 
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index b8ba49f..7f79d54 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -93,7 +93,7 @@
 	PLAT_ARM_SECURE_MAP_DEVICE,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	CSS_SGI_SP_CPER_BUF_MMAP,
 #endif
 	ARM_SP_IMAGE_RW_MMAP,
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 8d38108..8de0efe 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -87,6 +87,9 @@
 	SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
+#if RAS_FFH_SUPPORT
+	CSS_SGI_SP_CPER_BUF_MMAP,
+#endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
 	{0}
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
deleted file mode 100644
index 4f03ac4..0000000
--- a/plat/arm/css/sgi/sgi_ras.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <bl31/interrupt_mgmt.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/extensions/ras.h>
-#include <plat/arm/common/arm_spm_def.h>
-#include <plat/common/platform.h>
-#include <services/sdei.h>
-#include <services/spm_mm_svc.h>
-
-#include <sgi_ras.h>
-
-static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
-				int probe_data,
-				const struct err_handler_data *const data);
-typedef struct mm_communicate_header {
-	struct efi_guid	header_guid;
-	size_t		message_len;
-	uint8_t		data[8];
-} mm_communicate_header_t;
-
-/*
- * GUID to indicate that the MM communication message is intended for DMC-620
- * MM driver.
- */
-const struct efi_guid dmc620_ecc_event_guid = {
-	0x5ef0afd5, 0xe01a, 0x4c30,
-	{0x86, 0x19, 0x45, 0x46, 0x26, 0x91, 0x80, 0x98}
-};
-
-struct sgi_ras_ev_map sgi575_ras_map[] = {
-
-	/* DMC 0 error ECC error interrupt*/
-	{SGI_SDEI_DS_EVENT_0, 35},
-
-	/* DMC 1 error ECC error interrupt*/
-	{SGI_SDEI_DS_EVENT_1, 39},
-};
-
-#define SGI575_RAS_MAP_SIZE	ARRAY_SIZE(sgi575_ras_map)
-
-struct err_record_info sgi_err_records[] = {
-	{
-		/* DMC 0 error record info */
-		.handler = &sgi_ras_intr_handler,
-		.aux_data = (void *)0,
-	}, {
-		/* DMC 1 error record info */
-		.handler = &sgi_ras_intr_handler,
-		.aux_data = (void *)1,
-	},
-};
-
-struct ras_interrupt sgi_ras_interrupts[] = {
-	{
-		.intr_number = 35,
-		.err_record = &sgi_err_records[0],
-	}, {
-		.intr_number = 39,
-		.err_record = &sgi_err_records[1],
-	}
-};
-
-REGISTER_ERR_RECORD_INFO(sgi_err_records);
-REGISTER_RAS_INTERRUPTS(sgi_ras_interrupts);
-
-static struct sgi_ras_ev_map *plat_sgi_get_ras_ev_map(void)
-{
-	return sgi575_ras_map;
-}
-
-static int plat_sgi_get_ras_ev_map_size(void)
-{
-	return SGI575_RAS_MAP_SIZE;
-}
-
-/*
- * Find event mapping for a given interrupt number: On success, returns pointer
- * to the event mapping. On error, returns NULL.
- */
-static struct sgi_ras_ev_map *find_ras_event_map_by_intr(uint32_t intr_num)
-{
-	struct sgi_ras_ev_map *map = plat_sgi_get_ras_ev_map();
-	int i;
-	int size = plat_sgi_get_ras_ev_map_size();
-
-	for (i = 0; i < size; i++) {
-		if (map->intr == intr_num)
-			return map;
-
-		map++;
-	}
-
-	return NULL;
-}
-
-static void sgi_ras_intr_configure(int intr)
-{
-	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
-	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
-	plat_ic_clear_interrupt_pending(intr);
-	plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
-				(u_register_t)read_mpidr_el1());
-	plat_ic_enable_interrupt(intr);
-}
-
-static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
-				int probe_data,
-				const struct err_handler_data *const data)
-{
-	struct sgi_ras_ev_map *ras_map;
-	mm_communicate_header_t *header;
-	uint32_t intr;
-	int ret;
-
-	cm_el1_sysregs_context_save(NON_SECURE);
-	intr = data->interrupt;
-
-	/*
-	 * Find if this is a RAS interrupt. There must be an event against
-	 * this interrupt
-	 */
-	ras_map = find_ras_event_map_by_intr(intr);
-	assert(ras_map != NULL);
-
-	/*
-	 * Populate the MM_COMMUNICATE payload to share the
-	 * event info with StandaloneMM code. This allows us to use
-	 * MM_COMMUNICATE as a common entry mechanism into S-EL0. The
-	 * header data will be parsed in StandaloneMM to process the
-	 * corresponding event.
-	 *
-	 * TBD - Currently, the buffer allocated by SPM for communication
-	 * between EL3 and S-EL0 is being used(PLAT_SPM_BUF_BASE). But this
-	 * should happen via a dynamic mem allocation, which should be
-	 * managed by SPM -- the individual platforms then call the mem
-	 * alloc api to get memory for the payload.
-	 */
-	header = (void *) PLAT_SPM_BUF_BASE;
-	memset(header, 0, sizeof(*header));
-	memcpy(&header->data, &err_rec->aux_data, sizeof(err_rec->aux_data));
-	header->message_len = sizeof(err_rec->aux_data);
-	memcpy(&header->header_guid, (void *) &dmc620_ecc_event_guid,
-			sizeof(const struct efi_guid));
-
-	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
-		       plat_my_core_pos());
-
-	/*
-	 * Do an EOI of the RAS interrupt. This allows the
-	 * sdei event to be dispatched at the SDEI event's
-	 * priority.
-	 */
-	plat_ic_end_of_interrupt(intr);
-
-	/* Dispatch the event to the SDEI client */
-	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
-	if (ret != 0) {
-		/*
-		 * sdei_dispatch_event() may return failing result in some cases,
-		 * for example kernel may not have registered a handler or RAS event
-		 * may happen early during boot. We restore the NS context when
-		 * sdei_dispatch_event() returns failing result.
-		 */
-		ERROR("SDEI dispatch failed: %d", ret);
-		cm_el1_sysregs_context_restore(NON_SECURE);
-		cm_set_next_eret_context(NON_SECURE);
-	}
-
-	return ret;
-}
-
-int sgi_ras_intr_handler_setup(void)
-{
-	int i;
-	struct sgi_ras_ev_map *map = plat_sgi_get_ras_ev_map();
-	int size = plat_sgi_get_ras_ev_map_size();
-
-	for (i = 0; i < size; i++) {
-		sgi_ras_intr_configure(map->intr);
-		map++;
-	}
-
-	INFO("SGI: RAS Interrupt Handler successfully registered\n");
-
-	return 0;
-}
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/brcm/board/stingray/driver/swreg.c b/plat/brcm/board/stingray/driver/swreg.c
index 2b7c53b..a5b5b9f 100644
--- a/plat/brcm/board/stingray/driver/swreg.c
+++ b/plat/brcm/board/stingray/driver/swreg.c
@@ -296,7 +296,7 @@
 	return ret;
 }
 
-/* Update SWREG firmware for all power doman for A2 chip */
+/* Update SWREG firmware for all power domain for A2 chip */
 int swreg_firmware_update(void)
 {
 	enum sw_reg reg_id;
diff --git a/plat/brcm/board/stingray/include/scp_cmd.h b/plat/brcm/board/stingray/include/scp_cmd.h
index 806ef56..a7ab0e5 100644
--- a/plat/brcm/board/stingray/include/scp_cmd.h
+++ b/plat/brcm/board/stingray/include/scp_cmd.h
@@ -5,7 +5,7 @@
  */
 
 #ifndef SCP_CMD_H
-#define SCP_SMD_H
+#define SCP_CMD_H
 
 #include <stdint.h>
 
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 042916a..eca81b1 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -11,7 +11,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/console.h>
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 #include <lib/extensions/ras.h>
 #endif
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
@@ -81,7 +81,7 @@
 void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
 {
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	/* Call RAS EA handler */
 	int handled = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags);
 	if (handled != 0)
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
index da76884..be0fac1 100644
--- a/plat/common/aarch64/plat_ehf.c
+++ b/plat/common/aarch64/plat_ehf.c
@@ -12,7 +12,7 @@
  * Enumeration of priority levels on ARM platforms.
  */
 ehf_pri_desc_t plat_exceptions[] = {
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	/* RAS Priority */
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI),
 #endif
@@ -24,10 +24,18 @@
 	/* Normal priority SDEI */
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
+
 #if SPM_MM
+#if RAS_FFH_SUPPORT
+#if (PLAT_SP_PRI != PLAT_RAS_PRI)
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
+#endif
+#else
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
 #endif
-	/* Plaform specific exceptions description */
+#endif
+
+	/* Platform specific exceptions description */
 #ifdef PLAT_EHF_DESC
 	PLAT_EHF_DESC,
 #endif
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 50751ee..159eee9 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -245,6 +245,15 @@
 
 	return 0;
 }
+#elif defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
 #endif
 
 void bl31_plat_runtime_setup(void)
diff --git a/plat/imx/common/include/sci/sci_rpc.h b/plat/imx/common/include/sci/sci_rpc.h
index 60dbc27..b6adf33 100644
--- a/plat/imx/common/include/sci/sci_rpc.h
+++ b/plat/imx/common/include/sci/sci_rpc.h
@@ -100,7 +100,7 @@
 void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp);
 
 /*!
- * This is an internal function to dispath an RPC call that has
+ * This is an internal function to dispatch an RPC call that has
  * arrived via IPC over an MU. It is called by server-side SCFW.
  *
  * @param[in]     mu          MU message arrived on
diff --git a/plat/imx/common/include/sci/svc/pad/sci_pad_api.h b/plat/imx/common/include/sci/svc/pad/sci_pad_api.h
index dc23eed..ac93aae 100644
--- a/plat/imx/common/include/sci/svc/pad/sci_pad_api.h
+++ b/plat/imx/common/include/sci/svc/pad/sci_pad_api.h
@@ -42,7 +42,7 @@
  *
  * Pads are managed as a resource by the Resource Manager (RM).  They have
  * assigned owners and only the owners can configure the pads. Some of the
- * pads are reserved for use by the SCFW itself and this can be overriden
+ * pads are reserved for use by the SCFW itself and this can be overridden
  * with the implementation of board_config_sc(). Additionally, pads may
  * be assigned to various other partitions via the implementation of
  * board_system_config().
@@ -156,7 +156,7 @@
  * This type is used to declare a pad low-power isolation config.
  * ISO_LATE is the most common setting. ISO_EARLY is only used when
  * an output pad is directly determined by another input pad. The
- * other two are only used when SW wants to directly contol isolation.
+ * other two are only used when SW wants to directly control isolation.
  */
 typedef uint8_t sc_pad_iso_t;
 
diff --git a/plat/imx/common/include/sci/svc/pm/sci_pm_api.h b/plat/imx/common/include/sci/svc/pm/sci_pm_api.h
index 76ca5c4..1364795 100644
--- a/plat/imx/common/include/sci/svc/pm/sci_pm_api.h
+++ b/plat/imx/common/include/sci/svc/pm/sci_pm_api.h
@@ -294,7 +294,7 @@
  * Note some resources are still not accessible even when powered up if bus
  * transactions go through a fabric not powered up. Examples of this are
  * resources in display and capture subsystems which require the display
- * controller or the imaging subsytem to be powered up first.
+ * controller or the imaging subsystem to be powered up first.
  *
  * Not that resources are grouped into power domains by the underlying
  * hardware. If any resource in the domain is on, the entire power domain
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index 32a35ef..71e0af1 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -98,7 +98,7 @@
 		/* assert the pcg pcr bit of the core */
 		mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
 	} else {
-		/* disbale CORE WFI PDN & IRQ PUP */
+		/* disable CORE WFI PDN & IRQ PUP */
 		mmio_clrbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
 				COREx_IRQ_WUP(core_id));
 		/* deassert the pcg pcr bit of the core */
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
index cc1cb10..e0e38a9 100644
--- a/plat/imx/imx8m/imx8mm/gpc.c
+++ b/plat/imx/imx8m/imx8mm/gpc.c
@@ -376,7 +376,7 @@
 	/*
 	 * Set the CORE & SCU power up timing:
 	 * SW = 0x1, SW2ISO = 0x1;
-	 * the CPU CORE and SCU power up timming counter
+	 * the CPU CORE and SCU power up timing counter
 	 * is drived  by 32K OSC, each domain's power up
 	 * latency is (SW + SW2ISO) / 32768
 	 */
diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c
index 4e05297..20c9a55 100644
--- a/plat/imx/imx8m/imx8mn/gpc.c
+++ b/plat/imx/imx8m/imx8mn/gpc.c
@@ -170,7 +170,7 @@
 	/*
 	 * Set the CORE & SCU power up timing:
 	 * SW = 0x1, SW2ISO = 0x1;
-	 * the CPU CORE and SCU power up timming counter
+	 * the CPU CORE and SCU power up timing counter
 	 * is drived  by 32K OSC, each domain's power up
 	 * latency is (SW + SW2ISO) / 32768
 	 */
diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c
index 452e788..956b508 100644
--- a/plat/imx/imx8m/imx8mp/gpc.c
+++ b/plat/imx/imx8m/imx8mp/gpc.c
@@ -337,7 +337,7 @@
 	/*
 	 * Set the CORE & SCU power up timing:
 	 * SW = 0x1, SW2ISO = 0x1;
-	 * the CPU CORE and SCU power up timming counter
+	 * the CPU CORE and SCU power up timing counter
 	 * is drived  by 32K OSC, each domain's power up
 	 * latency is (SW + SW2ISO) / 32768
 	 */
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index 0a029d6..ebf92f7 100644
--- a/plat/imx/imx8m/imx8mq/gpc.c
+++ b/plat/imx/imx8m/imx8mq/gpc.c
@@ -417,7 +417,7 @@
 	/* set all mix/PU in A53 domain */
 	mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xfffd);
 
-	/* set SCU timming */
+	/* set SCU timing */
 	mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
 		      (0x59 << 10) | 0x5B | (0x2 << 20));
 
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 661f8e2..7065a65 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -30,6 +30,20 @@
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
 
+/*
+ * Avoid the pointer dereference of the canonical mmio_read_8() implementation.
+ * This prevents the compiler from mis-interpreting the MMIO access as an
+ * illegal memory access to a very low address (the IMX ROM is mapped at 0).
+ */
+static uint8_t mmio_read_8_ldrb(uintptr_t address)
+{
+	uint8_t reg;
+
+	__asm__ volatile ("ldrb %w0, [%1]" : "=r" (reg) : "r" (address));
+
+	return reg;
+}
+
 static const mmap_region_t imx_mmap[] = {
 	MAP_REGION_FLAT(GPV_BASE, GPV_SIZE, MT_DEVICE | MT_RW), /* GPV map */
 	MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM map */
@@ -70,11 +84,11 @@
 	uint32_t ocotp_val;
 
 	imx_soc_revision = mmio_read_32(IMX_ANAMIX_BASE + ANAMIX_DIGPROG);
-	rom_version = mmio_read_8(IMX_ROM_BASE + ROM_SOC_INFO_A0);
+	rom_version = mmio_read_8_ldrb(IMX_ROM_BASE + ROM_SOC_INFO_A0);
 	if (rom_version == 0x10)
 		return;
 
-	rom_version = mmio_read_8(IMX_ROM_BASE + ROM_SOC_INFO_B0);
+	rom_version = mmio_read_8_ldrb(IMX_ROM_BASE + ROM_SOC_INFO_B0);
 	if (rom_version == 0x20) {
 		imx_soc_revision &= ~0xff;
 		imx_soc_revision |= rom_version;
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 1da8d29..13e80fb 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -51,6 +51,16 @@
 #define IMX_PAD_UART_RX			SC_P_UART0_RX
 #define IMX_PAD_UART_TX			SC_P_UART0_TX
 
+#elif defined(IMX_USE_UART1)
+#define UART_PAD_CTRL	(PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \
+			(SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
+			(SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
+			(SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
+			(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
+#define IMX_RES_UART			SC_R_UART_1
+#define IMX_PAD_UART_RX			SC_P_UART1_RX
+#define IMX_PAD_UART_TX			SC_P_UART1_TX
+
 /*
  * On Toradex Colibri i.MX8QXP UART3 on the FLEXCAN2.
  * Use custom pad control for this
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index b880e1b..29f6f7c 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -41,6 +41,8 @@
 
 #if defined(IMX_USE_UART0)
 #define IMX_BOOT_UART_BASE		0x5a060000
+#elif defined(IMX_USE_UART1)
+#define IMX_BOOT_UART_BASE		0x5a070000
 #elif defined(IMX_USE_UART3)
 #define IMX_BOOT_UART_BASE		0x5a090000
 #else
diff --git a/plat/imx/imx93/aarch64/plat_helpers.S b/plat/imx/imx93/aarch64/plat_helpers.S
new file mode 100644
index 0000000..9987a53
--- /dev/null
+++ b/plat/imx/imx93/aarch64/plat_helpers.S
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_a55.h>
+
+#include <platform_def.h>
+
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_calc_core_pos
+	.globl	platform_mem_init
+
+	/* ------------------------------------------------------
+	 * Helper macro that reads the part number of the current
+	 * CPU and jumps to the given label if it matches the CPU
+	 * MIDR provided.
+	 *
+	 * Clobbers x0.
+	 * ------------------------------------------------------
+	 */
+	.macro  jump_if_cpu_midr _cpu_midr, _label
+
+	mrs	x0, midr_el1
+	ubfx	x0, x0, MIDR_PN_SHIFT, #12
+	cmp     w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.eq	\_label
+
+	.endm
+
+	/* ----------------------------------------------
+	 * unsigned int plat_is_my_cpu_primary(void);
+	 * This function checks if this is the primary CPU
+	 * ----------------------------------------------
+	 */
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
+	mov_imm x1, MPIDR_AFFINITY_MASK
+	and	x0, x0, x1
+	cmp	x0, #PLAT_PRIMARY_CPU
+	cset	x0, eq
+	ret
+endfunc plat_is_my_cpu_primary
+
+	/* ----------------------------------------------
+	 * unsigned int plat_my_core_pos(void)
+	 * This function uses the plat_calc_core_pos()
+	 * to get the index of the calling CPU.
+	 * ----------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	mov	x1, #MPIDR_AFFLVL_MASK
+	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+	ret
+endfunc plat_my_core_pos
+
+	/*
+	 * unsigned int plat_calc_core_pos(uint64_t mpidr)
+	 * helper function to calculate the core position.
+	 * With this function.
+	 */
+func plat_calc_core_pos
+	mov	x1, #MPIDR_AFFLVL_MASK
+	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+	ret
+endfunc plat_calc_core_pos
+
+func platform_mem_init
+	ret
+endfunc platform_mem_init
diff --git a/plat/imx/imx93/imx93_bl31_setup.c b/plat/imx/imx93/imx93_bl31_setup.c
new file mode 100644
index 0000000..8458f6c
--- /dev/null
+++ b/plat/imx/imx93/imx93_bl31_setup.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/nxp/trdc/imx_trdc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <imx8_lpuart.h>
+#include <plat_imx8.h>
+#include <platform_def.h>
+
+#define MAP_BL31_TOTAL										   \
+	MAP_REGION_FLAT(BL31_BASE, BL31_LIMIT - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO										   \
+	MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+
+static const mmap_region_t imx_mmap[] = {
+	AIPS1_MAP, AIPS2_MAP, AIPS4_MAP, GIC_MAP,
+	TRDC_A_MAP, TRDC_W_MAP, TRDC_M_MAP,
+	TRDC_N_MAP,
+	{0},
+};
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* get SPSR for BL33 entry */
+static uint32_t get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned long mode;
+	uint32_t spsr;
+
+	/* figure out what mode we enter the non-secure world */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+		u_register_t arg2, u_register_t arg3)
+{
+	static console_t console;
+
+	console_lpuart_register(IMX_LPUART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+		     IMX_CONSOLE_BAUDRATE, &console);
+
+	/* This console is only used for boot stage */
+	console_set_scope(&console, CONSOLE_FLAG_BOOT);
+
+	/*
+	 * tell BL3-1 where the non-secure software image is located
+	 * and the entry state information.
+	 */
+	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#if defined(SPD_opteed)
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = 0;
+
+	/* Pass TEE base and size to bl33 */
+	bl33_image_ep_info.args.arg1 = BL32_BASE;
+	bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+	/* Make sure memory is clean */
+	mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+	bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
+}
+
+void bl31_plat_arch_setup(void)
+{
+	/* no coherence memory support on i.MX9 */
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
+	};
+
+	/* Assign all the GPIO pins to non-secure world by default */
+	mmio_write_32(GPIO2_BASE + 0x10, 0xffffffff);
+	mmio_write_32(GPIO2_BASE + 0x14, 0x3);
+	mmio_write_32(GPIO2_BASE + 0x18, 0xffffffff);
+	mmio_write_32(GPIO2_BASE + 0x1c, 0x3);
+
+	mmio_write_32(GPIO3_BASE + 0x10, 0xffffffff);
+	mmio_write_32(GPIO3_BASE + 0x14, 0x3);
+	mmio_write_32(GPIO3_BASE + 0x18, 0xffffffff);
+	mmio_write_32(GPIO3_BASE + 0x1c, 0x3);
+
+	mmio_write_32(GPIO4_BASE + 0x10, 0xffffffff);
+	mmio_write_32(GPIO4_BASE + 0x14, 0x3);
+	mmio_write_32(GPIO4_BASE + 0x18, 0xffffffff);
+	mmio_write_32(GPIO4_BASE + 0x1c, 0x3);
+
+	mmio_write_32(GPIO1_BASE + 0x10, 0xffffffff);
+	mmio_write_32(GPIO1_BASE + 0x14, 0x3);
+	mmio_write_32(GPIO1_BASE + 0x18, 0xffffffff);
+	mmio_write_32(GPIO1_BASE + 0x1c, 0x3);
+
+	setup_page_tables(bl_regions, imx_mmap);
+	enable_mmu_el3(0);
+
+	/* trdc must be initialized */
+	trdc_config();
+}
+
+void bl31_platform_setup(void)
+{
+	generic_delay_timer_init();
+
+	plat_gic_driver_init();
+	plat_gic_init();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	}
+
+	if (type == SECURE) {
+		return &bl32_image_ep_info;
+	}
+
+	return NULL;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return COUNTER_FREQUENCY;
+}
diff --git a/plat/imx/imx93/imx93_psci.c b/plat/imx/imx93/imx93_psci.c
new file mode 100644
index 0000000..5e1fa95
--- /dev/null
+++ b/plat/imx/imx93/imx93_psci.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <plat_imx8.h>
+#include <pwr_ctrl.h>
+
+#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
+#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
+
+/* platform secure warm boot entry */
+static uintptr_t secure_entrypoint;
+
+static bool boot_stage = true;
+
+int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
+{
+	/* The non-secure entrypoint should be in RAM space */
+	if (ns_entrypoint < PLAT_NS_IMAGE_OFFSET) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int imx_validate_power_state(unsigned int power_state,
+			 psci_power_state_t *req_state)
+{
+	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	int pwr_type = psci_get_pstate_type(power_state);
+	int state_id = psci_get_pstate_id(power_state);
+
+	if (pwr_lvl > PLAT_MAX_PWR_LVL) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (pwr_type == PSTATE_TYPE_STANDBY) {
+		CORE_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+		CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+	}
+
+	if (pwr_type == PSTATE_TYPE_POWERDOWN && state_id == 0x33) {
+		CORE_PWR_STATE(req_state) = PLAT_MAX_OFF_STATE;
+		CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+void imx_set_cpu_boot_entry(unsigned int core_id, uint64_t boot_entry)
+{
+	/* set the cpu core reset entry: BLK_CTRL_S */
+	mmio_write_32(BLK_CTRL_S_BASE + CA55_RVBADDR0_L + core_id * 8, boot_entry >> 2);
+}
+
+int imx_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned int core_id;
+
+	core_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	imx_set_cpu_boot_entry(core_id, secure_entrypoint);
+
+	/*
+	 * When the core is first time boot up, the core is already ON after SoC POR,
+	 * So 'SW_WAKEUP' can not work, so need to toggle core's reset then release
+	 * the core from cpu_wait.
+	 */
+	if (boot_stage) {
+		/* assert CPU core SW reset */
+		mmio_clrbits_32(SRC_SLICE(SRC_A55C0 + core_id) + 0x24, BIT(2) | BIT(0));
+		/* deassert CPU core SW reset */
+		mmio_setbits_32(SRC_SLICE(SRC_A55C0 + core_id) + 0x24, BIT(2) | BIT(0));
+		/* release the cpuwait to kick the cpu */
+		mmio_clrbits_32(BLK_CTRL_S_BASE + CA55_CPUWAIT, BIT(core_id));
+	} else {
+		/* assert the CMC MISC SW WAKEUP BIT to kick the offline core */
+		gpc_assert_sw_wakeup(CPU_A55C0 + core_id);
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	plat_gic_pcpu_init();
+	plat_gic_cpuif_enable();
+
+	/* below config is ok both for boot & hotplug */
+	/* clear the CPU power mode */
+	gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_RUN);
+	/* clear the SW wakeup */
+	gpc_deassert_sw_wakeup(CPU_A55C0 + core_id);
+	/* switch to GIC wakeup source */
+	gpc_select_wakeup_gic(CPU_A55C0 + core_id);
+
+	if (boot_stage) {
+		/* SRC config */
+		/* config the MEM LPM */
+		src_mem_lpm_en(SRC_A55P0_MEM + core_id, MEM_OFF);
+		/* LPM config to only ON in run mode to its domain */
+		src_mix_set_lpm(SRC_A55C0 + core_id, core_id, CM_MODE_WAIT);
+		/* white list config, only enable its own domain */
+		src_authen_config(SRC_A55C0 + core_id, 1 << core_id, 0x1);
+
+		boot_stage = false;
+	}
+}
+
+void imx_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
+	unsigned int i;
+
+	plat_gic_cpuif_disable();
+	write_clusterpwrdn(DSU_CLUSTER_PWR_OFF);
+
+	/*
+	 * mask all the GPC IRQ wakeup to make sure no IRQ can wakeup this core
+	 * as we need to use SW_WAKEUP for hotplug purpose
+	 */
+	for (i = 0U; i < IMR_NUM; i++) {
+		gpc_set_irq_mask(CPU_A55C0 + core_id, i, 0xffffffff);
+	}
+	/* switch to GPC wakeup source */
+	gpc_select_wakeup_raw_irq(CPU_A55C0 + core_id);
+	/* config the target mode to suspend */
+	gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_SUSPEND);
+}
+
+void imx_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	/* do cpu level config */
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		plat_gic_cpuif_disable();
+		imx_set_cpu_boot_entry(core_id, secure_entrypoint);
+		/* config the target mode to WAIT */
+		gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_WAIT);
+	}
+
+	/* do cluster level config */
+	if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
+		/* config the A55 cluster target mode to WAIT */
+		gpc_set_cpu_mode(CPU_A55_PLAT, CM_MODE_WAIT);
+
+		/* config DSU for cluster power down with L3 MEM RET */
+		if (is_local_state_retn(CLUSTER_PWR_STATE(target_state))) {
+			write_clusterpwrdn(DSU_CLUSTER_PWR_OFF | BIT(1));
+		}
+	}
+}
+
+void imx_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	/* cluster level */
+	if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
+		/* set the cluster's target mode to RUN */
+		gpc_set_cpu_mode(CPU_A55_PLAT, CM_MODE_RUN);
+	}
+
+	/* do core level */
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		/* set A55 CORE's power mode to RUN */
+		gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_RUN);
+		plat_gic_cpuif_enable();
+	}
+}
+
+void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+
+	for (i = IMX_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+	}
+
+	SYSTEM_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+	CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+}
+
+void __dead2 imx_system_reset(void)
+{
+	mmio_write_32(WDOG3_BASE + WDOG_CNT, 0xd928c520);
+	while ((mmio_read_32(WDOG3_BASE + WDOG_CS) & WDOG_CS_ULK) == 0U) {
+		;
+	}
+
+	mmio_write_32(WDOG3_BASE + WDOG_TOVAL, 0x10);
+	mmio_write_32(WDOG3_BASE + WDOG_CS, 0x21e3);
+
+	while (1) {
+		wfi();
+	}
+}
+
+void __dead2 imx_system_off(void)
+{
+	mmio_setbits_32(BBNSM_BASE + BBNSM_CTRL, BBNSM_DP_EN | BBNSM_TOSP);
+
+	while (1) {
+		wfi();
+	}
+}
+
+static const plat_psci_ops_t imx_plat_psci_ops = {
+	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
+	.validate_power_state = imx_validate_power_state,
+	.pwr_domain_on = imx_pwr_domain_on,
+	.pwr_domain_off = imx_pwr_domain_off,
+	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
+	.pwr_domain_suspend = imx_pwr_domain_suspend,
+	.pwr_domain_suspend_finish = imx_pwr_domain_suspend_finish,
+	.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+	.system_reset = imx_system_reset,
+	.system_off = imx_system_off,
+};
+
+/* export the platform specific psci ops */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	/* sec_entrypoint is used for warm reset */
+	secure_entrypoint = sec_entrypoint;
+	imx_set_cpu_boot_entry(0, sec_entrypoint);
+
+	pwr_sys_init();
+
+	*psci_ops = &imx_plat_psci_ops;
+
+	return 0;
+}
diff --git a/plat/imx/imx93/include/platform_def.h b/plat/imx/imx93/include/platform_def.h
new file mode 100644
index 0000000..7efbf1c
--- /dev/null
+++ b/plat/imx/imx93/include/platform_def.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define PLATFORM_STACK_SIZE		0xB00
+#define CACHE_WRITEBACK_GRANULE		64
+
+#define PLAT_PRIMARY_CPU		U(0x0)
+#define PLATFORM_MAX_CPU_PER_CLUSTER	U(2)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	U(2)
+#define PLATFORM_CORE_COUNT		U(2)
+
+#define IMX_PWR_LVL0			MPIDR_AFFLVL0
+
+#define PWR_DOMAIN_AT_MAX_LVL		U(1)
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_OFF_STATE		U(4)
+#define PLAT_MAX_RET_STATE		U(2)
+
+#define BL31_BASE			U(0x204E0000)
+#define BL31_LIMIT			U(0x20520000)
+
+/* non-secure uboot base */
+/* TODO */
+#define PLAT_NS_IMAGE_OFFSET		U(0x80200000)
+#define BL32_FDT_OVERLAY_ADDR           (PLAT_NS_IMAGE_OFFSET + 0x3000000)
+
+/* GICv4 base address */
+#define PLAT_GICD_BASE			U(0x48000000)
+#define PLAT_GICR_BASE			U(0x48040000)
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
+
+#define MAX_XLAT_TABLES			8
+#define MAX_MMAP_REGIONS		16
+
+#define IMX_LPUART_BASE			U(0x44380000)
+#define IMX_BOOT_UART_CLK_IN_HZ		U(24000000) /* Select 24MHz oscillator */
+#define IMX_CONSOLE_BAUDRATE		115200
+
+#define AIPSx_SIZE			U(0x800000)
+#define AIPS1_BASE			U(0x44000000)
+#define AIPS2_BASE			U(0x42000000)
+#define AIPS3_BASE			U(0x42800000)
+#define AIPS4_BASE			U(0x49000000)
+#define GPIO1_BASE			U(0x47400000)
+#define GPIO2_BASE			U(0x43810000)
+#define GPIO3_BASE			U(0x43820000)
+#define GPIO4_BASE			U(0x43830000)
+
+#define TRDC_A_BASE			U(0x44270000)
+#define TRDC_W_BASE			U(0x42460000)
+#define TRDC_M_BASE			U(0x42810000)
+#define TRDC_N_BASE			U(0x49010000)
+#define TRDC_x_SISE			U(0x20000)
+
+#define WDOG3_BASE			U(0x42490000)
+#define WDOG_CS				U(0x0)
+#define WDOG_CS_ULK			BIT(11)
+#define WDOG_CNT			U(0x4)
+#define WDOG_TOVAL			U(0x8)
+
+#define BBNSM_BASE			U(0x44440000)
+#define BBNSM_CTRL			U(0x8)
+#define BBNSM_DP_EN			BIT(24)
+#define BBNSM_TOSP			BIT(25)
+
+#define SRC_BASE			U(0x44460000)
+#define GPC_BASE			U(0x44470000)
+#define BLK_CTRL_S_BASE			U(0x444F0000)
+#define S400_MU_BASE			U(0x47520000)
+
+/* system memory map define */
+#define AIPS2_MAP	MAP_REGION_FLAT(AIPS2_BASE, AIPSx_SIZE, MT_DEVICE | MT_RW | MT_NS)
+#define AIPS1_MAP	MAP_REGION_FLAT(AIPS1_BASE, AIPSx_SIZE, MT_DEVICE | MT_RW)
+#define AIPS4_MAP	MAP_REGION_FLAT(AIPS4_BASE, AIPSx_SIZE, MT_DEVICE | MT_RW | MT_NS)
+#define GIC_MAP		MAP_REGION_FLAT(PLAT_GICD_BASE, 0x200000, MT_DEVICE | MT_RW)
+#define TRDC_A_MAP	MAP_REGION_FLAT(TRDC_A_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
+#define TRDC_W_MAP	MAP_REGION_FLAT(TRDC_W_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
+#define TRDC_M_MAP	MAP_REGION_FLAT(TRDC_M_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
+#define TRDC_N_MAP	MAP_REGION_FLAT(TRDC_N_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
+
+#define COUNTER_FREQUENCY		24000000
+
+#endif /* platform_def.h */
diff --git a/plat/imx/imx93/include/pwr_ctrl.h b/plat/imx/imx93/include/pwr_ctrl.h
new file mode 100644
index 0000000..9bcf486
--- /dev/null
+++ b/plat/imx/imx93/include/pwr_ctrl.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PWR_CTRL_H
+#define PWR_CTRL_H
+
+#include <stdbool.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * GPC definitions & declarations
+ ******************************************************************************/
+/* GPC GLOBAL */
+#define GPC_GLOBAL_BASE		U(GPC_BASE + 0x4000)
+#define GPC_AUTHEN_CTRL		U(0x4)
+#define GPC_DOMAIN		U(0x10)
+#define GPC_MASTER		U(0x1c)
+#define GPC_SYS_SLEEP		U(0x40)
+#define PMIC_CTRL		U(0x100)
+#define PMIC_PRE_DLY_CTRL	U(0x104)
+#define PMIC_STBY_ACK_CTRL	U(0x108)
+#define GPC_ROSC_CTRL		U(0x200)
+#define GPC_AON_MEM_CTRL	U(0x204)
+#define GPC_EFUSE_CTRL		U(0x208)
+
+#define FORCE_CPUx_DISABLE(x)	(1 << (16 + (x)))
+#define PMIC_STBY_EN		BIT(0)
+#define ROSC_OFF_EN		BIT(0)
+
+/* GPC CPU_CTRL */
+#define CM_SLICE(x)		(GPC_BASE + 0x800 * (x))
+#define CM_AUTHEN_CTRL		U(0x4)
+#define CM_MISC			U(0xc)
+#define CM_MODE_CTRL		U(0x10)
+#define CM_IRQ_WAKEUP_MASK0	U(0x100)
+#define CM_SYS_SLEEP_CTRL	U(0x380)
+#define IMR_NUM			U(8)
+
+/* CM_MISC */
+#define SLEEP_HOLD_EN		BIT(1)
+#define IRQ_MUX			BIT(5)
+#define SW_WAKEUP		BIT(6)
+
+/* CM_SYS_SLEEP_CTRL */
+#define SS_WAIT			BIT(0)
+#define SS_STOP			BIT(1)
+#define SS_SUSPEND		BIT(2)
+
+#define CM_MODE_RUN		U(0x0)
+#define CM_MODE_WAIT		U(0x1)
+#define CM_MODE_STOP		U(0x2)
+#define CM_MODE_SUSPEND		U(0x3)
+
+#define LPM_SETTING(d, m)	((m) << (((d) % 8) * 4))
+
+enum gpc_cmc_slice {
+	CPU_M33,
+	CPU_A55C0,
+	CPU_A55C1,
+	CPU_A55_PLAT,
+};
+
+/* set gpc domain assignment */
+static inline void gpc_assign_domains(unsigned int domains)
+{
+	mmio_write_32(GPC_GLOBAL_BASE + GPC_DOMAIN, domains);
+}
+
+/* force a cpu into sleep status */
+static inline void gpc_force_cpu_suspend(unsigned int cpu)
+{
+	mmio_setbits_32(GPC_GLOBAL_BASE + GPC_SYS_SLEEP, FORCE_CPUx_DISABLE(cpu));
+}
+
+static inline void gpc_pmic_stby_en(bool en)
+{
+	mmio_write_32(GPC_GLOBAL_BASE + PMIC_CTRL, en ? 1 : 0);
+}
+
+static inline void gpc_rosc_off(bool off)
+{
+	mmio_write_32(GPC_GLOBAL_BASE + GPC_ROSC_CTRL, off ? 1 : 0);
+}
+
+static inline void gpc_set_cpu_mode(unsigned int cpu, unsigned int mode)
+{
+	mmio_write_32(CM_SLICE(cpu) + CM_MODE_CTRL, mode);
+}
+
+static inline void gpc_select_wakeup_gic(unsigned int cpu)
+{
+	mmio_setbits_32(CM_SLICE(cpu) + CM_MISC, IRQ_MUX);
+}
+
+static inline void gpc_select_wakeup_raw_irq(unsigned int cpu)
+{
+	mmio_clrbits_32(CM_SLICE(cpu) + CM_MISC, IRQ_MUX);
+}
+
+static inline void gpc_assert_sw_wakeup(unsigned int cpu)
+{
+	mmio_setbits_32(CM_SLICE(cpu) + CM_MISC, SW_WAKEUP);
+}
+
+static inline void gpc_deassert_sw_wakeup(unsigned int cpu)
+{
+	mmio_clrbits_32(CM_SLICE(cpu) + CM_MISC, SW_WAKEUP);
+}
+
+static inline void gpc_clear_cpu_sleep_hold(unsigned int cpu)
+{
+	mmio_clrbits_32(CM_SLICE(cpu) + CM_MISC, SLEEP_HOLD_EN);
+}
+
+static inline void gpc_set_irq_mask(unsigned int cpu, unsigned int idx, uint32_t mask)
+{
+	mmio_write_32(CM_SLICE(cpu) + idx * 0x4 + CM_IRQ_WAKEUP_MASK0, mask);
+}
+
+/*******************************************************************************
+ * SRC definitions & declarations
+ ******************************************************************************/
+#define SRC_SLICE(x)		(SRC_BASE + 0x400 * (x))
+#define SRC_AUTHEN_CTRL		U(0x4)
+#define SRC_LPM_SETTING0	U(0x10)
+#define SRC_LPM_SETTING1	U(0x14)
+#define SRC_LPM_SETTING2	U(0x18)
+#define SRC_SLICE_SW_CTRL	U(0x20)
+
+#define SRC_MEM_CTRL		U(0x4)
+#define MEM_LP_EN		BIT(2)
+#define MEM_LP_RETN		BIT(1)
+
+enum mix_mem_mode {
+	MEM_OFF,
+	MEM_RETN,
+};
+
+enum src_mix_mem_slice {
+	SRC_GLOBAL,
+
+	/* MIX slice */
+	SRC_SENTINEL,
+	SRC_AON,
+	SRC_WKUP,
+	SRC_DDR,
+	SRC_DPHY,
+	SRC_ML,
+	SRC_NIC,
+	SRC_HSIO,
+	SRC_MEDIA,
+	SRC_M33P,
+	SRC_A55C0,
+	SRC_A55C1,
+	SRC_A55P,
+
+	/* MEM slice */
+	SRC_AON_MEM,
+	SRC_WKUP_MEM,
+	SRC_DDR_MEM,
+	SRC_DPHY_MEM,
+	SRC_ML_MEM,
+	SRC_NIC_MEM,
+	SRC_NIC_OCRAM,
+	SRC_HSIO_MEM,
+	SRC_MEDIA_MEM,
+	SRC_A55P0_MEM,
+	SRC_A55P1_MEM,
+	SRC_A55_SCU_MEM,
+	SRC_A55_L3_MEM,
+};
+
+static inline void src_authen_config(unsigned int mix, unsigned int wlist,
+				unsigned int lpm_en)
+{
+	mmio_write_32(SRC_SLICE(mix) + SRC_AUTHEN_CTRL, (wlist << 16) | (lpm_en << 2));
+}
+
+static inline void src_mix_set_lpm(unsigned int mix, unsigned int did, unsigned int lpm_mode)
+{
+	mmio_clrsetbits_32(SRC_SLICE(mix) + SRC_LPM_SETTING1 + (did / 8) * 0x4,
+			   LPM_SETTING(did, 0x7), LPM_SETTING(did, lpm_mode));
+}
+
+static inline void src_mem_lpm_en(unsigned int mix, bool retn)
+{
+	mmio_setbits_32(SRC_SLICE(mix) + SRC_MEM_CTRL, MEM_LP_EN | (retn ? MEM_LP_RETN : 0));
+}
+
+static inline void src_mem_lpm_dis(unsigned int mix)
+{
+	mmio_clrbits_32(SRC_SLICE(mix) + SRC_MEM_CTRL, MEM_LP_EN | MEM_LP_RETN);
+}
+
+/*******************************************************************************
+ * BLK_CTRL_S definitions & declarations
+ ******************************************************************************/
+#define HW_LP_HANDHSK		U(0x110)
+#define HW_LP_HANDHSK2		U(0x114)
+#define CA55_CPUWAIT		U(0x118)
+#define CA55_RVBADDR0_L		U(0x11c)
+#define CA55_RVBADDR0_H		U(0x120)
+
+/*******************************************************************************
+ * Other definitions & declarations
+ ******************************************************************************/
+void pwr_sys_init(void);
+
+#endif /* PWR_CTRL_H */
+
diff --git a/plat/imx/imx93/plat_topology.c b/plat/imx/imx93/plat_topology.c
new file mode 100644
index 0000000..739e2b9
--- /dev/null
+++ b/plat/imx/imx93/plat_topology.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <plat/common/platform.h>
+
+const unsigned char imx_power_domain_tree_desc[] = {
+	PWR_DOMAIN_AT_MAX_LVL,
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return imx_power_domain_tree_desc;
+}
+
+/*
+ * Only one cluster is planned for i.MX9 family, no need
+ * to consider the cluster id
+ */
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
+		return -1;
+	}
+
+	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	return cpu_id;
+}
diff --git a/plat/imx/imx93/platform.mk b/plat/imx/imx93/platform.mk
new file mode 100644
index 0000000..ed7e81f
--- /dev/null
+++ b/plat/imx/imx93/platform.mk
@@ -0,0 +1,46 @@
+#
+# Copyright 2022-2023 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES		:=	-Iplat/imx/common/include		\
+				-Iplat/imx/imx93/include		\
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+GICV3_SUPPORT_GIC600  :=      1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
+				plat/common/plat_gicv3.c		\
+				plat/common/plat_psci_common.c		\
+				plat/imx/common/plat_imx8_gic.c
+
+BL31_SOURCES		+=	plat/common/aarch64/crash_console_helpers.S   \
+				plat/imx/imx93/aarch64/plat_helpers.S		\
+				plat/imx/imx93/plat_topology.c			\
+				plat/imx/common/lpuart_console.S		\
+				plat/imx/imx93/trdc.c			\
+				plat/imx/imx93/pwr_ctrl.c			\
+				plat/imx/imx93/imx93_bl31_setup.c		\
+				plat/imx/imx93/imx93_psci.c			\
+				lib/cpus/aarch64/cortex_a55.S			\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				drivers/nxp/trdc/imx_trdc.c			\
+				${IMX_GIC_SOURCES}				\
+				${XLAT_TABLES_LIB_SRCS}
+
+RESET_TO_BL31		:=	1
+HW_ASSISTED_COHERENCY	:= 	1
+USE_COHERENT_MEM	:=	0
+PROGRAMMABLE_RESET_ADDRESS :=	1
+COLD_BOOT_SINGLE_CPU	:=	1
+
+BL32_BASE               ?=      0x96000000
+BL32_SIZE               ?=      0x02000000
+$(eval $(call add_define,BL32_BASE))
+$(eval $(call add_define,BL32_SIZE))
diff --git a/plat/imx/imx93/pwr_ctrl.c b/plat/imx/imx93/pwr_ctrl.c
new file mode 100644
index 0000000..624c605
--- /dev/null
+++ b/plat/imx/imx93/pwr_ctrl.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdbool.h>
+
+#include <platform_def.h>
+#include <pwr_ctrl.h>
+
+/*Do the necessary GPC, SRC, BLK_CTRL_S init */
+void pwr_sys_init(void)
+{
+	unsigned int cpu;
+
+	/*
+	 * Assigned A55 cluster to 3, m33 to 2, A55 CORE0 & CORE1 to 0/1.
+	 * domain0/1 only used for trigger LPM of themselves. A55 cluster & M33's
+	 * domain assignment should be align with the TRDC DID.
+	 */
+	gpc_assign_domains(0x3102);
+
+	/* CA55 core0/1 config */
+	for (cpu = CPU_A55C0; cpu <= CPU_A55_PLAT; cpu++) {
+		/* clear the cpu sleep hold */
+		gpc_clear_cpu_sleep_hold(cpu);
+		/* use gic wakeup source by default */
+		gpc_select_wakeup_gic(cpu);
+		/*
+		 * Ignore A55 core0/1's LPM trigger for system sleep.
+		 * normally, for A55 side, only the A55 cluster(plat)
+		 * domain will be used to trigger the system wide low
+		 * power mode transition.
+		 */
+		if (cpu != CPU_A55_PLAT) {
+			gpc_force_cpu_suspend(cpu);
+		}
+	}
+
+	/* boot core(A55C0) */
+	src_mem_lpm_en(SRC_A55P0_MEM, MEM_OFF);
+	/* For A55 core, only need to be on in RUN mode */
+	src_mix_set_lpm(SRC_A55C0, 0x0, CM_MODE_WAIT);
+	/* whitelist: 0x1 for domain 0 only */
+	src_authen_config(SRC_A55C0, 0x1, 0x1);
+
+	/* A55 cluster */
+	gpc_select_wakeup_gic(CPU_A55_PLAT);
+	gpc_clear_cpu_sleep_hold(CPU_A55_PLAT);
+
+	/* SCU MEM must be OFF when A55 PLAT OFF */
+	src_mem_lpm_en(SRC_A55_SCU_MEM, MEM_OFF);
+	/* L3 memory in retention by default */
+	src_mem_lpm_en(SRC_A55_L3_MEM, MEM_RETN);
+
+	src_mix_set_lpm(SRC_A55P, 0x3, 0x1);
+	/* whitelist: 0x8 for domain 3 only */
+	src_authen_config(SRC_A55P, 0x8, 0x1);
+
+	/* enable the HW LP handshake between S401 & A55 cluster */
+	mmio_setbits_32(BLK_CTRL_S_BASE + HW_LP_HANDHSK, BIT(5));
+}
+
diff --git a/plat/imx/imx93/trdc.c b/plat/imx/imx93/trdc.c
new file mode 100644
index 0000000..0d09aa6
--- /dev/null
+++ b/plat/imx/imx93/trdc.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "trdc_config.h"
+
+struct trdc_mgr_info trdc_mgr_blks[] = {
+	{ TRDC_A_BASE, 0, 0, 39, 40 },
+	{ TRDC_W_BASE, 0, 0, 70, 71 },
+	{ TRDC_M_BASE, 1, 0, 1, 2 },
+	{ TRDC_N_BASE, 0, 1, 1, 2 },
+};
+
+unsigned int trdc_mgr_num = ARRAY_SIZE(trdc_mgr_blks);
+
+struct trdc_config_info trdc_cfg_info[] = {
+	{	TRDC_A_BASE,
+		trdc_a_mbc_glbac, ARRAY_SIZE(trdc_a_mbc_glbac),
+		trdc_a_mbc, ARRAY_SIZE(trdc_a_mbc),
+		trdc_a_mrc_glbac, ARRAY_SIZE(trdc_a_mrc_glbac),
+		trdc_a_mrc, ARRAY_SIZE(trdc_a_mrc)
+	}, /* TRDC_A */
+	{	TRDC_W_BASE,
+		trdc_w_mbc_glbac, ARRAY_SIZE(trdc_w_mbc_glbac),
+		trdc_w_mbc, ARRAY_SIZE(trdc_w_mbc),
+		trdc_w_mrc_glbac, ARRAY_SIZE(trdc_w_mrc_glbac),
+		trdc_w_mrc, ARRAY_SIZE(trdc_w_mrc)
+	}, /* TRDC_W */
+	{	TRDC_N_BASE,
+		trdc_n_mbc_glbac, ARRAY_SIZE(trdc_n_mbc_glbac),
+		trdc_n_mbc, ARRAY_SIZE(trdc_n_mbc),
+		trdc_n_mrc_glbac, ARRAY_SIZE(trdc_n_mrc_glbac),
+		trdc_n_mrc, ARRAY_SIZE(trdc_n_mrc)
+	}, /* TRDC_N */
+};
+
+void trdc_config(void)
+{
+	unsigned int i;
+
+	/* Set MTR to DID1 */
+	trdc_mda_set_noncpu(TRDC_A_BASE, 4, false, 0x2, 0x2, 0x1);
+
+	/* Set M33 to DID2*/
+	trdc_mda_set_cpu(TRDC_A_BASE, 1, 0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0);
+
+	/* Configure the access permission for TRDC MGR and MC slots */
+	for (i = 0U; i < ARRAY_SIZE(trdc_mgr_blks); i++) {
+		trdc_mgr_mbc_setup(&trdc_mgr_blks[i]);
+	}
+
+	/* Configure TRDC user settings from config table */
+	for (i = 0U; i < ARRAY_SIZE(trdc_cfg_info); i++) {
+		trdc_setup(&trdc_cfg_info[i]);
+	}
+
+	NOTICE("TRDC init done\n");
+}
diff --git a/plat/imx/imx93/trdc_config.h b/plat/imx/imx93/trdc_config.h
new file mode 100644
index 0000000..c623a19
--- /dev/null
+++ b/plat/imx/imx93/trdc_config.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/nxp/trdc/imx_trdc.h>
+
+#define TRDC_A_BASE	U(0x44270000)
+#define TRDC_W_BASE	U(0x42460000)
+#define TRDC_M_BASE	U(0x42460000)
+#define TRDC_N_BASE	U(0x49010000)
+
+/* GLBAC7 is used for TRDC only, any setting to GLBAC7 will be ignored */
+
+/* aonmix */
+struct trdc_glbac_config trdc_a_mbc_glbac[] = {
+	/* MBC0 */
+	{ 0, 0, SP(RW)  | SU(RW)   | NP(RW)  | NU(RW) },
+	/* MBC1 */
+	{ 1, 0, SP(RW)  | SU(RW)   | NP(RW)  | NU(RW) },
+	{ 1, 1, SP(RW)  | SU(R)    | NP(RW)  | NU(R)  },
+	{ 1, 2, SP(RWX) | SU(RWX)  | NP(RWX) | NU(RWX)  },
+};
+
+struct trdc_mbc_config trdc_a_mbc[] = {
+	{ 0, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS1 for S401 DID0 */
+	{ 0, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC0 Sentinel_SOC_In for S401 DID0 */
+	{ 0, 0, 2, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO1 for S401 DID0 */
+	{ 1, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC1 CM33 code TCM for S401 DID0 */
+	{ 1, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC1 CM33 system TCM for S401 DID0 */
+
+	{ 0, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS1 for MTR DID1 */
+	{ 0, 1, 1, MBC_BLK_ALL, 0, true }, /* MBC0 Sentinel_SOC_In for MTR DID1 */
+
+	{ 0, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS1 for M33 DID2 */
+	{ 0, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC0 Sentinel_SOC_In for M33 DID2 */
+	{ 0, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO1 for M33 DID2 */
+	{ 1, 2, 0, MBC_BLK_ALL, 2, true  }, /* MBC1 CM33 code TCM for M33 DID2 */
+	{ 1, 2, 1, MBC_BLK_ALL, 2, true  }, /* MBC1 CM33 system TCM for M33 DID2 */
+
+	{ 0, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS1 for A55 DID3 */
+	{ 0, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC0 Sentinel_SOC_In for A55 DID3 */
+	{ 0, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC0 GPIO1 for A55 DID3 */
+	{ 1, 3, 0, MBC_BLK_ALL, 1, false }, /* MBC1 CM33 code TCM for A55 DID3 */
+	{ 1, 3, 1, MBC_BLK_ALL, 1, false }, /* MBC1 CM33 system TCM for A55 DID3 */
+	{ 1, 10, 1, MBC_BLK_ALL, 2, false }, /* MBC1 CM33 system TCM for SoC masters DID10 */
+
+	{ 0, 7, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS1 for eDMA DID7 */
+};
+
+struct trdc_glbac_config trdc_a_mrc_glbac[] = {
+	{ 0, 0, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
+	{ 0, 1, SP(R)   | SU(0)   | NP(R)   | NU(0)   },
+};
+
+struct trdc_mrc_config trdc_a_mrc[] = {
+	{ 0, 2, 0, 0x00000000, 0x00040000, 0, true }, /* MRC0 M33 ROM for M33 DID2 */
+	{ 0, 3, 0, 0x00100000, 0x00040000, 1, true }, /* MRC0 M33 ROM for A55 DID3 */
+};
+
+/* wakeupmix */
+struct trdc_glbac_config trdc_w_mbc_glbac[] = {
+	/* MBC0 */
+	{ 0, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
+	/* MBC1 */
+	{ 1, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
+};
+
+struct trdc_mbc_config trdc_w_mbc[] = {
+	{ 0, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS2 for MTR DID1 */
+	{ 1, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC1 AIPS3 for MTR DID1 */
+
+	{ 0, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS2 for M33 DID2 */
+	{ 0, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO2_In for M33 DID2 */
+	{ 0, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO3 for M33 DID2 */
+	{ 0, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC0 DAP  for M33 DID2 */
+	{ 1, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC1 AIPS3 for M33 DID2 */
+	{ 1, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC1 AHB_ISPAP for M33 DID2 */
+	{ 1, 2, 2, MBC_BLK_ALL, 0, true },  /* MBC1 NIC_MAIN_GPV for M33 DID2 */
+	{ 1, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC1 GPIO4 for M33 DID2 */
+
+	{ 0, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS2 for A55 DID3 */
+	{ 0, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC0 GPIO2_In for A55 DID3 */
+	{ 0, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC0 GPIO3 for A55 DID3 */
+	{ 0, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC0 DAP  for A55 DID3 */
+	{ 1, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC1 AIPS3 for A55 DID3 */
+	{ 1, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC1 AHB_ISPAP for A55 DID3 */
+	{ 1, 3, 2, MBC_BLK_ALL, 0, true },  /* MBC1 NIC_MAIN_GPV for A55 DID3 */
+	{ 1, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC1 GPIO4 for A55 DID3 */
+
+	{ 0, 7, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS2 for eDMA DID7 */
+	{ 1, 7, 0, MBC_BLK_ALL, 0, false }, /* MBC1 AIPS3 for eDMA DID7  */
+};
+
+struct trdc_glbac_config trdc_w_mrc_glbac[] = {
+	/* MRC0 */
+	{ 0, 0, SP(RX)  | SU(RX)   | NP(RX)   | NU(RX)    },
+	/* MRC1 */
+	{ 1, 0, SP(RWX) | SU(RWX)  | NP(RWX)  | NU(RWX)   },
+};
+
+struct trdc_mrc_config trdc_w_mrc[] = {
+	{ 0, 3, 0, 0x00000000, 0x00040000, 0, false }, /* MRC0 A55 ROM for A55 DID3 */
+	{ 1, 2, 0, 0x28000000, 0x08000000, 0, true  }, /* MRC1 FLEXSPI1 for M33 DID2 */
+	{ 1, 3, 0, 0x28000000, 0x08000000, 0, false }, /* MRC1 FLEXSPI1 for A55 DID3 */
+};
+
+/* nicmix */
+struct trdc_glbac_config trdc_n_mbc_glbac[] = {
+	/* MBC0 */
+	{ 0, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
+	/* MBC1 */
+	{ 1, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
+	/* MBC2 */
+	{ 2, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
+	{ 2, 1, SP(R) | SU(R) | NP(R) | NU(R) },
+	/* MBC3 */
+	{ 3, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
+	{ 3, 1, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
+};
+
+struct trdc_mbc_config trdc_n_mbc[] = {
+	{ 0, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC0 DDRCFG for S401 DID0 */
+	{ 0, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS4 for  S401 DID0 */
+	{ 0, 0, 2, MBC_BLK_ALL, 0, true }, /* MBC0 MEDIAMIX for  S401 DID0 */
+	{ 0, 0, 3, MBC_BLK_ALL, 0, true }, /* MBC0 HSIOMIX for  S401 DID0 */
+	{ 1, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for  S401 DID0 */
+	{ 1, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for  S401 DID0 */
+	{ 1, 0, 2, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for  S401 DID0 */
+	{ 1, 0, 3, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for  S401 DID0 */
+	{ 2, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC2 GIC for  S401 DID0 */
+	{ 2, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC2 GIC for  S401 DID0 */
+	{ 3, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC3 OCRAM for  S401 DID0 */
+	{ 3, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC3 OCRAM for  S401 DID0 */
+
+	{ 0, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC0 DDRCFG for MTR DID1 */
+	{ 0, 1, 1, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS4 for  MTR DID1 */
+	{ 0, 1, 2, MBC_BLK_ALL, 0, true }, /* MBC0 MEDIAMIX for MTR DID1 */
+	{ 0, 1, 3, MBC_BLK_ALL, 0, true }, /* MBC0 HSIOMIX for  MTR DID1 */
+	{ 1, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for  MTR DID1 */
+	{ 1, 1, 1, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for  MTR DID1 */
+	{ 1, 1, 2, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for  MTR DID1 */
+	{ 1, 1, 3, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for  MTR DID1 */
+
+	{ 0, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC0 DDRCFG for M33 DID2 */
+	{ 0, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS4 for M33 DID2 */
+	{ 0, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC0 MEDIAMIX for M33 DID2 */
+	{ 0, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC0 HSIOMIX for M33 DID2 */
+	{ 1, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for M33 DID2 */
+	{ 1, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for M33 DID2 */
+	{ 1, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for M33 DID2 */
+	{ 1, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for M33 DID2 */
+	{ 2, 2, 0, MBC_BLK_ALL, 1, true }, /* MBC2 GIC for M33 DID2 */
+	{ 2, 2, 1, MBC_BLK_ALL, 1, true }, /* MBC2 GIC for M33 DID2 */
+	{ 3, 2, 0, MBC_BLK_ALL, 0, true  }, /* MBC3 OCRAM for M33 DID2 */
+	{ 3, 2, 1, MBC_BLK_ALL, 0, true  }, /* MBC3 OCRAM for M33 DID2 */
+
+	{ 0, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC0 DDRCFG for A55 DID3 */
+	{ 0, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS4 for A55 DID3 */
+	{ 0, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC0 MEDIAMIX for A55 DID3 */
+	{ 0, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC0 HSIOMIX for A55 DID3 */
+	{ 1, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC1 MTR_DCA, TCU, TROUT for A55 DID3 */
+	{ 1, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC1 MTR_DCA, TCU, TROUT for A55 DID3 */
+	{ 1, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC1 MLMIX for A55 DID3 */
+	{ 1, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC1 MLMIX for A55 DID3 */
+	{ 2, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC2 GIC for A55 DID3 */
+	{ 2, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC2 GIC for A55 DID3 */
+	{ 3, 3, 0, MBC_BLK_ALL, 1, true  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, MBC_BLK_ALL, 1, true  }, /* MBC3 OCRAM for A55 DID3 */
+
+	{ 3, 3, 0, 0, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 0, 1, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 0, 2, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 0, 3, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 0, 4, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 0, 5, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, 0, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, 1, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, 2, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, 3, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, 4, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+	{ 3, 3, 1, 5, 0, false  }, /* MBC3 OCRAM for A55 DID3 */
+
+	{ 0, 7, 1, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS4 for eDMA DID7 */
+	{ 0, 7, 2, MBC_BLK_ALL, 0, false }, /* MBC0 MEDIAMIX for eDMA DID7 */
+	{ 0, 7, 3, MBC_BLK_ALL, 0, false }, /* MBC0 HSIOMIX for eDMA DID7 */
+
+	{ 3, 10, 0, MBC_BLK_ALL, 0, false }, /* MBC3 OCRAM for DID10 */
+	{ 3, 10, 1, MBC_BLK_ALL, 0, false }, /* MBC3 OCRAM for DID10 */
+};
+
+struct trdc_glbac_config trdc_n_mrc_glbac[] = {
+	{ 0, 0, SP(RW)  | SU(RW)  | NP(RW)  | NU(RW)  },
+	{ 0, 1, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
+};
+
+#if defined(SPD_opteed)
+#define TEE_SHM_SIZE 0x200000
+
+#define DRAM_MEM_0_START (0x80000000)
+#define DRAM_MEM_0_SIZE (BL32_BASE - 0x80000000)
+
+#define DRAM_MEM_1_START (BL32_BASE)
+#define DRAM_MEM_1_SIZE (BL32_SIZE - TEE_SHM_SIZE)
+
+#define DRAM_MEM_2_START (DRAM_MEM_1_START + DRAM_MEM_1_SIZE)
+#define DRAM_MEM_2_SIZE (0x80000000 - DRAM_MEM_1_SIZE - DRAM_MEM_0_SIZE)
+
+struct trdc_mrc_config trdc_n_mrc[] = {
+	{ 0, 0, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for S400 DID0 */
+	{ 0, 1, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for MTR DID1 */
+	{ 0, 2, 0, 0x80000000, 0x80000000, 0, true }, /* MRC0 DRAM for M33 DID2 */
+	{ 0, 8, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for Coresight, Testport DID8 */
+	{ 0, 9, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for DAP DID9 */
+
+	{ 0, 3, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 1, false }, /* MRC0 DRAM for A55 DID3 */
+	{ 0, 5, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */
+	{ 0, 6, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */
+	{ 0, 7, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for eDMA DID7 */
+	{ 0, 10, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for SoC masters DID10 */
+	{ 0, 11, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for USB DID11 */
+
+	/* OPTEE memory for  secure access only. */
+	{ 0, 3, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 1, true }, /* MRC0 DRAM for A55 DID3 */
+	{ 0, 5, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for USDHC1 DID5 */
+	{ 0, 6, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for USDHC2 DID6 */
+	{ 0, 7, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for eDMA DID7 */
+	{ 0, 10, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for SoC masters DID10 */
+	{ 0, 11, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for USB DID11 */
+
+	{ 0, 3, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 1, false }, /* MRC0 DRAM for A55 DID3 */
+	{ 0, 5, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */
+	{ 0, 6, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */
+	{ 0, 7, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for eDMA DID7 */
+	{ 0, 10, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for SoC masters DID10 */
+	{ 0, 11, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for USB DID11 */
+
+};
+#else
+struct trdc_mrc_config trdc_n_mrc[] = {
+	{ 0, 0, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for S400 DID0 */
+	{ 0, 1, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for MTR DID1 */
+	{ 0, 2, 0, 0x80000000, 0x80000000, 0, true }, /* MRC0 DRAM for M33 DID2 */
+	{ 0, 3, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for A55 DID3 */
+	{ 0, 5, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */
+	{ 0, 6, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */
+	{ 0, 7, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for eDMA DID7 */
+	{ 0, 8, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for Coresight, Testport DID8 */
+	{ 0, 9, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for DAP DID9 */
+	{ 0, 10, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for SoC masters DID10 */
+	{ 0, 11, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USB DID11 */
+};
+#endif
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 26ed7ef..b4e19de 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -155,7 +155,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index f39d475..ee22241 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -127,5 +127,7 @@
 uint32_t get_wdt_clk(void);
 uint32_t get_uart_clk(void);
 uint32_t get_mmc_clk(void);
+uint32_t get_mpu_clk(void);
+uint32_t get_cpu_clk(void);
 
 #endif
diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h
index 3746d92..9db4292 100644
--- a/plat/intel/soc/agilex/include/agilex_memory_controller.h
+++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h
@@ -158,6 +158,19 @@
 #define AGX_SDRAM_0_LB_ADDR				0x0
 #define AGX_DDR_SIZE					0x40000000
 
+/* Macros */
+#define SOCFPGA_MEMCTRL_ECCCTRL1					0x008
+#define SOCFPGA_MEMCTRL_ERRINTEN					0x010
+#define SOCFPGA_MEMCTRL_ERRINTENS					0x014
+#define SOCFPGA_MEMCTRL_ERRINTENR					0x018
+#define SOCFPGA_MEMCTRL_INTMODE					0x01C
+#define SOCFPGA_MEMCTRL_INTSTAT					0x020
+#define SOCFPGA_MEMCTRL_DIAGINTTEST					0x024
+#define SOCFPGA_MEMCTRL_DERRADDRA					0x02C
+
+#define SOCFPGA_MEMCTRL(_reg)		(SOCFPGA_MEMCTRL_REG_BASE \
+						+ (SOCFPGA_MEMCTRL_##_reg))
+
 int init_hard_memory_controller(void);
 
 #endif
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
new file mode 100644
index 0000000..cb9222d
--- /dev/null
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef AGX_SOCFPGA_SYSTEMMANAGER_H
+#define AGX_SOCFPGA_SYSTEMMANAGER_H
+
+#include "socfpga_plat_def.h"
+
+/* System Manager Register Map */
+#define SOCFPGA_SYSMGR_SILICONID_1			0x00
+#define SOCFPGA_SYSMGR_SILICONID_2			0x04
+#define SOCFPGA_SYSMGR_WDDBG				0x08
+#define SOCFPGA_SYSMGR_MPU_STATUS			0x10
+#define SOCFPGA_SYSMGR_SDMMC_L3_MASTER			0x2C
+#define SOCFPGA_SYSMGR_NAND_L3_MASTER			0x34
+#define SOCFPGA_SYSMGR_USB0_L3_MASTER			0x38
+#define SOCFPGA_SYSMGR_USB1_L3_MASTER			0x3C
+#define SOCFPGA_SYSMGR_TSN_GLOBAL			0x40
+#define SOCFPGA_SYSMGR_EMAC_0				0x44 /* TSN_0 */
+#define SOCFPGA_SYSMGR_EMAC_1				0x48 /* TSN_1 */
+#define SOCFPGA_SYSMGR_EMAC_2				0x4C /* TSN_2 */
+#define SOCFPGA_SYSMGR_TSN_0_ACE			0x50
+#define SOCFPGA_SYSMGR_TSN_1_ACE			0x54
+#define SOCFPGA_SYSMGR_TSN_2_ACE			0x58
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_1			0x68
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2			0x6C
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3			0x70
+#define SOCFPGA_SYSMGR_DMAC0_L3_MASTER			0x74
+#define SOCFPGA_SYSMGR_ETR_L3_MASTER			0x78
+#define SOCFPGA_SYSMGR_DMAC1_L3_MASTER			0x7C
+#define SOCFPGA_SYSMGR_SEC_CTRL_SLT			0x80
+#define SOCFPGA_SYSMGR_OSC_TRIM				0x84
+#define SOCFPGA_SYSMGR_DMAC0_CTRL_STATUS_REG		0x88
+#define SOCFPGA_SYSMGR_DMAC1_CTRL_STATUS_REG		0x8C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_VALUE		0x90
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SET			0x94
+#define SOCFPGA_SYSMGR_ECC_INTMASK_CLR			0x98
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SERR			0x9C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_DERR			0xA0
+/* NOC configuration value for Agilex5 */
+#define SOCFPGA_SYSMGR_NOC_TIMEOUT			0xC0
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET			0xC4
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR			0xC8
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL			0xCC
+#define SOCFPGA_SYSMGR_NOC_IDLEACK			0xD0
+#define SOCFPGA_SYSMGR_NOC_IDLESTATUS			0xD4
+#define SOCFPGA_SYSMGR_FPGA2SOC_CTRL			0xD8
+#define SOCFPGA_SYSMGR_FPGA_CFG				0xDC
+#define SOCFPGA_SYSMGR_GPO				0xE4
+#define SOCFPGA_SYSMGR_GPI				0xE8
+#define SOCFPGA_SYSMGR_MPU				0xF0
+#define SOCFPGA_SYSMGR_SDM_HPS_SPARE			0xF4
+#define SOCFPGA_SYSMGR_HPS_SDM_SPARE			0xF8
+#define SOCFPGA_SYSMGR_DFI_INTF				0xFC
+#define SOCFPGA_SYSMGR_NAND_DD_CTRL			0x100
+#define SOCFPGA_SYSMGR_NAND_PHY_CTRL_REG		0x104
+#define SOCFPGA_SYSMGR_NAND_PHY_TSEL_REG		0x108
+#define SOCFPGA_SYSMGR_NAND_DQ_TIMING_REG		0x10C
+#define SOCFPGA_SYSMGR_PHY_DQS_TIMING_REG		0x110
+#define SOCFPGA_SYSMGR_NAND_PHY_GATE_LPBK_CTRL_REG	0x114
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_MASTER_CTRL_REG	0x118
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_SLAVE_CTRL_REG	0x11C
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG0	0x120
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG1	0x124
+#define SOCFPGA_SYSMGR_NAND_DD_STATUS_REG		0x128
+#define SOCFPGA_SYSMGR_NAND_DD_ID_LOW_REG		0x12C
+#define SOCFPGA_SYSMGR_NAND_DD_ID_HIGH_REG		0x130
+#define SOCFPGA_SYSMGR_NAND_WRITE_PROT_EN_REG		0x134
+#define SOCFPGA_SYSMGR_SDMMC_CMD_QUEUE_SETTING_REG	0x138
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_LOW			0x13C
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_HIGH			0x140
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_0			0x144
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_1			0x148
+#define SOCFPGA_SYSMGR_F2S_BRIDGE_CTRL			0x14C
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA0	0x150
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA1	0x154
+#define SOCFPGA_SYSMGR_SDM_TBU_STASH_CTRL_REG_1_SDM	0x158
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB2	0x15C
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB3	0x160
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_SDMMC	0x164
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_NAND	0x168
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_ETR	0x16C
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN0	0x170
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN1	0x174
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN2	0x178
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA0	0x17C
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA1	0x180
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_CTRL_REG_1_SDM	0x184
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB2	0x188
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB3	0x18C
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_SDMMC	0x190
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_NAND	0x194
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_ETR	0x198
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN0	0x19C
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN1	0x1A0
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN2	0x1A4
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA0	0x1A8
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA1	0x1AC
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_ID_AX_REG_1_SDM	0x1B0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB2	0x1B4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB3	0x1B8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_SDMMC	0x1BC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_NAND	0x1C0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_ETR	0x1C4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN0	0x1C8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN1	0x1CC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN2	0x1D0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG0		0x1F0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG1		0x1F4
+
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0		0x200
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1		0x204
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2		0x208
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_3		0x20C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_4		0x210
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_5		0x214
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_6		0x218
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_7		0x21C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
+#define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
+#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_3		0x23C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_4		0x240
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_5		0x244
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_6		0x248
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_7		0x24C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_8		0x250
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_9		0x254
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0		0x258
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_1		0x25C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_2		0x260
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_3		0x264
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_4		0x268
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_5		0x26C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_6		0x270
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_7		0x274
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8		0x278
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9		0x27C
+
+#define DMA0_STREAM_CTRL_REG				0x10D1217C
+#define DMA1_STREAM_CTRL_REG				0x10D12180
+#define SDM_STREAM_CTRL_REG				0x10D12184
+#define USB2_STREAM_CTRL_REG				0x10D12188
+#define USB3_STREAM_CTRL_REG				0x10D1218C
+#define SDMMC_STREAM_CTRL_REG				0x10D12190
+#define NAND_STREAM_CTRL_REG				0x10D12194
+#define ETR_STREAM_CTRL_REG				0x10D12198
+#define TSN0_STREAM_CTRL_REG				0x10D1219C
+#define TSN1_STREAM_CTRL_REG				0x10D121A0
+#define TSN2_STREAM_CTRL_REG				0x10D121A4
+
+/* Stream ID configuration value for Agilex5 */
+#define TSN0						0x00010001
+#define TSN1						0x00020002
+#define TSN2						0x00030003
+#define NAND						0x00040004
+#define SDMMC						0x00050005
+#define USB0						0x00060006
+#define USB1						0x00070007
+#define DMA0						0x00080008
+#define DMA1						0x00090009
+#define SDM						0x000A000A
+#define CORE_SIGHT_DEBUG				0x000B000B
+
+/* Field Masking */
+#define SYSMGR_SDMMC_DRVSEL(x)				(((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x)				(((x) & 0x7) << 4)
+#define IDLE_DATA_LWSOC2FPGA				BIT(4)
+#define IDLE_DATA_SOC2FPGA				BIT(0)
+#define IDLE_DATA_MASK					(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
+#define SYSMGR_ECC_OCRAM_MASK				BIT(1)
+#define SYSMGR_ECC_DDR0_MASK				BIT(16)
+#define SYSMGR_ECC_DDR1_MASK				BIT(17)
+#define WSTREAMIDEN_REG_CTRL				BIT(0)
+#define RSTREAMIDEN_REG_CTRL				BIT(1)
+#define WMMUSECSID_REG_VAL				BIT(4)
+#define RMMUSECSID_REG_VAL				BIT(5)
+
+/* Macros */
+#define SOCFPGA_SYSMGR(_reg)				(SOCFPGA_SYSMGR_REG_BASE \
+								+ (SOCFPGA_SYSMGR_##_reg))
+
+#define ENABLE_STREAMID					WSTREAMIDEN_REG_CTRL | \
+							RSTREAMIDEN_REG_CTRL
+#define ENABLE_STREAMID_SECURE_TX			WSTREAMIDEN_REG_CTRL | \
+							RSTREAMIDEN_REG_CTRL | \
+							WMMUSECSID_REG_VAL | RMMUSECSID_REG_VAL
+
+#endif /* AGX5_SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index b216ab1..a744d09 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,22 +8,30 @@
 #ifndef PLAT_SOCFPGA_DEF_H
 #define PLAT_SOCFPGA_DEF_H
 
+#include "agilex_system_manager.h"
 #include <platform_def.h>
 
 /* Platform Setting */
-#define PLATFORM_MODEL				PLAT_SOCFPGA_AGILEX
-#define BOOT_SOURCE				BOOT_SOURCE_SDMMC
+#define PLATFORM_MODEL						PLAT_SOCFPGA_AGILEX
+#define BOOT_SOURCE							BOOT_SOURCE_SDMMC
+#define PLAT_PRIMARY_CPU					0
+#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT			MPIDR_AFF0_SHIFT
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE		0x2000000
 
+/* QSPI Setting */
+#define CAD_QSPIDATA_OFST			0xff900000
+#define CAD_QSPI_OFFSET				0xff8d2000
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
 
 #define SOCFPGA_MMC_REG_BASE			0xff808000
-
+#define SOCFPGA_MEMCTRL_REG_BASE		0xf8011100
 #define SOCFPGA_RSTMGR_REG_BASE			0xffd11000
 #define SOCFPGA_SYSMGR_REG_BASE			0xffd12000
 
@@ -32,9 +40,66 @@
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE           0xffd21200
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE         0xffd21300
 
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define DRAM_BASE				(0x0)
+#define DRAM_SIZE				(0x80000000)
+
+#define OCRAM_BASE				(0xFFE00000)
+#define OCRAM_SIZE				(0x00040000)
+
+#define MEM64_BASE				(0x0100000000)
+#define MEM64_SIZE				(0x1F00000000)
+
+#define DEVICE1_BASE				(0x80000000)
+#define DEVICE1_SIZE				(0x60000000)
+
+#define DEVICE2_BASE				(0xF7000000)
+#define DEVICE2_SIZE				(0x08E00000)
+
+#define DEVICE3_BASE				(0xFFFC0000)
+#define DEVICE3_SIZE				(0x00008000)
+
+#define DEVICE4_BASE				(0x2000000000)
+#define DEVICE4_SIZE				(0x0100000000)
+
+#define BL2_BASE		(0xffe00000)
+#define BL2_LIMIT		(0xffe1b000)
+
+#define BL31_BASE		(0x1000)
+#define BL31_LIMIT		(0x81000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define PLAT_UART0_BASE		(0xFFC02000)
+#define PLAT_UART1_BASE		(0xFFC02100)
+
+/*******************************************************************************
+ * GIC related constants
+ ******************************************************************************/
+#define PLAT_GIC_BASE			(0xFFFC0000)
+#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
+#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
+#define PLAT_GICR_BASE			0
+
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
+#define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
+
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0xFFD12218
+
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
 
-uint32_t get_cpu_clk(void);
-
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index 76b9937..d32c3f1 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,8 +11,8 @@
 #include <lib/mmio.h>
 
 #include "agilex_clock_manager.h"
+#include "agilex_system_manager.h"
 #include "socfpga_handoff.h"
-#include "socfpga_system_manager.h"
 
 
 uint32_t wait_pll_lock(void)
@@ -388,12 +388,22 @@
 	return mmc_clk;
 }
 
+/* Return MPU clock */
+uint32_t get_mpu_clk(void)
+{
+	uint32_t mpu_clk;
+
+	mpu_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC0,
+				CLKMGR_PERPLL_PLLC0);
+	return mpu_clk;
+}
+
 /* Get cpu freq clock */
 uint32_t get_cpu_clk(void)
 {
 	uint32_t cpu_clk;
 
-	cpu_clk = get_l3_clk()/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+	cpu_clk = get_mpu_clk()/PLAT_HZ_CONVERT_TO_MHZ;
 
 	return cpu_clk;
 }
diff --git a/plat/intel/soc/agilex/soc/agilex_pinmux.c b/plat/intel/soc/agilex/soc/agilex_pinmux.c
index 96e1ade..d2a06fb 100644
--- a/plat/intel/soc/agilex/soc/agilex_pinmux.c
+++ b/plat/intel/soc/agilex/soc/agilex_pinmux.c
@@ -7,7 +7,7 @@
 #include <lib/mmio.h>
 
 #include "agilex_pinmux.h"
-#include "socfpga_system_manager.h"
+#include "agilex_system_manager.h"
 
 const uint32_t sysmgr_pinmux_array_sel[] = {
 	0x00000000, 0x00000001, /* usb */
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
new file mode 100644
index 0000000..88f9880
--- /dev/null
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/synopsys/dw_mmc.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_memory_controller.h"
+#include "agilex5_mmc.h"
+#include "agilex5_pinmux.h"
+#include "agilex5_system_manager.h"
+#include "ccu/ncore_ccu.h"
+#include "combophy/combophy.h"
+#include "nand/nand.h"
+#include "qspi/cadence_qspi.h"
+#include "sdmmc/sdmmc.h"
+#include "socfpga_emac.h"
+#include "socfpga_f2sdram_manager.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
+#include "socfpga_reset_manager.h"
+#include "wdt/watchdog.h"
+
+
+/* Declare mmc_info */
+static struct mmc_device_info mmc_info;
+
+/* Declare cadence idmac descriptor */
+extern struct cdns_idmac_desc cdns_desc[8] __aligned(32);
+
+const mmap_region_t agilex_plat_mmap[] = {
+	MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE,
+		MT_MEMORY | MT_RW | MT_NS),
+	MAP_REGION_FLAT(PSS_BASE, PSS_SIZE,
+		MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE,
+		MT_NON_CACHEABLE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CCU_BASE, CCU_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE,
+		MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(GIC_BASE, GIC_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	{0},
+};
+
+boot_source_type boot_source = BOOT_SOURCE;
+
+void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
+				u_register_t x2, u_register_t x4)
+{
+	static console_t console;
+
+	handoff reverse_handoff_ptr;
+
+	generic_delay_timer_init();
+	config_clkmgr_handoff(&reverse_handoff_ptr);
+	mailbox_init();
+	enable_nonsecure_access();
+
+	deassert_peripheral_reset();
+	if (combo_phy_init(&reverse_handoff_ptr) != 0) {
+		ERROR("Combo Phy initialization failed\n");
+	}
+
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+	PLAT_BAUDRATE, &console);
+
+	/* Store magic number */
+	mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+	handoff reverse_handoff_ptr;
+
+	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
+
+	mmc_info.mmc_dev_type = MMC_DEVICE_TYPE;
+	mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
+
+	/* Request ownership and direct access to QSPI */
+	mailbox_hps_qspi_enable();
+
+	switch (boot_source) {
+	case BOOT_SOURCE_SDMMC:
+		NOTICE("SDMMC boot\n");
+		sdmmc_init(&reverse_handoff_ptr, &params, &mmc_info);
+		socfpga_io_setup(boot_source);
+		break;
+
+	case BOOT_SOURCE_QSPI:
+		NOTICE("QSPI boot\n");
+		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
+			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
+			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
+		socfpga_io_setup(boot_source);
+		break;
+
+	case BOOT_SOURCE_NAND:
+		NOTICE("NAND boot\n");
+		nand_init(&reverse_handoff_ptr);
+		socfpga_io_setup(boot_source);
+		break;
+
+	default:
+		ERROR("Unsupported boot source\n");
+		panic();
+		break;
+	}
+}
+
+uint32_t get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+	assert(bl_mem_params);
+
+	switch (image_id) {
+	case BL33_IMAGE_ID:
+		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+		bl_mem_params->ep_info.spsr = get_spsr_for_bl33_entry();
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup code
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+}
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
new file mode 100644
index 0000000..5ae4bf7
--- /dev/null
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include "agilex5_power_manager.h"
+#include "ccu/ncore_ccu.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
+#include "socfpga_reset_manager.h"
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+#define SMMU_SDMMC
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ?
+			  &bl33_image_ep_info : &bl32_image_ep_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->pc)
+		return next_image_info;
+	else
+		return NULL;
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	static console_t console;
+
+	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
+
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+	PLAT_BAUDRATE, &console);
+
+	init_ncore_ccu();
+	setup_smmu_stream_id();
+
+	/*
+	 * Check params passed from BL31 should not be NULL,
+	 */
+	void *from_bl2 = (void *) arg0;
+
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	void *plat_params_from_bl2 = (void *) arg3;
+
+	assert(plat_params_from_bl2 == NULL);
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+	/*
+	 * According to the file ``Documentation/arm64/booting.txt`` of the
+	 * Linux kernel tree, Linux expects the physical address of the device
+	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+	 * must be 0.
+	 */
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
+	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+	assert(params_from_bl2 != NULL);
+
+	/*
+	 * Copy BL32 (if populated by BL31) and BL33 entry point information.
+	 * They are stored in Secure RAM, in BL31's address space.
+	 */
+
+	if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+		params_from_bl2->h.version >= VERSION_2) {
+
+		bl_params_node_t *bl_params = params_from_bl2->head;
+
+		while (bl_params) {
+			if (bl_params->image_id == BL33_IMAGE_ID) {
+				bl33_image_ep_info = *bl_params->ep_info;
+			}
+				bl_params = bl_params->next_params_info;
+		}
+	} else {
+		struct socfpga_bl31_params *arg_from_bl2 =
+			(struct socfpga_bl31_params *) from_bl2;
+
+		assert(arg_from_bl2->h.type == PARAM_BL31);
+		assert(arg_from_bl2->h.version >= VERSION_1);
+
+		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+		bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
+	}
+
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+}
+
+static const interrupt_prop_t agx5_interrupt_props[] = {
+	PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+static const gicv3_driver_data_t plat_gicv3_gic_data = {
+	.gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+	.gicr_base = PLAT_INTEL_SOCFPGA_GICR_BASE,
+	.interrupt_props = agx5_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(agx5_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+};
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup code
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+	socfpga_delay_timer_init();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	gicv3_driver_init(&plat_gicv3_gic_data);
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+#if !defined(SIMICS_RUN)
+	ncore_enable_ocram_firewall();
+#endif
+
+}
+
+const mmap_region_t plat_agilex_mmap[] = {
+	MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+	MAP_REGION_FLAT(PSS_BASE, PSS_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, MT_NON_CACHEABLE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CCU_BASE, CCU_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	{0}
+};
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+	uint32_t boot_core = 0x00;
+	uint32_t cpuid = 0x00;
+
+	cpuid = read_mpidr();
+	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	NOTICE("BL31: Boot Core = %x\n", boot_core);
+	NOTICE("BL31: CPU ID = %x\n", cpuid);
+
+}
+
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+/* SMP: Secondary cores BL31 setup reset vector */
+void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)
+{
+	unsigned int pch_cpu = 0x00;
+	unsigned int pchctlr_old = 0x00;
+	unsigned int pchctlr_new = 0x00;
+	uint32_t boot_core = 0x00;
+
+	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	/* Update the p-channel based on cpu id */
+	pch_cpu = 1 << cpu_id;
+
+	if (boot_core == 0x00) {
+		/* Update reset vector to 0x00 */
+		mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU2,
+(uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+	} else {
+		/* Update reset vector to 0x00 */
+		mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU0,
+(uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+	}
+
+	/* Update reset vector to 0x00 */
+	mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU1, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+	mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU3, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+
+	/* On all cores - temporary */
+	pchctlr_old = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
+	pchctlr_new = pchctlr_old | (pch_cpu<<1);
+	mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pchctlr_new);
+
+	/* We will only release the target secondary CPUs */
+	/* Bit mask for each CPU BIT0-3 */
+	mmio_write_32(RSTMGR_CPUSTRELEASE_CPUx, pch_cpu);
+}
+
+void bl31_plat_set_secondary_cpu_off(void)
+{
+	unsigned int pch_cpu = 0x00;
+	unsigned int pch_cpu_off = 0x00;
+	unsigned int cpu_id = plat_my_core_pos();
+
+	pch_cpu_off = 1 << cpu_id;
+
+	pch_cpu = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
+	pch_cpu = pch_cpu & ~(pch_cpu_off << 1);
+
+	mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu);
+}
+
+void bl31_plat_enable_mmu(uint32_t flags)
+{
+	/* TODO: Enable mmu when needed */
+}
diff --git a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
new file mode 100644
index 0000000..566a80d
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CLOCKMANAGER_H
+#define CLOCKMANAGER_H
+
+#include "socfpga_handoff.h"
+
+/* Clock Manager Registers */
+#define CLKMGR_OFFSET					0x10d10000
+
+#define CLKMGR_CTRL					0x0
+#define CLKMGR_STAT					0x4
+#define CLKMGR_TESTIOCTROL				0x8
+#define CLKMGR_INTRGEN					0xc
+#define CLKMGR_INTRMSK					0x10
+#define CLKMGR_INTRCLR					0x14
+#define CLKMGR_INTRSTS					0x18
+#define CLKMGR_INTRSTK					0x1c
+#define CLKMGR_INTRRAW					0x20
+
+/* Main PLL Group */
+#define CLKMGR_MAINPLL					0x10d10024
+#define CLKMGR_MAINPLL_EN				0x0
+#define CLKMGR_MAINPLL_ENS				0x4
+#define CLKMGR_MAINPLL_BYPASS				0xc
+#define CLKMGR_MAINPLL_BYPASSS				0x10
+#define CLKMGR_MAINPLL_BYPASSR				0x14
+#define CLKMGR_MAINPLL_NOCCLK				0x1c
+#define CLKMGR_MAINPLL_NOCDIV				0x20
+#define CLKMGR_MAINPLL_PLLGLOB				0x24
+#define CLKMGR_MAINPLL_FDBCK				0x28
+#define CLKMGR_MAINPLL_MEM				0x2c
+#define CLKMGR_MAINPLL_MEMSTAT				0x30
+#define CLKMGR_MAINPLL_VCOCALIB				0x34
+#define CLKMGR_MAINPLL_PLLC0				0x38
+#define CLKMGR_MAINPLL_PLLC1				0x3c
+#define CLKMGR_MAINPLL_PLLC2				0x40
+#define CLKMGR_MAINPLL_PLLC3				0x44
+#define CLKMGR_MAINPLL_PLLM				0x48
+#define CLKMGR_MAINPLL_FHOP				0x4c
+#define CLKMGR_MAINPLL_SSC				0x50
+#define CLKMGR_MAINPLL_LOSTLOCK				0x54
+
+/* Peripheral PLL Group */
+#define CLKMGR_PERPLL					0x10d1007c
+#define CLKMGR_PERPLL_EN				0x0
+#define CLKMGR_PERPLL_ENS				0x4
+#define CLKMGR_PERPLL_BYPASS				0xc
+#define CLKMGR_PERPLL_EMACCTL				0x18
+#define CLKMGR_PERPLL_GPIODIV				0x1c
+#define CLKMGR_PERPLL_PLLGLOB				0x20
+#define CLKMGR_PERPLL_FDBCK				0x24
+#define CLKMGR_PERPLL_MEM				0x28
+#define CLKMGR_PERPLL_MEMSTAT				0x2c
+#define CLKMGR_PERPLL_PLLC0				0x30
+#define CLKMGR_PERPLL_PLLC1				0x34
+#define CLKMGR_PERPLL_VCOCALIB				0x38
+#define CLKMGR_PERPLL_PLLC2				0x3c
+#define CLKMGR_PERPLL_PLLC3				0x40
+#define CLKMGR_PERPLL_PLLM				0x44
+#define CLKMGR_PERPLL_LOSTLOCK				0x50
+
+/* Altera Group */
+#define CLKMGR_ALTERA					0x10d100d0
+#define CLKMGR_ALTERA_JTAG				0x0
+#define CLKMGR_ALTERA_EMACACTR				0x4
+#define CLKMGR_ALTERA_EMACBCTR				0x8
+#define CLKMGR_ALTERA_EMACPTPCTR			0xc
+#define CLKMGR_ALTERA_GPIODBCTR				0x10
+#define CLKMGR_ALTERA_S2FUSER0CTR			0x18
+#define CLKMGR_ALTERA_S2FUSER1CTR			0x1c
+#define CLKMGR_ALTERA_PSIREFCTR				0x20
+#define CLKMGR_ALTERA_EXTCNTRST				0x24
+#define CLKMGR_ALTERA_USB31CTR				0x28
+#define CLKMGR_ALTERA_DSUCTR				0x2c
+#define CLKMGR_ALTERA_CORE01CTR				0x30
+#define CLKMGR_ALTERA_CORE23CTR				0x34
+#define CLKMGR_ALTERA_CORE2CTR				0x38
+#define CLKMGR_ALTERA_CORE3CTR				0x3c
+
+/* Membus */
+#define CLKMGR_MEM_REQ					BIT(24)
+#define CLKMGR_MEM_WR					BIT(25)
+#define CLKMGR_MEM_ERR					BIT(26)
+#define CLKMGR_MEM_WDAT_OFFSET				16
+#define CLKMGR_MEM_ADDR					0x4027
+#define CLKMGR_MEM_WDAT					0x80
+
+/* Clock Manager Macros */
+#define CLKMGR_CTRL_BOOTMODE_SET_MSK			0x00000001
+#define CLKMGR_STAT_BUSY_E_BUSY				0x1
+#define CLKMGR_STAT_BUSY(x)				(((x) & 0x00000001) >> 0)
+#define CLKMGR_STAT_MAINPLLLOCKED(x)			(((x) & 0x00000100) >> 8)
+#define CLKMGR_STAT_PERPLLLOCKED(x)			(((x) & 0x00010000) >> 16)
+#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK		0x00000004
+#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK		0x00000008
+#define CLKMGR_INTOSC_HZ				460000000
+
+/* Main PLL Macros */
+#define CLKMGR_MAINPLL_EN_RESET				0x0000005e
+#define CLKMGR_MAINPLL_ENS_RESET			0x0000005e
+
+/* Peripheral PLL Macros */
+#define CLKMGR_PERPLL_EN_RESET				0x040007FF
+#define CLKMGR_PERPLL_ENS_RESET			0x040007FF
+
+#define CLKMGR_PERPLL_EN_SDMMCCLK			BIT(5)
+#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)		(((x) << 0) & 0x0000ffff)
+
+/* Altera Macros */
+#define CLKMGR_ALTERA_EXTCNTRST_RESET			0xff
+
+/* Shared Macros */
+#define CLKMGR_PSRC(x)					(((x) & 0x00030000) >> 16)
+#define CLKMGR_PSRC_MAIN				0
+#define CLKMGR_PSRC_PER					1
+
+#define CLKMGR_PLLGLOB_PSRC_EOSC1			0x0
+#define CLKMGR_PLLGLOB_PSRC_INTOSC			0x1
+#define CLKMGR_PLLGLOB_PSRC_F2S				0x2
+
+#define CLKMGR_PLLM_MDIV(x)				((x) & 0x000003ff)
+#define CLKMGR_PLLGLOB_PD_SET_MSK			0x00000001
+#define CLKMGR_PLLGLOB_RST_SET_MSK			0x00000002
+
+#define CLKMGR_PLLGLOB_REFCLKDIV(x)			(((x) & 0x00003f00) >> 8)
+#define CLKMGR_PLLGLOB_AREFCLKDIV(x)			(((x) & 0x00000f00) >> 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV(x)			(((x) & 0x00003000) >> 12)
+
+#define CLKMGR_VCOCALIB_HSCNT_SET(x)			(((x) << 0) & 0x000003ff)
+#define CLKMGR_VCOCALIB_MSCNT_SET(x)			(((x) << 16) & 0x00ff0000)
+
+#define CLKMGR_CLR_LOSTLOCK_BYPASS			0x20000000
+
+typedef struct {
+	uint32_t  clk_freq_of_eosc1;
+	uint32_t  clk_freq_of_f2h_free;
+	uint32_t  clk_freq_of_cb_intosc_ls;
+} CLOCK_SOURCE_CONFIG;
+
+void config_clkmgr_handoff(handoff *hoff_ptr);
+uint32_t get_wdt_clk(void);
+uint32_t get_uart_clk(void);
+uint32_t get_mmc_clk(void);
+
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_memory_controller.h b/plat/intel/soc/agilex5/include/agilex5_memory_controller.h
new file mode 100644
index 0000000..1708488
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_memory_controller.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGX_MEMORYCONTROLLER_H
+#define AGX_MEMORYCONTROLLER_H
+
+#include "socfpga_plat_def.h"
+
+#define AGX_MPFE_IOHMC_REG_DRAMADDRW				0xf80100a8
+#define AGX_MPFE_IOHMC_CTRLCFG0					0xf8010028
+#define AGX_MPFE_IOHMC_CTRLCFG1					0xf801002c
+#define AGX_MPFE_IOHMC_CTRLCFG2					0xf8010030
+#define AGX_MPFE_IOHMC_CTRLCFG3					0xf8010034
+#define AGX_MPFE_IOHMC_DRAMADDRW				0xf80100a8
+#define AGX_MPFE_IOHMC_DRAMTIMING0				0xf8010050
+#define AGX_MPFE_IOHMC_CALTIMING0				0xf801007c
+#define AGX_MPFE_IOHMC_CALTIMING1				0xf8010080
+#define AGX_MPFE_IOHMC_CALTIMING2				0xf8010084
+#define AGX_MPFE_IOHMC_CALTIMING3				0xf8010088
+#define AGX_MPFE_IOHMC_CALTIMING4				0xf801008c
+#define AGX_MPFE_IOHMC_CALTIMING9				0xf80100a0
+#define AGX_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT(x)			(((x) & 0x000000ff) >> 0)
+#define AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value)		(((value) & 0x00000060) >> 5)
+
+#define AGX_MPFE_HMC_ADP_ECCCTRL1				0xf8011100
+#define AGX_MPFE_HMC_ADP_ECCCTRL2				0xf8011104
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT			0xf8011218
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE		0x000000ff
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL			0xf8011214
+
+
+#define AGX_MPFE_IOHMC_REG_CTRLCFG1				0xf801002c
+
+#define AGX_MPFE_IOHMC_REG_NIOSRESERVE0_OFST			0xf8010110
+
+#define IOHMC_DRAMADDRW_COL_ADDR_WIDTH(x)			(((x) & 0x0000001f) >> 0)
+#define IOHMC_DRAMADDRW_ROW_ADDR_WIDTH(x)			(((x) & 0x000003e0) >> 5)
+#define IOHMC_DRAMADDRW_CS_ADDR_WIDTH(x)			(((x) & 0x00070000) >> 16)
+#define IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH(x)			(((x) & 0x0000c000) >> 14)
+#define IOHMC_DRAMADDRW_BANK_ADDR_WIDTH(x)			(((x) & 0x00003c00) >> 10)
+
+#define AGX_MPFE_DDR(x)						(0xf8000000 + x)
+#define AGX_MPFE_HMC_ADP_DDRCALSTAT				0xf801100c
+#define AGX_MPFE_DDR_MAIN_SCHED					0xf8000400
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRCONF				0xf8000408
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRTIMING			0xf800040c
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK			0x0000001f
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRMODE				0xf8000410
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV			0xf800043c
+#define AGX_MPFE_DDR_MAIN_SCHED_READLATENCY			0xf8000414
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE			0xf8000438
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST		10
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST		4
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST		0
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET(x)			(((x) << 0) & 0x0000001f)
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST		0
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK		(BIT(0) | BIT(1))
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST		2
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK		(BIT(2) | BIT(3))
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST		4
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK		(BIT(4) | BIT(5))
+
+#define AGX_MPFE_HMC_ADP(x)					(0xf8011000 + (x))
+#define AGX_MPFE_HMC_ADP_HPSINTFCSEL				0xf8011210
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL				0xf8011008
+#define HMC_ADP_DDRIOCTRL					0x8
+#define HMC_ADP_DDRIOCTRL_IO_SIZE(x)				(((x) & 0x00000003) >> 0)
+#define HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH(x)			(((x) & 0x00003e00) >> 9)
+#define ADP_DRAMADDRWIDTH					0xe0
+
+#define ACT_TO_ACT_DIFF_BANK(value)				(((value) & 0x00fc0000) >> 18)
+#define ACT_TO_ACT(value)					(((value) & 0x0003f000) >> 12)
+#define ACT_TO_RDWR(value)					(((value) & 0x0000003f) >> 0)
+#define ACT_TO_ACT(value)					(((value) & 0x0003f000) >> 12)
+
+/* timing 2 */
+#define RD_TO_RD_DIFF_CHIP(value)				(((value) & 0x00000fc0) >> 6)
+#define RD_TO_WR_DIFF_CHIP(value)				(((value) & 0x3f000000) >> 24)
+#define RD_TO_WR(value)						(((value) & 0x00fc0000) >> 18)
+#define RD_TO_PCH(value)					(((value) & 0x00000fc0) >> 6)
+
+/* timing 3 */
+#define CALTIMING3_WR_TO_RD_DIFF_CHIP(value)			(((value) & 0x0003f000) >> 12)
+#define CALTIMING3_WR_TO_RD(value)				(((value) & 0x00000fc0) >> 6)
+
+/* timing 4 */
+#define PCH_TO_VALID(value)					(((value) & 0x00000fc0) >> 6)
+
+#define DDRTIMING_BWRATIO_OFST					31
+#define DDRTIMING_WRTORD_OFST					26
+#define DDRTIMING_RDTOWR_OFST					21
+#define DDRTIMING_BURSTLEN_OFST					18
+#define DDRTIMING_WRTOMISS_OFST					12
+#define DDRTIMING_RDTOMISS_OFST					6
+#define DDRTIMING_ACTTOACT_OFST					0
+
+#define ADP_DDRIOCTRL_IO_SIZE(x)				(((x) & 0x3) >> 0)
+
+#define DDRMODE_AUTOPRECHARGE_OFST				1
+#define DDRMODE_BWRATIOEXTENDED_OFST				0
+
+
+#define AGX_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL(x)		(((x) & 0x7f) >> 0)
+#define AGX_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE(x)		(((x) & 0x0f) >> 0)
+
+#define AGX_CCU_CPU0_MPRT_DDR					0xf7004400
+#define AGX_CCU_CPU0_MPRT_MEM0					0xf70045c0
+#define AGX_CCU_CPU0_MPRT_MEM1A					0xf70045e0
+#define AGX_CCU_CPU0_MPRT_MEM1B					0xf7004600
+#define AGX_CCU_CPU0_MPRT_MEM1C					0xf7004620
+#define AGX_CCU_CPU0_MPRT_MEM1D					0xf7004640
+#define AGX_CCU_CPU0_MPRT_MEM1E					0xf7004660
+#define AGX_CCU_IOM_MPRT_MEM0					0xf7018560
+#define AGX_CCU_IOM_MPRT_MEM1A					0xf7018580
+#define	AGX_CCU_IOM_MPRT_MEM1B					0xf70185a0
+#define	AGX_CCU_IOM_MPRT_MEM1C					0xf70185c0
+#define	AGX_CCU_IOM_MPRT_MEM1D					0xf70185e0
+#define	AGX_CCU_IOM_MPRT_MEM1E					0xf7018600
+
+#define AGX_NOC_FW_DDR_SCR					0xf8020200
+#define AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT		0xf802021c
+#define AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT			0xf8020218
+#define AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT		0xf802029c
+#define AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT		0xf8020298
+
+#define AGX_SOC_NOC_FW_DDR_SCR_ENABLE				0xf8020200
+#define AGX_SOC_NOC_FW_DDR_SCR_ENABLESET			0xf8020204
+#define AGX_CCU_NOC_DI_SET_MSK					0x10
+
+#define AGX_SYSMGR_CORE_HMC_CLK					0xffd120b4
+#define AGX_SYSMGR_CORE_HMC_CLK_STATUS				0x00000001
+
+#define AGX_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0(x)		(((x) & 0xffff) >> 0)
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_MSK			0x00000003
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_OFST			0
+#define AGX_MPFE_HMC_ADP_HPSINTFCSEL_ENABLE			0x001f1f1f
+#define AGX_IOHMC_CTRLCFG1_ENABLE_ECC_OFST			7
+
+#define AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK	0x00010000
+#define AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK		0x00000100
+#define AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK		0x00000001
+
+#define AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK		0x00000001
+#define AGX_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK	0x00010000
+#define AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK		0x00000100
+#define AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(value)			(((value) & 0x1) >> 0)
+
+
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE(x)			(((x) & 0x00003) >> 0)
+#define IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH(x)			(((x) & 0x03c00) >> 10)
+#define IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH(x)		(((x) & 0x0c000) >> 14)
+#define IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH(x)			(((x) & 0x0001f) >> 0)
+#define IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH(x)			(((x) & 0x70000) >> 16)
+#define IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH(x)			(((x) & 0x003e0) >> 5)
+
+#define AGX_SDRAM_0_LB_ADDR					0x0
+#define AGX_DDR_SIZE						0x40000000
+
+/* Macros */
+#define SOCFPGA_MEMCTRL_ECCCTRL1				0x008
+#define SOCFPGA_MEMCTRL_ERRINTEN				0x010
+#define SOCFPGA_MEMCTRL_ERRINTENS				0x014
+#define SOCFPGA_MEMCTRL_ERRINTENR				0x018
+#define SOCFPGA_MEMCTRL_INTMODE					0x01C
+#define SOCFPGA_MEMCTRL_INTSTAT					0x020
+#define SOCFPGA_MEMCTRL_DIAGINTTEST				0x024
+#define SOCFPGA_MEMCTRL_DERRADDRA				0x02C
+
+#define SOCFPGA_MEMCTRL(_reg)					(SOCFPGA_MEMCTRL_REG_BASE \
+								+ (SOCFPGA_MEMCTRL_##_reg))
+
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_mmc.h b/plat/intel/soc/agilex5/include/agilex5_mmc.h
new file mode 100644
index 0000000..c8a5fba
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_mmc.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+void agx5_mmc_init(void);
diff --git a/plat/intel/soc/agilex5/include/agilex5_pinmux.h b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
new file mode 100644
index 0000000..8a8e8c7
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGX5_PINMUX_H
+#define AGX5_PINMUX_H
+
+/* PINMUX REGISTER ADDRESS */
+#define AGX5_PINMUX_PIN0SEL					0x10d13000
+#define AGX5_PINMUX_IO0CTRL					0x10d13130
+#define AGX5_PINMUX_EMAC0_USEFPGA				0x10d13300
+#define AGX5_PINMUX_IO0_DELAY					0x10d13400
+#define AGX5_PERIPHERAL						0x10d14044
+
+#include "socfpga_handoff.h"
+
+/* PINMUX DEFINE */
+#define PINMUX_HANDOFF_ARRAY_SIZE(x)				(sizeof(x) / sizeof((x)[0]))
+#define PINMUX_HANDOFF_CONFIG_ADDR				0xbeec
+#define PINMUX_HANDOFF_CONFIG_VAL				0x7e000
+
+/* Macros */
+#define SOCFPGA_PINMUX_SEL_NAND					(0x03)
+#define SOCFPGA_PINMUX_PIN0SEL					(0x00)
+#define SOCFPGA_PINMUX_PIN1SEL					(0x04)
+#define SOCFPGA_PINMUX_PIN2SEL					(0x08)
+#define SOCFPGA_PINMUX_PIN3SEL					(0x0C)
+#define SOCFPGA_PINMUX_PIN4SEL					(0x10)
+#define SOCFPGA_PINMUX_PIN5SEL					(0x14)
+#define SOCFPGA_PINMUX_PIN6SEL					(0x18)
+#define SOCFPGA_PINMUX_PIN7SEL					(0x1C)
+#define SOCFPGA_PINMUX_PIN8SEL					(0x20)
+#define SOCFPGA_PINMUX_PIN9SEL					(0x24)
+#define SOCFPGA_PINMUX_PIN10SEL					(0x28)
+#define SOCFPGA_PINMUX_PIN11SEL					(0x2C)
+#define SOCFPGA_PINMUX_PIN12SEL					(0x30)
+#define SOCFPGA_PINMUX_PIN13SEL					(0x34)
+#define SOCFPGA_PINMUX_PIN14SEL					(0x38)
+#define SOCFPGA_PINMUX_PIN15SEL					(0x3C)
+#define SOCFPGA_PINMUX_PIN16SEL					(0x40)
+#define SOCFPGA_PINMUX_PIN17SEL					(0x44)
+#define SOCFPGA_PINMUX_PIN18SEL					(0x48)
+#define SOCFPGA_PINMUX_PIN19SEL					(0x4C)
+#define SOCFPGA_PINMUX_PIN20SEL					(0x50)
+#define SOCFPGA_PINMUX_PIN21SEL					(0x54)
+#define SOCFPGA_PINMUX_PIN22SEL					(0x58)
+#define SOCFPGA_PINMUX_PIN23SEL					(0x5C)
+#define SOCFPGA_PINMUX_PIN24SEL					(0x60)
+#define SOCFPGA_PINMUX_PIN25SEL					(0x64)
+#define SOCFPGA_PINMUX_PIN26SEL					(0x68)
+#define SOCFPGA_PINMUX_PIN27SEL					(0x6C)
+#define SOCFPGA_PINMUX_PIN28SEL					(0x70)
+#define SOCFPGA_PINMUX_PIN29SEL					(0x74)
+#define SOCFPGA_PINMUX_PIN30SEL					(0x78)
+#define SOCFPGA_PINMUX_PIN31SEL					(0x7C)
+#define SOCFPGA_PINMUX_PIN32SEL					(0x80)
+#define SOCFPGA_PINMUX_PIN33SEL					(0x84)
+#define SOCFPGA_PINMUX_PIN34SEL					(0x88)
+#define SOCFPGA_PINMUX_PIN35SEL					(0x8C)
+#define SOCFPGA_PINMUX_PIN36SEL					(0x90)
+#define SOCFPGA_PINMUX_PIN37SEL					(0x94)
+#define SOCFPGA_PINMUX_PIN38SEL					(0x98)
+#define SOCFPGA_PINMUX_PIN39SEL					(0x9C)
+#define SOCFPGA_PINMUX_PIN40SEL					(0x100)
+#define SOCFPGA_PINMUX_PIN41SEL					(0x104)
+#define SOCFPGA_PINMUX_PIN42SEL					(0x108)
+#define SOCFPGA_PINMUX_PIN43SEL					(0x10C)
+#define SOCFPGA_PINMUX_PIN44SEL					(0x110)
+#define SOCFPGA_PINMUX_PIN45SEL					(0x114)
+#define SOCFPGA_PINMUX_PIN46SEL					(0x118)
+#define SOCFPGA_PINMUX_PIN47SEL					(0x11C)
+
+#define SOCFPGA_PINMUX_IO0CTRL					(0x00)
+#define SOCFPGA_PINMUX_IO1CTRL					(0x04)
+#define SOCFPGA_PINMUX_IO2CTRL					(0x08)
+#define SOCFPGA_PINMUX_IO3CTRL					(0x0C)
+#define SOCFPGA_PINMUX_IO4CTRL					(0x10)
+#define SOCFPGA_PINMUX_IO5CTRL					(0x14)
+#define SOCFPGA_PINMUX_IO6CTRL					(0x18)
+#define SOCFPGA_PINMUX_IO7CTRL					(0x1C)
+#define SOCFPGA_PINMUX_IO8CTRL					(0x20)
+#define SOCFPGA_PINMUX_IO9CTRL					(0x24)
+#define SOCFPGA_PINMUX_IO10CTRL					(0x28)
+#define SOCFPGA_PINMUX_IO11CTRL					(0x2C)
+#define SOCFPGA_PINMUX_IO12CTRL					(0x30)
+#define SOCFPGA_PINMUX_IO13CTRL					(0x34)
+#define SOCFPGA_PINMUX_IO14CTRL					(0x38)
+#define SOCFPGA_PINMUX_IO15CTRL					(0x3C)
+#define SOCFPGA_PINMUX_IO16CTRL					(0x40)
+#define SOCFPGA_PINMUX_IO17CTRL					(0x44)
+#define SOCFPGA_PINMUX_IO18CTRL					(0x48)
+#define SOCFPGA_PINMUX_IO19CTRL					(0x4C)
+#define SOCFPGA_PINMUX_IO20CTRL					(0x50)
+#define SOCFPGA_PINMUX_IO21CTRL					(0x54)
+#define SOCFPGA_PINMUX_IO22CTRL					(0x58)
+#define SOCFPGA_PINMUX_IO23CTRL					(0x5C)
+#define SOCFPGA_PINMUX_IO24CTRL					(0x60)
+#define SOCFPGA_PINMUX_IO25CTRL					(0x64)
+#define SOCFPGA_PINMUX_IO26CTRL					(0x68)
+#define SOCFPGA_PINMUX_IO27CTRL					(0x6C)
+#define SOCFPGA_PINMUX_IO28CTRL					(0xD0)
+#define SOCFPGA_PINMUX_IO29CTRL					(0xD4)
+#define SOCFPGA_PINMUX_IO30CTRL					(0xD8)
+#define SOCFPGA_PINMUX_IO31CTRL					(0xDC)
+#define SOCFPGA_PINMUX_IO32CTRL					(0xE0)
+#define SOCFPGA_PINMUX_IO33CTRL					(0xE4)
+#define SOCFPGA_PINMUX_IO34CTRL					(0xE8)
+#define SOCFPGA_PINMUX_IO35CTRL					(0xEC)
+#define SOCFPGA_PINMUX_IO36CTRL					(0xF0)
+#define SOCFPGA_PINMUX_IO37CTRL					(0xF4)
+#define SOCFPGA_PINMUX_IO38CTRL					(0xF8)
+#define SOCFPGA_PINMUX_IO39CTRL					(0xFC)
+#define SOCFPGA_PINMUX_IO40CTRL					(0x100)
+#define SOCFPGA_PINMUX_IO41CTRL					(0x104)
+#define SOCFPGA_PINMUX_IO42CTRL					(0x108)
+#define SOCFPGA_PINMUX_IO43CTRL					(0x10C)
+#define SOCFPGA_PINMUX_IO44CTRL					(0x110)
+#define SOCFPGA_PINMUX_IO45CTRL					(0x114)
+#define SOCFPGA_PINMUX_IO46CTRL					(0x118)
+#define SOCFPGA_PINMUX_IO47CTRL					(0x11C)
+
+#define SOCFPGA_PINMUX_EMAC0_USEFPGA				(0x00)
+#define SOCFPGA_PINMUX_EMAC1_USEFPGA				(0x04)
+#define SOCFPGA_PINMUX_EMAC2_USEFPGA				(0x08)
+#define SOCFPGA_PINMUX_I2C0_USEFPGA				(0x0C)
+#define SOCFPGA_PINMUX_I2C1_USEFPGA				(0x10)
+#define SOCFPGA_PINMUX_I2C_EMAC0_USEFPGA			(0x14)
+#define SOCFPGA_PINMUX_I2C_EMAC1_USEFPGA			(0x18)
+#define SOCFPGA_PINMUX_I2C_EMAC2_USEFPGA			(0x1C)
+#define SOCFPGA_PINMUX_NAND_USEFPGA				(0x20)
+#define SOCFPGA_PINMUX_SPIM0_USEFPGA				(0x28)
+#define SOCFPGA_PINMUX_SPIM1_USEFPGA				(0x2C)
+#define SOCFPGA_PINMUX_SPIS0_USEFPGA				(0x30)
+#define SOCFPGA_PINMUX_SPIS1_USEFPGA				(0x34)
+#define SOCFPGA_PINMUX_UART0_USEFPGA				(0x38)
+#define SOCFPGA_PINMUX_UART1_USEFPGA				(0x3C)
+#define SOCFPGA_PINMUX_MDIO0_USEFPGA				(0x40)
+#define SOCFPGA_PINMUX_MDIO1_USEFPGA				(0x44)
+#define SOCFPGA_PINMUX_MDIO2_USEFPGA				(0x48)
+#define SOCFPGA_PINMUX_JTAG_USEFPGA				(0x50)
+#define SOCFPGA_PINMUX_SDMMC_USEFPGA				(0x54)
+
+#define SOCFPGA_PINMUX_IO0DELAY					(0x00)
+#define SOCFPGA_PINMUX_IO1DELAY					(0x04)
+#define SOCFPGA_PINMUX_IO2DELAY					(0x08)
+#define SOCFPGA_PINMUX_IO3DELAY					(0x0C)
+#define SOCFPGA_PINMUX_IO4DELAY					(0x10)
+#define SOCFPGA_PINMUX_IO5DELAY					(0x14)
+#define SOCFPGA_PINMUX_IO6DELAY					(0x18)
+#define SOCFPGA_PINMUX_IO7DELAY					(0x1C)
+#define SOCFPGA_PINMUX_IO8DELAY					(0x20)
+#define SOCFPGA_PINMUX_IO9DELAY					(0x24)
+#define SOCFPGA_PINMUX_IO10DELAY				(0x28)
+#define SOCFPGA_PINMUX_IO11DELAY				(0x2C)
+#define SOCFPGA_PINMUX_IO12DELAY				(0x30)
+#define SOCFPGA_PINMUX_IO13DELAY				(0x34)
+#define SOCFPGA_PINMUX_IO14DELAY				(0x38)
+#define SOCFPGA_PINMUX_IO15DELAY				(0x3C)
+#define SOCFPGA_PINMUX_IO16DELAY				(0x40)
+#define SOCFPGA_PINMUX_IO17DELAY				(0x44)
+#define SOCFPGA_PINMUX_IO18DELAY				(0x48)
+#define SOCFPGA_PINMUX_IO19DELAY				(0x4C)
+#define SOCFPGA_PINMUX_IO20DELAY				(0x50)
+#define SOCFPGA_PINMUX_IO21DELAY				(0x54)
+#define SOCFPGA_PINMUX_IO22DELAY				(0x58)
+#define SOCFPGA_PINMUX_IO23DELAY				(0x5C)
+#define SOCFPGA_PINMUX_IO24DELAY				(0x60)
+#define SOCFPGA_PINMUX_IO25DELAY				(0x64)
+#define SOCFPGA_PINMUX_IO26DELAY				(0x68)
+#define SOCFPGA_PINMUX_IO27DELAY				(0x6C)
+#define SOCFPGA_PINMUX_IO28DELAY				(0x70)
+#define SOCFPGA_PINMUX_IO29DELAY				(0x74)
+#define SOCFPGA_PINMUX_IO30DELAY				(0x78)
+#define SOCFPGA_PINMUX_IO31DELAY				(0x7C)
+#define SOCFPGA_PINMUX_IO32DELAY				(0x80)
+#define SOCFPGA_PINMUX_IO33DELAY				(0x84)
+#define SOCFPGA_PINMUX_IO34DELAY				(0x88)
+#define SOCFPGA_PINMUX_IO35DELAY				(0x8C)
+#define SOCFPGA_PINMUX_IO36DELAY				(0x90)
+#define SOCFPGA_PINMUX_IO37DELAY				(0x94)
+#define SOCFPGA_PINMUX_IO38DELAY				(0x98)
+#define SOCFPGA_PINMUX_IO39DELAY				(0x9C)
+#define SOCFPGA_PINMUX_IO40DELAY				(0xA0)
+#define SOCFPGA_PINMUX_IO41DELAY				(0xA4)
+#define SOCFPGA_PINMUX_IO42DELAY				(0xA8)
+#define SOCFPGA_PINMUX_IO43DELAY				(0xAC)
+#define SOCFPGA_PINMUX_IO44DELAY				(0xB0)
+#define SOCFPGA_PINMUX_IO45DELAY				(0xB4)
+#define SOCFPGA_PINMUX_IO46DELAY				(0xB8)
+#define SOCFPGA_PINMUX_IO47DELAY				(0xBC)
+
+#define SOCFPGA_PINMUX_I3C0_USEFPGA				(0xC0)
+#define SOCFPGA_PINMUX_I3C1_USEFPGA				(0xC4)
+
+#define SOCFPGA_PINMUX(_reg)					(SOCFPGA_PINMUX_REG_BASE \
+								+ (SOCFPGA_PINMUX_##_reg))
+
+void config_pinmux(handoff *handoff);
+void config_peripheral(handoff *handoff);
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_power_manager.h b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
new file mode 100644
index 0000000..1bba74b
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POWERMANAGER_H
+#define POWERMANAGER_H
+
+#include "socfpga_handoff.h"
+
+#define AGX5_PWRMGR_BASE					0x10d14000
+
+/* DSU */
+#define AGX5_PWRMGR_DSU_FWENCTL					0x0
+#define AGX5_PWRMGR_DSU_PGENCTL					0x4
+#define AGX5_PWRMGR_DSU_PGSTAT					0x8
+#define AGX5_PWRMGR_DSU_PWRCTLR					0xc
+#define AGX5_PWRMGR_DSU_PWRSTAT0				0x10
+#define AGX5_PWRMGR_DSU_PWRSTAT1				0x14
+
+/* DSU Macros*/
+#define AGX5_PWRMGR_DSU_FWEN(x)					((x) & 0xf)
+#define AGX5_PWRMGR_DSU_PGEN(x)					((x) & 0xf)
+#define AGX5_PWRMGR_DSU_PGEN_OUT(x)				((x) & 0xf)
+#define AGX5_PWRMGR_DSU_SINGLE_PACCEPT(x)			((x) & 0x1)
+#define AGX5_PWRMGR_DSU_SINGLE_PDENY(x)				(((x) & 0x1) << 1)
+#define AGX5_PWRMGR_DSU_SINGLE_FSM_STATE(x)			(((x) & 0xff) << 8)
+#define AGX5_PWRMGR_DSU_SINGLE_PCH_DONE(x)			(((x) & 0x1) << 31)
+#define AGX5_PWRMGR_DSU_MULTI_PACTIVE_IN(x)			((x) & 0xff)
+#define AGX5_PWRMGR_DSU_MULTI_PACCEPT(x)			(((x) & 0xff) << 8)
+#define AGX5_PWRMGR_DSU_MULTI_PDENY(x)				(((x) & 0xff) << 16)
+#define AGX5_PWRMGR_DSU_MULTI_PCH_DONE(x)			(((x) & 0x1) << 31)
+
+/* CPU */
+#define AGX5_PWRMGR_CPU_PWRCTLR0				0x18
+#define AGX5_PWRMGR_CPU_PWRCTLR1				0x20
+#define AGX5_PWRMGR_CPU_PWRCTLR2				0x28
+#define AGX5_PWRMGR_CPU_PWRCTLR3				0x30
+#define AGX5_PWRMGR_CPU_PWRSTAT0				0x1c
+#define AGX5_PWRMGR_CPU_PWRSTAT1				0x24
+#define AGX5_PWRMGR_CPU_PWRSTAT2				0x2c
+#define AGX5_PWRMGR_CPU_PWRSTAT3				0x34
+
+/* APS */
+#define AGX5_PWRMGR_APS_FWENCTL					0x38
+#define AGX5_PWRMGR_APS_PGENCTL					0x3C
+#define AGX5_PWRMGR_APS_PGSTAT					0x40
+
+/* PSS */
+#define AGX5_PWRMGR_PSS_FWENCTL					0x44
+#define AGX5_PWRMGR_PSS_PGENCTL					0x48
+#define AGX5_PWRMGR_PSS_PGSTAT					0x4c
+
+/* PSS Macros*/
+#define AGX5_PWRMGR_PSS_FWEN(x)					((x) & 0xff)
+#define AGX5_PWRMGR_PSS_PGEN(x)					((x) & 0xff)
+#define AGX5_PWRMGR_PSS_PGEN_OUT(x)				((x) & 0xff)
+
+/* MPU */
+#define AGX5_PWRMGR_MPU_PCHCTLR					0x50
+#define AGX5_PWRMGR_MPU_PCHSTAT					0x54
+#define AGX5_PWRMGR_MPU_BOOTCONFIG				0x58
+#define AGX5_PWRMGR_CPU_POWER_STATE_MASK			0x1E
+
+/* MPU Macros*/
+#define AGX5_PWRMGR_MPU_TRIGGER_PCH_DSU(x)			((x) & 0x1)
+#define AGX5_PWRMGR_MPU_TRIGGER_PCH_CPU(x)			(((x) & 0xf) << 1)
+#define AGX5_PWRMGR_MPU_STATUS_PCH_CPU(x)			(((x) & 0xf) << 1)
+
+/* Shared Macros */
+#define AGX5_PWRMGR(_reg)					(AGX5_PWRMGR_BASE + \
+								(AGX5_PWRMGR_##_reg))
+
+/* POWER MANAGER ERROR CODE */
+#define AGX5_PWRMGR_HANDOFF_PERIPHERAL				-1
+#define AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY			0x0
+#define AGX5_PWRMGR_PSS_STAT_BUSY(x)				(((x) & 0x000000FF) >> 0)
+
+int pss_sram_power_off(handoff *hoff_ptr);
+int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff);
+
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_system_manager.h b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
new file mode 100644
index 0000000..9a58cdb
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef AGX5_SOCFPGA_SYSTEMMANAGER_H
+#define AGX5_SOCFPGA_SYSTEMMANAGER_H
+
+#include "socfpga_plat_def.h"
+
+/* System Manager Register Map */
+#define SOCFPGA_SYSMGR_SILICONID_1					0x00
+#define SOCFPGA_SYSMGR_SILICONID_2					0x04
+#define SOCFPGA_SYSMGR_WDDBG						0x08
+#define SOCFPGA_SYSMGR_MPU_STATUS					0x10
+#define SOCFPGA_SYSMGR_SDMMC_L3_MASTER					0x2C
+#define SOCFPGA_SYSMGR_NAND_L3_MASTER					0x34
+#define SOCFPGA_SYSMGR_USB0_L3_MASTER					0x38
+#define SOCFPGA_SYSMGR_USB1_L3_MASTER					0x3C
+#define SOCFPGA_SYSMGR_TSN_GLOBAL					0x40
+#define SOCFPGA_SYSMGR_EMAC_0						0x44 /* TSN_0 */
+#define SOCFPGA_SYSMGR_EMAC_1						0x48 /* TSN_1 */
+#define SOCFPGA_SYSMGR_EMAC_2						0x4C /* TSN_2 */
+#define SOCFPGA_SYSMGR_TSN_0_ACE					0x50
+#define SOCFPGA_SYSMGR_TSN_1_ACE					0x54
+#define SOCFPGA_SYSMGR_TSN_2_ACE					0x58
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_1					0x68
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2					0x6C
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3					0x70
+#define SOCFPGA_SYSMGR_DMAC0_L3_MASTER					0x74
+#define SOCFPGA_SYSMGR_ETR_L3_MASTER					0x78
+#define SOCFPGA_SYSMGR_DMAC1_L3_MASTER					0x7C
+#define SOCFPGA_SYSMGR_SEC_CTRL_SLT					0x80
+#define SOCFPGA_SYSMGR_OSC_TRIM						0x84
+#define SOCFPGA_SYSMGR_DMAC0_CTRL_STATUS_REG				0x88
+#define SOCFPGA_SYSMGR_DMAC1_CTRL_STATUS_REG				0x8C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_VALUE				0x90
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SET					0x94
+#define SOCFPGA_SYSMGR_ECC_INTMASK_CLR					0x98
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SERR					0x9C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_DERR					0xA0
+/* NOC configuration value */
+#define SOCFPGA_SYSMGR_NOC_TIMEOUT					0xC0
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET					0xC4
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR					0xC8
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL					0xCC
+#define SOCFPGA_SYSMGR_NOC_IDLEACK					0xD0
+#define SOCFPGA_SYSMGR_NOC_IDLESTATUS					0xD4
+#define SOCFPGA_SYSMGR_FPGA2SOC_CTRL					0xD8
+#define SOCFPGA_SYSMGR_FPGA_CFG						0xDC
+#define SOCFPGA_SYSMGR_GPO						0xE4
+#define SOCFPGA_SYSMGR_GPI						0xE8
+#define SOCFPGA_SYSMGR_MPU						0xF0
+#define SOCFPGA_SYSMGR_SDM_HPS_SPARE					0xF4
+#define SOCFPGA_SYSMGR_HPS_SDM_SPARE					0xF8
+#define SOCFPGA_SYSMGR_DFI_INTF						0xFC
+#define SOCFPGA_SYSMGR_NAND_DD_CTRL					0x100
+#define SOCFPGA_SYSMGR_NAND_PHY_CTRL_REG				0x104
+#define SOCFPGA_SYSMGR_NAND_PHY_TSEL_REG				0x108
+#define SOCFPGA_SYSMGR_NAND_DQ_TIMING_REG				0x10C
+#define SOCFPGA_SYSMGR_PHY_DQS_TIMING_REG				0x110
+#define SOCFPGA_SYSMGR_NAND_PHY_GATE_LPBK_CTRL_REG			0x114
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_MASTER_CTRL_REG			0x118
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_SLAVE_CTRL_REG			0x11C
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG0			0x120
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG1			0x124
+#define SOCFPGA_SYSMGR_NAND_DD_STATUS_REG				0x128
+#define SOCFPGA_SYSMGR_NAND_DD_ID_LOW_REG				0x12C
+#define SOCFPGA_SYSMGR_NAND_DD_ID_HIGH_REG				0x130
+#define SOCFPGA_SYSMGR_NAND_WRITE_PROT_EN_REG				0x134
+#define SOCFPGA_SYSMGR_SDMMC_CMD_QUEUE_SETTING_REG			0x138
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_LOW					0x13C
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_HIGH					0x140
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_0					0x144
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_1					0x148
+#define SOCFPGA_SYSMGR_F2S_BRIDGE_CTRL					0x14C
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA0			0x150
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA1			0x154
+#define SOCFPGA_SYSMGR_SDM_TBU_STASH_CTRL_REG_1_SDM			0x158
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB2			0x15C
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB3			0x160
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_SDMMC			0x164
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_NAND			0x168
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_ETR			0x16C
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN0			0x170
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN1			0x174
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN2			0x178
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA0			0x17C
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA1			0x180
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_CTRL_REG_1_SDM			0x184
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB2			0x188
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB3			0x18C
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_SDMMC			0x190
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_NAND			0x194
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_ETR			0x198
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN0			0x19C
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN1			0x1A0
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN2			0x1A4
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA0			0x1A8
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA1			0x1AC
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_ID_AX_REG_1_SDM			0x1B0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB2			0x1B4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB3			0x1B8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_SDMMC			0x1BC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_NAND			0x1C0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_ETR			0x1C4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN0			0x1C8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN1			0x1CC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN2			0x1D0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG0				0x1F0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG1				0x1F4
+
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0				0x200
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1				0x204
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2				0x208
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_3				0x20C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_4				0x210
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_5				0x214
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_6				0x218
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_7				0x21C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8				0x220
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9				0x224
+#define SOCFPGA_SYSMGR_MPFE_CONFIG					0x228
+#define SOCFPGA_SYSMGR_MPFE_status					0x22C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0				0x230
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1				0x234
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2				0x238
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_3				0x23C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_4				0x240
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_5				0x244
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_6				0x248
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_7				0x24C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_8				0x250
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_9				0x254
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0				0x258
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_1				0x25C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_2				0x260
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_3				0x264
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_4				0x268
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_5				0x26C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_6				0x270
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_7				0x274
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8				0x278
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9				0x27C
+
+#define DMA0_STREAM_CTRL_REG						0x10D1217C
+#define DMA1_STREAM_CTRL_REG						0x10D12180
+#define SDM_STREAM_CTRL_REG						0x10D12184
+#define USB2_STREAM_CTRL_REG						0x10D12188
+#define USB3_STREAM_CTRL_REG						0x10D1218C
+#define SDMMC_STREAM_CTRL_REG						0x10D12190
+#define NAND_STREAM_CTRL_REG						0x10D12194
+#define ETR_STREAM_CTRL_REG						0x10D12198
+#define TSN0_STREAM_CTRL_REG						0x10D1219C
+#define TSN1_STREAM_CTRL_REG						0x10D121A0
+#define TSN2_STREAM_CTRL_REG						0x10D121A4
+
+/* Stream ID configuration value for Agilex5 */
+#define TSN0								0x00010001
+#define TSN1								0x00020002
+#define TSN2								0x00030003
+#define NAND								0x00040004
+#define SDMMC								0x00050005
+#define USB0								0x00060006
+#define USB1								0x00070007
+#define DMA0								0x00080008
+#define DMA1								0x00090009
+#define SDM								0x000A000A
+#define CORE_SIGHT_DEBUG						0x000B000B
+
+/* Field Masking */
+#define SYSMGR_SDMMC_DRVSEL(x)						(((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x)						(((x) & 0x7) << 4)
+
+#define SYSMGR_F2S_BRIDGE_CTRL_EN					BIT(0)
+#define IDLE_DATA_LWSOC2FPGA						BIT(4)
+#define IDLE_DATA_SOC2FPGA						BIT(0)
+#define IDLE_DATA_MASK							(IDLE_DATA_LWSOC2FPGA \
+									| IDLE_DATA_SOC2FPGA)
+#define SYSMGR_ECC_OCRAM_MASK						BIT(1)
+#define SYSMGR_ECC_DDR0_MASK						BIT(16)
+#define SYSMGR_ECC_DDR1_MASK						BIT(17)
+
+#define WSTREAMIDEN_REG_CTRL						BIT(0)
+#define RSTREAMIDEN_REG_CTRL						BIT(1)
+#define WMMUSECSID_REG_VAL						BIT(4)
+#define RMMUSECSID_REG_VAL						BIT(5)
+
+/* Macros */
+#define SOCFPGA_SYSMGR(_reg)						(SOCFPGA_SYSMGR_REG_BASE \
+									+ (SOCFPGA_SYSMGR_##_reg))
+
+#define ENABLE_STREAMID							WSTREAMIDEN_REG_CTRL \
+									| RSTREAMIDEN_REG_CTRL
+#define ENABLE_STREAMID_SECURE_TX					WSTREAMIDEN_REG_CTRL \
+									| RSTREAMIDEN_REG_CTRL \
+									| WMMUSECSID_REG_VAL \
+									| RMMUSECSID_REG_VAL
+
+#endif /* AGX5_SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
new file mode 100644
index 0000000..8a49d61
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include "agilex5_memory_controller.h"
+#include "agilex5_system_manager.h"
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL						PLAT_SOCFPGA_AGILEX5
+#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+#define MMC_DEVICE_TYPE						1  /* MMC = 0, SD = 1 */
+#define XLAT_TABLES_V2						U(1)
+#define PLAT_PRIMARY_CPU_A55					0x000
+#define PLAT_PRIMARY_CPU_A76					0x200
+#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT				MPIDR_AFF2_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT				MPIDR_AFF1_SHIFT
+#define PLAT_L2_RESET_REQ			0xB007C0DE
+
+/* System Counter */ /* TODO: Update back to 400MHz */
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				(80000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				(80)
+
+/* FPGA config helpers */
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x2000000
+
+/* QSPI Setting */
+#define CAD_QSPIDATA_OFST					0x10900000
+#define CAD_QSPI_OFFSET						0x108d2000
+
+/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE				0x1c000000
+#define SOCFPGA_F2SDRAMMGR_REG_BASE				0x18001000
+
+#define SOCFPGA_MMC_REG_BASE					0x10808000
+#define SOCFPGA_MEMCTRL_REG_BASE				0x108CC000
+#define SOCFPGA_RSTMGR_REG_BASE					0x10d11000
+#define SOCFPGA_SYSMGR_REG_BASE					0x10d12000
+#define SOCFPGA_PINMUX_REG_BASE					0x10d13000
+#define SOCFPGA_NAND_REG_BASE					0x10B80000
+
+#define SOCFPGA_L4_PER_SCR_REG_BASE				0x10d21000
+#define SOCFPGA_L4_SYS_SCR_REG_BASE				0x10d21100
+#define SOCFPGA_SOC2FPGA_SCR_REG_BASE				0x10d21200
+#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE				0x10d21300
+
+/* Define maximum page size for NAND flash devices */
+#define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x1000)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define DRAM_BASE						(0x80000000)
+#define DRAM_SIZE						(0x80000000)
+
+#define OCRAM_BASE						(0x00000000)
+#define OCRAM_SIZE						(0x00080000)
+
+#define MEM64_BASE						(0x0080000000)
+#define MEM64_SIZE						(0x0080000000)
+
+//128MB PSS
+#define PSS_BASE						(0x10000000)
+#define PSS_SIZE						(0x08000000)
+
+//64MB MPFE
+#define MPFE_BASE						(0x18000000)
+#define MPFE_SIZE						(0x04000000)
+
+//16MB CCU
+#define CCU_BASE						(0x1C000000)
+#define CCU_SIZE						(0x01000000)
+
+//1MB GIC
+#define GIC_BASE						(0x1D000000)
+#define GIC_SIZE						(0x00100000)
+
+#define BL2_BASE						(0x00000000)
+#define BL2_LIMIT						(0x0001b000)
+
+#define BL31_BASE						(0x80000000)
+#define BL31_LIMIT						(0x82000000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define PLAT_UART0_BASE						(0x10C02000)
+#define PLAT_UART1_BASE						(0x10C02100)
+
+/*******************************************************************************
+ * GIC related constants
+ ******************************************************************************/
+#define PLAT_GIC_BASE						(0x1D000000)
+#define PLAT_GICC_BASE						(PLAT_GIC_BASE + 0x20000)
+#define PLAT_GICD_BASE						(PLAT_GIC_BASE + 0x00000)
+#define PLAT_GICR_BASE						(PLAT_GIC_BASE + 0x60000)
+
+#define PLAT_INTEL_SOCFPGA_GICR_BASE				PLAT_GICR_BASE
+
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	sdmmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	sdmmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0x10D12218
+
+#endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
new file mode 100644
index 0000000..779c629
--- /dev/null
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_INCLUDES		:=	\
+			-Iplat/intel/soc/agilex5/include/		\
+			-Iplat/intel/soc/common/drivers/		\
+			-Iplat/intel/soc/common/include/
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600	:=	1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+AGX5_GICv3_SOURCES	:=	\
+			${GICV3_SOURCES}				\
+			plat/common/plat_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	:=	\
+			${AGX5_GICv3_SOURCES}				\
+			drivers/cadence/combo_phy/cdns_combo_phy.c	\
+			drivers/cadence/emmc/cdns_sdmmc.c	\
+			drivers/cadence/nand/cdns_nand.c	\
+			drivers/delay_timer/delay_timer.c		\
+			drivers/delay_timer/generic_delay_timer.c	\
+			drivers/ti/uart/aarch64/16550_console.S		\
+			plat/intel/soc/common/aarch64/platform_common.c	\
+			plat/intel/soc/common/aarch64/plat_helpers.S	\
+			plat/intel/soc/common/drivers/ccu/ncore_ccu.c	\
+			plat/intel/soc/common/drivers/combophy/combophy.c			\
+			plat/intel/soc/common/drivers/sdmmc/sdmmc.c			\
+			plat/intel/soc/common/drivers/ddr/ddr.c			\
+			plat/intel/soc/common/drivers/nand/nand.c			\
+			plat/intel/soc/common/socfpga_delay_timer.c
+
+BL2_SOURCES		+=	\
+		common/desc_image_load.c				\
+		lib/xlat_tables_v2/aarch64/enable_mmu.S	\
+		lib/xlat_tables_v2/xlat_tables_context.c \
+		lib/xlat_tables_v2/xlat_tables_core.c \
+		lib/xlat_tables_v2/aarch64/xlat_tables_arch.c \
+		lib/xlat_tables_v2/xlat_tables_utils.c \
+		drivers/mmc/mmc.c					\
+		drivers/intel/soc/stratix10/io/s10_memmap_qspi.c	\
+		drivers/io/io_storage.c					\
+		drivers/io/io_block.c					\
+		drivers/io/io_fip.c					\
+		drivers/io/io_mtd.c					\
+		drivers/partition/partition.c				\
+		drivers/partition/gpt.c					\
+		drivers/synopsys/emmc/dw_mmc.c				\
+		lib/cpus/aarch64/cortex_a55.S				\
+		lib/cpus/aarch64/cortex_a76.S				\
+		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
+		plat/intel/soc/agilex5/soc/agilex5_memory_controller.c	\
+		plat/intel/soc/agilex5/soc/agilex5_mmc.c			\
+		plat/intel/soc/agilex5/soc/agilex5_pinmux.c		\
+		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
+		plat/intel/soc/common/socfpga_image_load.c		\
+		plat/intel/soc/common/socfpga_storage.c			\
+		plat/intel/soc/common/socfpga_vab.c				\
+		plat/intel/soc/common/soc/socfpga_emac.c		\
+		plat/intel/soc/common/soc/socfpga_firewall.c		\
+		plat/intel/soc/common/soc/socfpga_handoff.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
+		plat/intel/soc/common/soc/socfpga_reset_manager.c	\
+		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
+		plat/intel/soc/agilex5/bl2_plat_setup.c			\
+		plat/intel/soc/common/drivers/wdt/watchdog.c
+
+include lib/zlib/zlib.mk
+PLAT_INCLUDES	+=	-Ilib/zlib
+BL2_SOURCES	+=	$(ZLIB_SOURCES)
+
+BL31_SOURCES	+=	\
+		drivers/arm/cci/cci.c					\
+		${XLAT_TABLES_LIB_SRCS}						\
+		lib/cpus/aarch64/aem_generic.S				\
+		lib/cpus/aarch64/cortex_a55.S				\
+		lib/cpus/aarch64/cortex_a76.S				\
+		plat/common/plat_psci_common.c				\
+		plat/intel/soc/agilex5/bl31_plat_setup.c		\
+		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/common/socfpga_psci.c			\
+		plat/intel/soc/common/socfpga_sip_svc.c			\
+		plat/intel/soc/common/socfpga_sip_svc_v2.c			\
+		plat/intel/soc/common/socfpga_topology.c		\
+		plat/intel/soc/common/sip/socfpga_sip_ecc.c		\
+		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
+		plat/intel/soc/common/soc/socfpga_reset_manager.c
+
+# Configs for A76 and A55
+HW_ASSISTED_COHERENCY := 1
+USE_COHERENT_MEM := 0
+CTX_INCLUDE_AARCH32_REGS := 0
+ERRATA_A55_1530923 := 1
+
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+PROGRAMMABLE_RESET_ADDRESS	:= 0
+RESET_TO_BL2			:= 1
+BL2_INV_DCACHE			:= 0
+MULTI_CONSOLE_API		:= 1
diff --git a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
new file mode 100644
index 0000000..522bf5d
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_system_manager.h"
+#include "socfpga_handoff.h"
+
+uint32_t wait_pll_lock(void)
+{
+	uint32_t data;
+	uint32_t count = 0;
+
+	do {
+		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+		count++;
+		if (count >= 1000)
+			return -ETIMEDOUT;
+
+	} while ((CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
+			(CLKMGR_STAT_PERPLLLOCKED(data) == 0));
+	return 0;
+}
+
+uint32_t wait_fsm(void)
+{
+	uint32_t data;
+	uint32_t count = 0;
+
+	do {
+		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+		count++;
+		if (count >= 1000)
+			return -ETIMEDOUT;
+
+	} while (CLKMGR_STAT_BUSY(data) == CLKMGR_STAT_BUSY_E_BUSY);
+
+	return 0;
+}
+
+uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
+{
+	uint32_t val = 0;
+	uint32_t count = 0;
+	uint32_t req_status = 0;
+
+	val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
+		(data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
+	mmio_write_32(pll_mem_offset, val);
+
+	do {
+		req_status = mmio_read_32(pll_mem_offset);
+		count++;
+	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+
+	if (count >= 10)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+uint32_t pll_source_sync_read(uint32_t pll_mem_offset)
+{
+	uint32_t val = 0;
+	uint32_t rdata = 0;
+	uint32_t count = 0;
+	uint32_t req_status = 0;
+
+	val = (CLKMGR_MEM_REQ | CLKMGR_MEM_ADDR);
+	mmio_write_32(pll_mem_offset, val);
+
+	do {
+		req_status = mmio_read_32(pll_mem_offset);
+		count++;
+	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+
+	if (count >= 10)
+		return -ETIMEDOUT;
+
+	rdata = mmio_read_32(pll_mem_offset + 0x4);
+	INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
+
+	return rdata;
+}
+
+void config_clkmgr_handoff(handoff *hoff_ptr)
+{
+	/* Take both PLL out of reset and power up */
+
+	mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
+			CLKMGR_PLLGLOB_PD_SET_MSK |
+			CLKMGR_PLLGLOB_RST_SET_MSK);
+	mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
+			CLKMGR_PLLGLOB_PD_SET_MSK |
+			CLKMGR_PLLGLOB_RST_SET_MSK);
+
+	/* PLL lock */
+	wait_pll_lock();
+
+	/* Bypass all mainpllgrp's clocks to input clock ref */
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASSS, 0xff);
+	/* Bypass all perpllgrp's clocks to input clock ref */
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0xff);
+
+	/* Pass clock source frequency into scratch register */
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1),
+		hoff_ptr->hps_osc_clk_hz);
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2),
+		hoff_ptr->fpga_clk_hz);
+
+	/* Take all PLLs out of bypass */
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0);
+	wait_fsm();
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0);
+	wait_fsm();
+
+	/* Enable mainpllgrp's software-managed clock */
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_EN,
+			CLKMGR_MAINPLL_EN_RESET);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+			CLKMGR_PERPLL_EN_RESET);
+}
+
+/* Extract reference clock from platform clock source */
+uint32_t get_ref_clk(uint32_t pllglob)
+{
+	uint32_t arefclkdiv, ref_clk;
+	uint32_t scr_reg;
+
+	switch (CLKMGR_PSRC(pllglob)) {
+	case CLKMGR_PLLGLOB_PSRC_EOSC1:
+		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
+		ref_clk = mmio_read_32(scr_reg);
+		break;
+	case CLKMGR_PLLGLOB_PSRC_INTOSC:
+		ref_clk = CLKMGR_INTOSC_HZ;
+		break;
+	case CLKMGR_PLLGLOB_PSRC_F2S:
+		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
+		ref_clk = mmio_read_32(scr_reg);
+		break;
+	default:
+		ref_clk = 0;
+		assert(0);
+		break;
+	}
+
+	arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob);
+	ref_clk /= arefclkdiv;
+
+	return ref_clk;
+}
+
+/* Calculate clock frequency based on parameter */
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+{
+	uint32_t ref_clk = 0;
+
+	uint32_t clk_psrc, mdiv;
+	uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg;
+
+
+	clk_psrc = mmio_read_32(CLKMGR_MAINPLL + psrc_reg);
+	clk_psrc = 0;
+
+	switch (clk_psrc) {
+	case 0:
+		pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
+		pllc_reg = CLKMGR_MAINPLL + main_pllc;
+		pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+		break;
+	case CLKMGR_PSRC_PER:
+		pllm_reg = CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM;
+		pllc_reg = CLKMGR_PERPLL + per_pllc;
+		pllglob_reg = CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB;
+		break;
+	default:
+		return 0;
+	}
+	pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
+			pllc_reg = CLKMGR_MAINPLL + main_pllc;
+			pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+
+	ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
+	mdiv = CLKMGR_PLLM_MDIV(mmio_read_32(pllm_reg));
+	ref_clk *= mdiv;
+
+	pllc_div = mmio_read_32(pllc_reg) & 0x7ff;
+	NOTICE("return = %d Hz\n", (ref_clk / pllc_div));
+
+	ref_clk = 200000000;
+	return (uint32_t) ref_clk;
+
+}
+
+/* Return L3 interconnect clock */
+uint32_t get_l3_clk(void)
+{
+	uint32_t l3_clk;
+
+	l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
+				CLKMGR_PERPLL_PLLC1);
+	return l3_clk;
+}
+
+/* Calculate clock frequency to be used for watchdog timer */
+uint32_t get_wdt_clk(void)
+{
+	uint32_t l3_clk, l4_sys_clk;
+
+	l3_clk = get_l3_clk();
+	l4_sys_clk = l3_clk / 4;
+
+	return l4_sys_clk;
+}
+
+/* Calculate clock frequency to be used for UART driver */
+uint32_t get_uart_clk(void)
+{
+	uint32_t data32, l3_clk, l4_sp_clk;
+
+	l3_clk = get_l3_clk();
+
+	data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV);
+	data32 = (data32 >> 16) & 0x3;
+
+	l4_sp_clk = l3_clk >> data32;
+
+	return l4_sp_clk;
+}
+
+/* Calculate clock frequency to be used for SDMMC driver */
+uint32_t get_mmc_clk(void)
+{
+	uint32_t mmc_clk;
+
+	//TODO: To update when handoff data is ready
+	//uint32_t data32;
+
+	//mmc_clk = get_clk_freq(CLKMGR_ALTERA_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3);
+
+	//data32 = mmio_read_32(CLKMGR_ALTERA + CLKMGR_ALTERA_SDMMCCTR);
+	//data32 = (data32 & 0x7ff) + 1;
+	//mmc_clk = (mmc_clk / data32) / 4;
+
+
+	mmc_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC3,
+				CLKMGR_PERPLL_PLLC3);
+
+	// TODO: To update when handoff data is ready
+	NOTICE("mmc_clk = %d Hz\n", mmc_clk);
+
+	return mmc_clk;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_memory_controller.c b/plat/intel/soc/agilex5/soc/agilex5_memory_controller.c
new file mode 100644
index 0000000..0ddff4a
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_memory_controller.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "agilex5_memory_controller.h"
+#include <platform_def.h>
+
+#define ALT_CCU_NOC_DI_SET_MSK		0x10
+
+#define DDR_READ_LATENCY_DELAY		40
+#define MAX_MEM_CAL_RETRY		3
+#define PRE_CALIBRATION_DELAY		1
+#define POST_CALIBRATION_DELAY		1
+#define TIMEOUT_EMIF_CALIBRATION	1000
+#define CLEAR_EMIF_DELAY		1000
+#define CLEAR_EMIF_TIMEOUT		1000
+
+#define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
+#define DDR_CONFIG_ELEMENTS	(ARRAY_SIZE(ddr_config))
+
+/* tWR = Min. 15ns constant, see JEDEC standard eg. DDR4 is JESD79-4.pdf */
+#define tWR_IN_NS 15
+
+void configure_hmc_adaptor_regs(void);
+void configure_ddr_sched_ctrl_regs(void);
+
+/* The followring are the supported configurations */
+uint32_t ddr_config[] = {
+	/* DDR_CONFIG(Address order,Bank,Column,Row) */
+	/* List for DDR3 or LPDDR3 (pinout order > chip, row, bank, column) */
+	DDR_CONFIG(0, 3, 10, 12),
+	DDR_CONFIG(0, 3,  9, 13),
+	DDR_CONFIG(0, 3, 10, 13),
+	DDR_CONFIG(0, 3,  9, 14),
+	DDR_CONFIG(0, 3, 10, 14),
+	DDR_CONFIG(0, 3, 10, 15),
+	DDR_CONFIG(0, 3, 11, 14),
+	DDR_CONFIG(0, 3, 11, 15),
+	DDR_CONFIG(0, 3, 10, 16),
+	DDR_CONFIG(0, 3, 11, 16),
+	DDR_CONFIG(0, 3, 12, 15),	/* 0xa */
+	/* List for DDR4 only (pinout order > chip, bank, row, column) */
+	DDR_CONFIG(1, 3, 10, 14),
+	DDR_CONFIG(1, 4, 10, 14),
+	DDR_CONFIG(1, 3, 10, 15),
+	DDR_CONFIG(1, 4, 10, 15),
+	DDR_CONFIG(1, 3, 10, 16),
+	DDR_CONFIG(1, 4, 10, 16),
+	DDR_CONFIG(1, 3, 10, 17),
+	DDR_CONFIG(1, 4, 10, 17),
+};
+
+static int match_ddr_conf(uint32_t ddr_conf)
+{
+	int i;
+
+	for (i = 0; i < DDR_CONFIG_ELEMENTS; i++) {
+		if (ddr_conf == ddr_config[i])
+			return i;
+	}
+	return 0;
+}
+
+static int check_hmc_clk(void)
+{
+	unsigned long timeout = 0;
+	uint32_t hmc_clk;
+
+	do {
+		hmc_clk = mmio_read_32(AGX_SYSMGR_CORE_HMC_CLK);
+		if (hmc_clk & AGX_SYSMGR_CORE_HMC_CLK_STATUS)
+			break;
+		udelay(1);
+	} while (++timeout < 1000);
+	if (timeout >= 1000)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int clear_emif(void)
+{
+	uint32_t data;
+	unsigned long timeout;
+
+	mmio_write_32(AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL, 0);
+
+	timeout = 0;
+	do {
+		data = mmio_read_32(AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT);
+		if ((data & AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE) == 0)
+			break;
+		udelay(CLEAR_EMIF_DELAY);
+	} while (++timeout < CLEAR_EMIF_TIMEOUT);
+	if (timeout >= CLEAR_EMIF_TIMEOUT)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int mem_calibration(void)
+{
+	int status;
+	uint32_t data;
+	unsigned long timeout;
+	unsigned long retry = 0;
+
+	udelay(PRE_CALIBRATION_DELAY);
+
+	do {
+		if (retry != 0)
+			INFO("DDR: Retrying DRAM calibration\n");
+
+		timeout = 0;
+		do {
+			data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRCALSTAT);
+			if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
+				break;
+			udelay(500);
+		} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
+
+		if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
+			status = clear_emif();
+			if (status)
+				ERROR("Failed to clear Emif\n");
+		} else {
+			break;
+		}
+	} while (++retry < MAX_MEM_CAL_RETRY);
+
+	if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
+		ERROR("DDR: DRAM calibration failed.\n");
+		status = -EIO;
+	} else {
+		INFO("DDR: DRAM calibration success.\n");
+		status = 0;
+	}
+
+	udelay(POST_CALIBRATION_DELAY);
+
+	return status;
+}
+
+int init_hard_memory_controller(void)
+{
+	int status;
+
+	status = check_hmc_clk();
+	if (status) {
+		ERROR("DDR: Error, HMC clock not running\n");
+		return status;
+	}
+
+	status = mem_calibration();
+	if (status) {
+		ERROR("DDR: Memory Calibration Failed\n");
+		return status;
+	}
+
+	configure_hmc_adaptor_regs();
+
+	return 0;
+}
+
+void configure_ddr_sched_ctrl_regs(void)
+{
+	uint32_t data, dram_addr_order, ddr_conf, bank, row, col,
+		rd_to_miss, wr_to_miss, burst_len, burst_len_ddr_clk,
+		burst_len_sched_clk, act_to_act, rd_to_wr, wr_to_rd, bw_ratio,
+		t_rtp, t_rp, t_rcd, rd_latency, tw_rin_clk_cycles,
+		bw_ratio_extended, auto_precharge = 0, act_to_act_bank, faw,
+		faw_bank, bus_rd_to_rd, bus_rd_to_wr, bus_wr_to_rd;
+
+	INFO("Init HPS NOC's DDR Scheduler.\n");
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG1);
+	dram_addr_order = AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_DRAMADDRW);
+
+	col  = IOHMC_DRAMADDRW_COL_ADDR_WIDTH(data);
+	row  = IOHMC_DRAMADDRW_ROW_ADDR_WIDTH(data);
+	bank = IOHMC_DRAMADDRW_BANK_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH(data);
+
+	ddr_conf = match_ddr_conf(DDR_CONFIG(dram_addr_order, bank, col, row));
+
+	if (ddr_conf) {
+		mmio_clrsetbits_32(
+			AGX_MPFE_DDR_MAIN_SCHED_DDRCONF,
+			AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK,
+			AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET(ddr_conf));
+	} else {
+		ERROR("DDR: Cannot find predefined ddrConf configuration.\n");
+	}
+
+	mmio_write_32(AGX_MPFE_HMC_ADP(ADP_DRAMADDRWIDTH), data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_DRAMTIMING0);
+	rd_latency = AGX_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING0);
+	act_to_act = ACT_TO_ACT(data);
+	t_rcd = ACT_TO_RDWR(data);
+	act_to_act_bank = ACT_TO_ACT_DIFF_BANK(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING1);
+	rd_to_wr = RD_TO_WR(data);
+	bus_rd_to_rd = RD_TO_RD_DIFF_CHIP(data);
+	bus_rd_to_wr = RD_TO_WR_DIFF_CHIP(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING2);
+	t_rtp = RD_TO_PCH(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING3);
+	wr_to_rd = CALTIMING3_WR_TO_RD(data);
+	bus_wr_to_rd = CALTIMING3_WR_TO_RD_DIFF_CHIP(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING4);
+	t_rp = PCH_TO_VALID(data);
+
+	data = mmio_read_32(AGX_MPFE_HMC_ADP(HMC_ADP_DDRIOCTRL));
+	bw_ratio = ((HMC_ADP_DDRIOCTRL_IO_SIZE(data) == 0) ? 0 : 1);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG0);
+	burst_len = HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH(data);
+	burst_len_ddr_clk = burst_len / 2;
+	burst_len_sched_clk = ((burst_len/2) / 2);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG0);
+	switch (AGX_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE(data)) {
+	case 1:
+		/* DDR4 - 1333MHz */
+		/* 20 (19.995) clock cycles = 15ns */
+		/* Calculate with rounding */
+		tw_rin_clk_cycles = (((tWR_IN_NS * 1333) % 1000) >= 500) ?
+			((tWR_IN_NS * 1333) / 1000) + 1 :
+			((tWR_IN_NS * 1333) / 1000);
+		break;
+	default:
+		/* Others - 1066MHz or slower */
+		/* 16 (15.990) clock cycles = 15ns */
+		/* Calculate with rounding */
+		tw_rin_clk_cycles = (((tWR_IN_NS * 1066) % 1000) >= 500) ?
+			((tWR_IN_NS * 1066) / 1000) + 1 :
+			((tWR_IN_NS * 1066) / 1000);
+		break;
+	}
+
+	rd_to_miss = t_rtp + t_rp + t_rcd - burst_len_sched_clk;
+	wr_to_miss = ((rd_latency + burst_len_ddr_clk + 2 + tw_rin_clk_cycles)
+			/ 2) - rd_to_wr + t_rp + t_rcd;
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_DDRTIMING,
+		bw_ratio << DDRTIMING_BWRATIO_OFST |
+		wr_to_rd << DDRTIMING_WRTORD_OFST|
+		rd_to_wr << DDRTIMING_RDTOWR_OFST |
+		burst_len_sched_clk << DDRTIMING_BURSTLEN_OFST |
+		wr_to_miss << DDRTIMING_WRTOMISS_OFST |
+		rd_to_miss << DDRTIMING_RDTOMISS_OFST |
+		act_to_act << DDRTIMING_ACTTOACT_OFST);
+
+	data = mmio_read_32(AGX_MPFE_HMC_ADP(HMC_ADP_DDRIOCTRL));
+	bw_ratio_extended = ((ADP_DDRIOCTRL_IO_SIZE(data) == 0) ? 1 : 0);
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_DDRMODE,
+		bw_ratio_extended << DDRMODE_BWRATIOEXTENDED_OFST |
+		auto_precharge << DDRMODE_AUTOPRECHARGE_OFST);
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_READLATENCY,
+		(rd_latency / 2) + DDR_READ_LATENCY_DELAY);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING9);
+	faw = AGX_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT(data);
+
+	faw_bank = 1; // always 1 because we always have 4 bank DDR.
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE,
+		faw_bank << AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST |
+		faw << AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST |
+		act_to_act_bank << AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST);
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV,
+		((bus_rd_to_rd
+			<< AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST)
+			& AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK) |
+		((bus_rd_to_wr
+			<< AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST)
+			& AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK) |
+		((bus_wr_to_rd
+			<< AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST)
+			& AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK));
+
+}
+
+unsigned long get_physical_dram_size(void)
+{
+	uint32_t data;
+	unsigned long ram_addr_width, ram_ext_if_io_width;
+
+	data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRIOCTRL);
+	switch (AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE(data)) {
+	case 0:
+		ram_ext_if_io_width = 16;
+		break;
+	case 1:
+		ram_ext_if_io_width = 32;
+		break;
+	case 2:
+		ram_ext_if_io_width = 64;
+		break;
+	default:
+		ram_ext_if_io_width = 0;
+		break;
+	}
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_REG_DRAMADDRW);
+	ram_addr_width = IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH(data);
+
+	return (1 << ram_addr_width) * (ram_ext_if_io_width / 8);
+}
+
+
+
+void configure_hmc_adaptor_regs(void)
+{
+	uint32_t data;
+	uint32_t dram_io_width;
+
+	/* Configure DDR data rate */
+	dram_io_width = AGX_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0(
+		mmio_read_32(AGX_MPFE_IOHMC_REG_NIOSRESERVE0_OFST));
+	dram_io_width = (dram_io_width & 0xFF) >> 5;
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG3);
+
+	dram_io_width |= (data & 0x4);
+
+	mmio_write_32(AGX_MPFE_HMC_ADP_DDRIOCTRL, dram_io_width);
+
+	/* Copy dram addr width from IOHMC to HMC ADP */
+	data = mmio_read_32(AGX_MPFE_IOHMC_DRAMADDRW);
+	mmio_write_32(AGX_MPFE_HMC_ADP(ADP_DRAMADDRWIDTH), data);
+
+	/* Enable nonsecure access to DDR */
+	data = get_physical_dram_size();
+
+	if (data < AGX_DDR_SIZE)
+		data = AGX_DDR_SIZE;
+
+	mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT, data - 1);
+	mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT, 0x1f);
+
+	mmio_write_32(AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT, data - 1);
+
+	mmio_write_32(AGX_SOC_NOC_FW_DDR_SCR_ENABLESET, BIT(0) | BIT(8));
+
+	/* ECC enablement */
+	data = mmio_read_32(AGX_MPFE_IOHMC_REG_CTRLCFG1);
+	if (data & (1 << AGX_IOHMC_CTRLCFG1_ENABLE_ECC_OFST)) {
+		mmio_clrsetbits_32(AGX_MPFE_HMC_ADP_ECCCTRL1,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK);
+
+		mmio_clrsetbits_32(AGX_MPFE_HMC_ADP_ECCCTRL2,
+			AGX_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK,
+			AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK);
+
+		mmio_clrsetbits_32(AGX_MPFE_HMC_ADP_ECCCTRL1,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK);
+		INFO("Scrubbing ECC\n");
+
+		/* ECC Scrubbing */
+		zeromem((void *)DRAM_BASE, DRAM_SIZE);
+	} else {
+		INFO("ECC is disabled.\n");
+	}
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_mmc.c b/plat/intel/soc/agilex5/soc/agilex5_mmc.c
new file mode 100644
index 0000000..48f7341
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_mmc.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_system_manager.h"
+
+void agx5_mmc_init(void)
+{
+// TODO: To update when handoff data is ready
+
+	//mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+	//	CLKMGR_PERPLL_EN_SDMMCCLK);
+	//mmio_write_32(SOCFPGA_SYSMGR(SDMMC),
+	//	SYSMGR_SDMMC_SMPLSEL(0) | SYSMGR_SDMMC_DRVSEL(3));
+	//mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+	//	CLKMGR_PERPLL_EN_SDMMCCLK);
+
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
new file mode 100644
index 0000000..50d9e36
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include "agilex5_pinmux.h"
+#include "agilex5_system_manager.h"
+
+const uint32_t sysmgr_pinmux_array_sel[] = {
+	0x00000000, 0x00000001, /* usb */
+	0x00000004, 0x00000001,
+	0x00000008, 0x00000001,
+	0x0000000c, 0x00000001,
+	0x00000010, 0x00000001,
+	0x00000014, 0x00000001,
+	0x00000018, 0x00000001,
+	0x0000001c, 0x00000001,
+	0x00000020, 0x00000001,
+	0x00000024, 0x00000001,
+	0x00000028, 0x00000001,
+	0x0000002c, 0x00000001,
+	0x00000030, 0x00000000, /* emac0 */
+	0x00000034, 0x00000000,
+	0x00000038, 0x00000000,
+	0x0000003c, 0x00000000,
+	0x00000040, 0x00000000,
+	0x00000044, 0x00000000,
+	0x00000048, 0x00000000,
+	0x0000004c, 0x00000000,
+	0x00000050, 0x00000000,
+	0x00000054, 0x00000000,
+	0x00000058, 0x00000000,
+	0x0000005c, 0x00000000,
+	0x00000060, 0x00000008, /* gpio1 */
+	0x00000064, 0x00000008,
+	0x00000068, 0x00000005, /* uart0 tx */
+	0x0000006c, 0x00000005, /* uart 0 rx */
+	0x00000070, 0x00000008, /* gpio */
+	0x00000074, 0x00000008,
+	0x00000078, 0x00000004, /* i2c1 */
+	0x0000007c, 0x00000004,
+	0x00000080, 0x00000007, /* jtag */
+	0x00000084, 0x00000007,
+	0x00000088, 0x00000007,
+	0x0000008c, 0x00000007,
+	0x00000090, 0x00000001, /* sdmmc data0 */
+	0x00000094, 0x00000001,
+	0x00000098, 0x00000001,
+	0x0000009c, 0x00000001,
+	0x00000100, 0x00000001,
+	0x00000104, 0x00000001, /* sdmmc.data3 */
+	0x00000108, 0x00000008, /* loan */
+	0x0000010c, 0x00000008, /* gpio */
+	0x00000110, 0x00000008,
+	0x00000114, 0x00000008, /* gpio1.io21 */
+	0x00000118, 0x00000005, /* mdio0.mdio */
+	0x0000011c, 0x00000005  /* mdio0.mdc */
+};
+
+const uint32_t sysmgr_pinmux_array_ctrl[] = {
+	0x00000000, 0x00502c38, /* Q1_1 */
+	0x00000004, 0x00102c38,
+	0x00000008, 0x00502c38,
+	0x0000000c, 0x00502c38,
+	0x00000010, 0x00502c38,
+	0x00000014, 0x00502c38,
+	0x00000018, 0x00502c38,
+	0x0000001c, 0x00502c38,
+	0x00000020, 0x00502c38,
+	0x00000024, 0x00502c38,
+	0x00000028, 0x00502c38,
+	0x0000002c, 0x00502c38,
+	0x00000030, 0x00102c38, /* Q2_1 */
+	0x00000034, 0x00102c38,
+	0x00000038, 0x00502c38,
+	0x0000003c, 0x00502c38,
+	0x00000040, 0x00102c38,
+	0x00000044, 0x00102c38,
+	0x00000048, 0x00502c38,
+	0x0000004c, 0x00502c38,
+	0x00000050, 0x00102c38,
+	0x00000054, 0x00102c38,
+	0x00000058, 0x00502c38,
+	0x0000005c, 0x00502c38,
+	0x00000060, 0x00502c38, /* Q3_1 */
+	0x00000064, 0x00502c38,
+	0x00000068, 0x00102c38,
+	0x0000006c, 0x00502c38,
+	0x000000d0, 0x00502c38,
+	0x000000d4, 0x00502c38,
+	0x000000d8, 0x00542c38,
+	0x000000dc, 0x00542c38,
+	0x000000e0, 0x00502c38,
+	0x000000e4, 0x00502c38,
+	0x000000e8, 0x00102c38,
+	0x000000ec, 0x00502c38,
+	0x000000f0, 0x00502c38, /* Q4_1 */
+	0x000000f4, 0x00502c38,
+	0x000000f8, 0x00102c38,
+	0x000000fc, 0x00502c38,
+	0x00000100, 0x00502c38,
+	0x00000104, 0x00502c38,
+	0x00000108, 0x00102c38,
+	0x0000010c, 0x00502c38,
+	0x00000110, 0x00502c38,
+	0x00000114, 0x00502c38,
+	0x00000118, 0x00542c38,
+	0x0000011c, 0x00102c38
+};
+
+const uint32_t sysmgr_pinmux_array_fpga[] = {
+	0x00000000, 0x00000000,
+	0x00000004, 0x00000000,
+	0x00000008, 0x00000000,
+	0x0000000c, 0x00000000,
+	0x00000010, 0x00000000,
+	0x00000014, 0x00000000,
+	0x00000018, 0x00000000,
+	0x0000001c, 0x00000000,
+	0x00000020, 0x00000000,
+	0x00000028, 0x00000000,
+	0x0000002c, 0x00000000,
+	0x00000030, 0x00000000,
+	0x00000034, 0x00000000,
+	0x00000038, 0x00000000,
+	0x0000003c, 0x00000000,
+	0x00000040, 0x00000000,
+	0x00000044, 0x00000000,
+	0x00000048, 0x00000000,
+	0x00000050, 0x00000000,
+	0x00000054, 0x00000000,
+	0x00000058, 0x0000002a
+};
+
+const uint32_t sysmgr_pinmux_array_iodelay[] = {
+	0x00000000, 0x00000000,
+	0x00000004, 0x00000000,
+	0x00000008, 0x00000000,
+	0x0000000c, 0x00000000,
+	0x00000010, 0x00000000,
+	0x00000014, 0x00000000,
+	0x00000018, 0x00000000,
+	0x0000001c, 0x00000000,
+	0x00000020, 0x00000000,
+	0x00000024, 0x00000000,
+	0x00000028, 0x00000000,
+	0x0000002c, 0x00000000,
+	0x00000030, 0x00000000,
+	0x00000034, 0x00000000,
+	0x00000038, 0x00000000,
+	0x0000003c, 0x00000000,
+	0x00000040, 0x00000000,
+	0x00000044, 0x00000000,
+	0x00000048, 0x00000000,
+	0x0000004c, 0x00000000,
+	0x00000050, 0x00000000,
+	0x00000054, 0x00000000,
+	0x00000058, 0x00000000,
+	0x0000005c, 0x00000000,
+	0x00000060, 0x00000000,
+	0x00000064, 0x00000000,
+	0x00000068, 0x00000000,
+	0x0000006c, 0x00000000,
+	0x00000070, 0x00000000,
+	0x00000074, 0x00000000,
+	0x00000078, 0x00000000,
+	0x0000007c, 0x00000000,
+	0x00000080, 0x00000000,
+	0x00000084, 0x00000000,
+	0x00000088, 0x00000000,
+	0x0000008c, 0x00000000,
+	0x00000090, 0x00000000,
+	0x00000094, 0x00000000,
+	0x00000098, 0x00000000,
+	0x0000009c, 0x00000000,
+	0x00000100, 0x00000000,
+	0x00000104, 0x00000000,
+	0x00000108, 0x00000000,
+	0x0000010c, 0x00000000,
+	0x00000110, 0x00000000,
+	0x00000114, 0x00000000,
+	0x00000118, 0x00000000,
+	0x0000011c, 0x00000000
+};
+
+void config_fpgaintf_mod(void)
+{
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+}
+
+void config_pinmux(handoff *hoff_ptr)
+{
+	unsigned int i;
+
+	mmio_write_32(PINMUX_HANDOFF_CONFIG_ADDR, PINMUX_HANDOFF_CONFIG_VAL);
+	for (i = 0; i < PINMUX_HANDOFF_ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_PIN0SEL +
+			hoff_ptr->pinmux_sel_array[i],
+			hoff_ptr->pinmux_sel_array[i + 1]);
+	}
+
+	config_fpgaintf_mod();
+}
+
+void config_peripheral(handoff *hoff_ptr)
+{
+
+	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
+	// Pending SDM to pass over handoff data
+	// unsigned int i;
+
+	// for (i = 0; i < 4; i += 2) {
+	//	mmio_write_32(AGX_EDGE_PERIPHERAL +
+	//	hoff_ptr->peripheral_pwr_gate_array[i],
+	//	hoff_ptr->peripheral_pwr_gate_array[i+1]);
+	// }
+
+
+	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
+	mmio_write_32(AGX5_PERIPHERAL,
+	hoff_ptr->peripheral_pwr_gate_array);
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
new file mode 100644
index 0000000..0d81970
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "agilex5_power_manager.h"
+#include "socfpga_reset_manager.h"
+
+int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
+{
+	uint32_t data = 0;
+	uint32_t count = 0;
+	uint32_t pgstat = 0;
+
+	/* Wait FSM ready */
+	do {
+		data = mmio_read_32(AGX5_PWRMGR(PSS_PGSTAT));
+		count++;
+		if (count >= 1000) {
+			return -ETIMEDOUT;
+		}
+
+	} while (AGX5_PWRMGR_PSS_STAT_BUSY(data) == AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY);
+
+	/* Verify PSS SRAM power gated */
+	pgstat = mmio_read_32(AGX5_PWRMGR(PSS_PGSTAT));
+	if (pgstat != (AGX5_PWRMGR_PSS_PGEN_OUT(peripheral_handoff))) {
+		return AGX5_PWRMGR_HANDOFF_PERIPHERAL;
+	}
+
+	return 0;
+}
+
+int pss_sram_power_off(handoff *hoff_ptr)
+{
+	int ret = 0;
+	uint32_t peripheral_handoff = 0;
+
+	/* Get PSS SRAM handoff data */
+	peripheral_handoff = hoff_ptr->peripheral_pwr_gate_array;
+
+	/* Enable firewall for PSS SRAM */
+	mmio_write_32(AGX5_PWRMGR(PSS_FWENCTL),
+			AGX5_PWRMGR_PSS_FWEN(peripheral_handoff));
+
+	/* Wait */
+	udelay(1);
+
+	/* Power gating PSS SRAM */
+	mmio_write_32(AGX5_PWRMGR(PSS_PGENCTL),
+			AGX5_PWRMGR_PSS_PGEN(peripheral_handoff));
+
+	ret = wait_verify_fsm(1000, peripheral_handoff);
+
+	return ret;
+}
+
+void config_pwrmgr_handoff(handoff *hoff_ptr)
+{
+	int ret = 0;
+
+	switch (hoff_ptr->header_magic) {
+	case HANDOFF_MAGIC_PERIPHERAL:
+		ret = pss_sram_power_off(hoff_ptr);
+		break;
+	default:
+		break;
+	}
+
+	if (ret != 0) {
+		ERROR("Config PwrMgr handoff failed. error %d\n", ret);
+		assert(false);
+	}
+}
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 213fd3c..cbd0121 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,6 +34,11 @@
 func plat_secondary_cold_boot_setup
 	/* Wait until the it gets reset signal from rstmgr gets populated */
 poll_mailbox:
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mov_imm x0, PLAT_SEC_ENTRY
+	cbz	x0, poll_mailbox
+	br      x0
+#else
 	wfi
 	mov_imm	x0, PLAT_SEC_ENTRY
 	ldr	x1, [x0]
@@ -44,8 +49,13 @@
 	cmp	x3, x4
 	b.ne	poll_mailbox
 	br	x1
+#endif
 endfunc plat_secondary_cold_boot_setup
 
+#if	((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
+
 func platform_is_primary_cpu
 	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
 	cmp	x0, #PLAT_PRIMARY_CPU
@@ -53,6 +63,21 @@
 	ret
 endfunc platform_is_primary_cpu
 
+#else
+
+func platform_is_primary_cpu
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp x0, #(PLAT_PRIMARY_CPU_A76)
+	b.eq primary_cpu
+	cmp x0, #(PLAT_PRIMARY_CPU_A55)
+	b.eq primary_cpu
+primary_cpu:
+	cset	x0, eq
+	ret
+endfunc platform_is_primary_cpu
+
+#endif
+
 func plat_is_my_cpu_primary
 	mrs	x0, mpidr_el1
 	b   platform_is_primary_cpu
@@ -62,11 +87,27 @@
 	mrs	x0, mpidr_el1
 	and	x1, x0, #MPIDR_CPU_MASK
 	and	x0, x0, #MPIDR_CLUSTER_MASK
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	add	x0, x1, x0, LSR #8
+#else
 	add	x0, x1, x0, LSR #6
+#endif
 	ret
 endfunc plat_my_core_pos
 
 func warm_reset_req
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	bl	plat_is_my_cpu_primary
+	cbnz	x0, warm_reset
+warm_reset:
+	mov_imm x1, PLAT_SEC_ENTRY
+	str	xzr, [x1]
+	mrs	x1, rmr_el3
+	orr	x1, x1, #0x02
+	msr	rmr_el3, x1
+	isb
+	dsb	sy
+#else
 	str	xzr, [x4]
 	bl	plat_is_my_cpu_primary
 	cbz	x0, cpu_in_wfi
@@ -80,11 +121,28 @@
 cpu_in_wfi:
 	wfi
 	b	cpu_in_wfi
+#endif
 endfunc warm_reset_req
 
+/* TODO: Zephyr warm reset test */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 func plat_get_my_entrypoint
 	ldr	x4, =L2_RESET_DONE_REG
 	ldr	x5, [x4]
+	ldr	x1, =PLAT_L2_RESET_REQ
+	cmp	x1, x5
+	b.eq	zephyr_reset_req
+	mov_imm	x1, PLAT_SEC_ENTRY
+	ldr	x0, [x1]
+	ret
+zephyr_reset_req:
+	ldr	x0, =0x00
+	ret
+endfunc plat_get_my_entrypoint
+#else
+func plat_get_my_entrypoint
+	ldr	x4, =L2_RESET_DONE_REG
+	ldr	x5, [x4]
 	ldr	x1, =L2_RESET_DONE_STATUS
 	cmp	x1, x5
 	b.eq	warm_reset_req
@@ -92,7 +150,7 @@
 	ldr	x0, [x1]
 	ret
 endfunc plat_get_my_entrypoint
-
+#endif
 
 	/* ---------------------------------------------
 	 * int plat_crash_console_init(void)
@@ -138,6 +196,13 @@
 	ret
 endfunc platform_mem_init
 
+	/* --------------------------------------------------------
+	 * macro plat_secondary_cpus_bl31_entry;
+	 *
+	 * el3_entrypoint_common init param configuration.
+	 * Called very early in the secondary cores boot process.
+	 * --------------------------------------------------------
+	 */
 func plat_secondary_cpus_bl31_entry
 	el3_entrypoint_common                                   \
 		_init_sctlr=0                                   \
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index 99d48d2..684a625 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -1,101 +1,86 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-
 #include <assert.h>
 #include <common/debug.h>
 #include <errno.h>
 #include <lib/mmio.h>
+#include <platform_def.h>
 
 #include "ncore_ccu.h"
+#include "socfpga_plat_def.h"
+#include "socfpga_system_manager.h"
 
 uint32_t poll_active_bit(uint32_t dir);
 
-static coh_ss_id_t subsystem_id;
+#define SMMU_DMI			1
 
 
+static coh_ss_id_t subsystem_id;
 void get_subsystem_id(void)
 {
 	uint32_t snoop_filter, directory, coh_agent;
-
 	snoop_filter = CSIDR_NUM_SF(mmio_read_32(NCORE_CCU_CSR(NCORE_CSIDR)));
 	directory = CSUIDR_NUM_DIR(mmio_read_32(NCORE_CCU_CSR(NCORE_CSUIDR)));
 	coh_agent = CSUIDR_NUM_CAI(mmio_read_32(NCORE_CCU_CSR(NCORE_CSUIDR)));
-
 	subsystem_id.num_snoop_filter = snoop_filter + 1;
 	subsystem_id.num_directory = directory;
 	subsystem_id.num_coh_agent = coh_agent;
 }
-
 uint32_t directory_init(void)
 {
 	uint32_t dir_sf_mtn, dir_sf_en;
 	uint32_t dir, sf, ret;
-
 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
 		for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) {
 			dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
 			dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
-
 			/* Initialize All Entries */
 			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf));
-
 			/* Poll Active Bit */
 			ret = poll_active_bit(dir);
 			if (ret != 0) {
 				ERROR("Timeout during active bit polling");
 				return -ETIMEDOUT;
 			}
-
 			/* Disable snoop filter, a bit per snoop filter */
 			mmio_clrbits_32(dir_sf_en, BIT(sf));
-
 		}
 	}
-
 	return 0;
 }
-
 uint32_t coherent_agent_intfc_init(void)
 {
 	uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
-
 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
 		for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) {
 			ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0);
 			ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR));
-
 			/* Coh Agent Snoop Enable */
 			if (CACHING_AGENT_BIT(ca_id))
-				mmio_write_32(ca_snoop_en, BIT(ca));
-
+				mmio_setbits_32(ca_snoop_en, BIT(ca));
 			/* Coh Agent Snoop DVM Enable */
 			ca_type = CACHING_AGENT_TYPE(ca_id);
 			if (ca_type == ACE_W_DVM || ca_type == ACE_L_W_DVM)
-				mmio_write_32(NCORE_CCU_CSR(NCORE_CSADSER0),
+				mmio_setbits_32(NCORE_CCU_CSR(NCORE_CSADSER0),
 				BIT(ca));
 		}
 	}
-
 	return 0;
 }
-
 uint32_t poll_active_bit(uint32_t dir)
 {
 	uint32_t timeout = 80000;
 	uint32_t poll_dir =  DIRECTORY_UNIT(dir, NCORE_DIRUSFMAR);
-
 	while (timeout > 0) {
 		if (mmio_read_32(poll_dir) == 0)
 			return 0;
 		timeout--;
 	}
-
 	return -1;
 }
-
 void bypass_ocram_firewall(void)
 {
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -107,7 +92,6 @@
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
-
 void ncore_enable_ocram_firewall(void)
 {
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -119,15 +103,44 @@
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
-
 uint32_t init_ncore_ccu(void)
 {
 	uint32_t status;
-
 	get_subsystem_id();
 	status = directory_init();
 	status = coherent_agent_intfc_init();
 	bypass_ocram_firewall();
-
 	return status;
 }
+
+void setup_smmu_stream_id(void)
+{
+	/* Configure Stream ID for Agilex5 */
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_ID_AX_REG_0_DMA0), DMA0);
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_ID_AX_REG_0_DMA1), DMA1);
+	mmio_write_32(SOCFPGA_SYSMGR(SDM_TBU_STREAM_ID_AX_REG_1_SDM), SDM);
+	/* Reg map showing USB2 but Linux USB0? */
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_USB2), USB0);
+	/* Reg map showing USB3 but Linux USB1? */
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_USB3), USB1);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_SDMMC), SDMMC);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_NAND), NAND);
+	/* To confirm ETR - core sight debug*/
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_ETR), CORE_SIGHT_DEBUG);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN0), TSN0);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN1), TSN1);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN2), TSN2);
+
+	/* Enabled Stream ctrl register for Agilex5 */
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA0), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA1), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(SDM_TBU_STREAM_CTRL_REG_1_SDM), ENABLE_STREAMID_SECURE_TX);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_USB2), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_USB3), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_SDMMC), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_NAND), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_ETR), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN0), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN1), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN2), ENABLE_STREAMID);
+}
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
index 3f662ff..6cdbeb8 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
@@ -1,99 +1,420 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-
 #ifndef NCORE_CCU_H
 #define NCORE_CCU_H
 
+#include <stdbool.h>
+#include <stdint.h>
 
-#define NCORE_CCU_OFFSET		0xf7000000
+#ifndef CCU_ACTIVATE_COH_FPGA
+#define CCU_ACTIVATE_COH_FPGA 0
+#endif
+// Address map for ccu init
+#define addr_CAIUIDR1				(0x1C000000)
+#define addr_GRBUNRRUCR				(0x1c0ffff8)
+#define base_addr_NRS_CAIU0			(0x1c000000)
+#define base_addr_NRS_NCAIU0			(0x1c001000)
+#define base_addr_NRS_NCAIU1			(0x1c002000)
+#define base_addr_NRS_NCAIU2			(0x1c003000)
+#define base_addr_NRS_NCAIU3			(0x1c004000)
+#define base_addr_NRS_DCE0			(0x1c005000)
+#define base_addr_NRS_DCE1			(0x1c006000)
+//#define base_addr_NRS_DMI0			(0x1c007000)
+//#define base_addr_NRS_DMI1			(0x1c008000)
+//DMI
+#define ALT_CCU_CCU_DMI0_DMIUSMCTCR_ADDR	0x1C007300
+#define ALT_CCU_CCU_DMI1_DMIUSMCTCR_ADDR	0x1C008300
+//DSU
+#define ALT_CCU_DSU_CAIUAMIGR_ADDR		0x1C0003C0
+#define ALT_CCU_DSU_CAIUMIFSR_ADDR		0x1C0003C4
+#define ALT_CCU_DSU_CAIUGPRBLR1_ADDR		0x1C000414
+#define ALT_CCU_DSU_CAIUGPRBHR1_ADDR		0x1C000418
+#define ALT_CCU_DSU_CAIUGPRAR1_ADDR		0x1C000410
+#define ALT_CCU_DSU_CAIUGPRBLR2_ADDR		0x1C000424
+#define ALT_CCU_DSU_CAIUGPRBHR2_ADDR		0x1C000428
+#define ALT_CCU_DSU_CAIUGPRAR2_ADDR		0x1C000420
+#define ALT_CCU_DSU_CAIUGPRBLR4_ADDR		0x1C000444
+#define ALT_CCU_DSU_CAIUGPRBHR4_ADDR		0x1C000448
+#define ALT_CCU_DSU_CAIUGPRAR4_ADDR		0x1C000440
+#define ALT_CCU_DSU_CAIUGPRBLR5_ADDR		0x1C000454
+#define ALT_CCU_DSU_CAIUGPRBHR5_ADDR		0x1C000458
+#define ALT_CCU_DSU_CAIUGPRAR5_ADDR		0x1C000450
+#define ALT_CCU_DSU_CAIUGPRBLR6_ADDR		0x1C000464
+#define ALT_CCU_DSU_CAIUGPRBHR6_ADDR		0x1C000468
+#define ALT_CCU_DSU_CAIUGPRAR6_ADDR		0x1C000460
+#define ALT_CCU_DSU_CAIUGPRBLR7_ADDR		0x1C000474
+#define ALT_CCU_DSU_CAIUGPRBHR7_ADDR		0x1C000478
+#define ALT_CCU_DSU_CAIUGPRAR7_ADDR		0x1C000470
+#define ALT_CCU_DSU_CAIUGPRBLR8_ADDR		0x1C000484
+#define ALT_CCU_DSU_CAIUGPRBHR8_ADDR		0x1C000488
+#define ALT_CCU_DSU_CAIUGPRAR8_ADDR		0x1C000480
+#define ALT_CCU_DSU_CAIUGPRBLR9_ADDR		0x1C000494
+#define ALT_CCU_DSU_CAIUGPRBHR9_ADDR		0x1C000498
+#define ALT_CCU_DSU_CAIUGPRAR9_ADDR		0x1C000490
+#define ALT_CCU_DSU_CAIUGPRBLR10_ADDR		0x1C0004A4
+#define ALT_CCU_DSU_CAIUGPRBHR10_ADDR		0x1C0004A8
+#define ALT_CCU_DSU_CAIUGPRAR10_ADDR		0x1C0004A0
+//GIC
+#define ALT_CCU_GIC_M_XAIUAMIGR_ADDR		0x1C0023C0
+#define ALT_CCU_GIC_M_XAIUMIFSR_ADDR		0x1C0023C4
+#define ALT_CCU_GIC_M_XAIUGPRBLR1_ADDR		0x1C002414
+#define ALT_CCU_GIC_M_XAIUGPRBHR1_ADDR		0x1C002418
+#define ALT_CCU_GIC_M_XAIUGPRAR1_ADDR		0x1C002410
+#define ALT_CCU_GIC_M_XAIUGPRBLR6_ADDR		0x1C002464
+#define ALT_CCU_GIC_M_XAIUGPRBHR6_ADDR		0x1C002468
+#define ALT_CCU_GIC_M_XAIUGPRAR6_ADDR		0x1C002460
+#define ALT_CCU_GIC_M_XAIUGPRBLR8_ADDR		0x1C002484
+#define ALT_CCU_GIC_M_XAIUGPRBHR8_ADDR		0x1C002488
+#define ALT_CCU_GIC_M_XAIUGPRAR8_ADDR		0x1C002480
+#define ALT_CCU_GIC_M_XAIUGPRBLR10_ADDR		0x1C0024A4
+#define ALT_CCU_GIC_M_XAIUGPRBHR10_ADDR		0x1C0024A8
+#define ALT_CCU_GIC_M_XAIUGPRAR10_ADDR		0x1C0024A0
+//FPGA2SOC
+#define ALT_CCU_FPGA2SOC_XAIUAMIGR_ADDR		0x1C0013C0
+#define ALT_CCU_FPGA2SOC_XAIUMIFSR_ADDR		0x1C0013C4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR1_ADDR	0x1C001414
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR1_ADDR	0x1C001418
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR1_ADDR	0x1C001410
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR6_ADDR	0x1C001464
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR6_ADDR	0x1C001468
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR6_ADDR	0x1C001460
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR8_ADDR	0x1C001484
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR8_ADDR	0x1C001488
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR8_ADDR	0x1C001480
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR10_ADDR	0x1C0014A4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR10_ADDR	0x1C0014A8
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR10_ADDR	0x1C0014A0
+//TCU
+#define ALT_CCU_TCU_BASE 0x1C003000
+#define ALT_CCU_TCU_XAIUAMIGR_ADDR		ALT_CCU_TCU_BASE + 0x03C0
+#define ALT_CCU_TCU_XAIUMIFSR_ADDR		ALT_CCU_TCU_BASE + 0x03C4
+#define ALT_CCU_TCU_XAIUGPRBLR0_ADDR		ALT_CCU_TCU_BASE + 0x0404
+#define ALT_CCU_TCU_XAIUGPRBHR0_ADDR		ALT_CCU_TCU_BASE + 0x0408
+#define ALT_CCU_TCU_XAIUGPRAR0_ADDR		ALT_CCU_TCU_BASE + 0x0400
+#define ALT_CCU_TCU_XAIUGPRBLR1_ADDR		ALT_CCU_TCU_BASE + 0x0414
+#define ALT_CCU_TCU_XAIUGPRBHR1_ADDR		ALT_CCU_TCU_BASE + 0x0418
+#define ALT_CCU_TCU_XAIUGPRAR1_ADDR		ALT_CCU_TCU_BASE + 0x0410
+#define ALT_CCU_TCU_XAIUGPRBLR2_ADDR		ALT_CCU_TCU_BASE + 0x0424
+#define ALT_CCU_TCU_XAIUGPRBHR2_ADDR		ALT_CCU_TCU_BASE + 0x0428
+#define ALT_CCU_TCU_XAIUGPRAR2_ADDR		ALT_CCU_TCU_BASE + 0x0420
+#define ALT_CCU_TCU_XAIUGPRBLR6_ADDR		0x1C003464
+#define ALT_CCU_TCU_XAIUGPRBHR6_ADDR		0x1C003468
+#define ALT_CCU_TCU_XAIUGPRAR6_ADDR		0x1C003460
+#define ALT_CCU_TCU_XAIUGPRBLR8_ADDR		0x1C003484
+#define ALT_CCU_TCU_XAIUGPRBHR8_ADDR		0x1C003488
+#define ALT_CCU_TCU_XAIUGPRAR8_ADDR		0x1C003480
+#define ALT_CCU_TCU_XAIUGPRBLR10_ADDR		0x1C0034A4
+#define ALT_CCU_TCU_XAIUGPRBHR10_ADDR		0x1C0034A8
+#define ALT_CCU_TCU_XAIUGPRAR10_ADDR		0x1C0034A0
+//IOM
+#define ALT_CCU_CCU_IOM_XAIUAMIGR_ADDR		0x1C0043C0
+#define ALT_CCU_CCU_IOM_XAIUMIFSR_ADDR		0x1C0013C4
+#define ALT_CCU_IOM_XAIUGPRBLR1_ADDR		0x1C001414
+#define ALT_CCU_IOM_XAIUGPRBHR1_ADDR		0x1C001418
+#define ALT_CCU_IOM_XAIUGPRAR1_ADDR		0x1C001410
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR6_ADDR	0x1C001464
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR6_ADDR	0x1C001468
+#define ALT_CCU_CCU_IOM_XAIUGPRAR6_ADDR		0x1C001460
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR8_ADDR	0x1C001484
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR8_ADDR	0x1C001488
+#define ALT_CCU_CCU_IOM_XAIUGPRAR8_ADDR		0x1C001480
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR10_ADDR	0x1C0014A4
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR10_ADDR	0x1C0014A8
+#define ALT_CCU_CCU_IOM_XAIUGPRAR10_ADDR	0x1C0014A0
+//DCE
+#define ALT_CCU_DCE0_DCEUAMIGR_ADDR		0x1C0053C0
+#define ALT_CCU_DCE0_DCEUMIFSR_ADDR		0x1C0053C4
+#define ALT_CCU_DCE0_DCEUGPRBLR6_ADDR		0x1C005464
+#define ALT_CCU_DCE0_DCEUGPRBHR6_ADDR		0x1C005468
+#define ALT_CCU_DCE0_DCEUGPRAR6_ADDR		0x1C005460
+#define ALT_CCU_DCE0_DCEUGPRBLR8_ADDR		0x1C005484
+#define ALT_CCU_DCE0_DCEUGPRBHR8_ADDR		0x1C005488
+#define ALT_CCU_DCE0_DCEUGPRAR8_ADDR		0x1C005480
+#define ALT_CCU_DCE0_DCEUGPRBLR10_ADDR		0x1C0054A4
+#define ALT_CCU_DCE0_DCEUGPRBHR10_ADDR		0x1C0054A8
+#define ALT_CCU_DCE0_DCEUGPRAR10_ADDR		0x1C0054A0
+#define ALT_CCU_DCE1_DCEUAMIGR_ADDR		0x1C0063C0
+#define ALT_CCU_DCE1_DCEUMIFSR_ADDR		0x1C0063C4
+#define ALT_CCU_DCE1_DCEUGPRBLR6_ADDR		0x1C006464
+#define ALT_CCU_DCE1_DCEUGPRBHR6_ADDR		0x1C006468
+#define ALT_CCU_DCE1_DCEUGPRAR6_ADDR		0x1C006460
+#define ALT_CCU_DCE1_DCEUGPRBLR8_ADDR		0x1C006484
+#define ALT_CCU_DCE1_DCEUGPRBHR8_ADDR		0x1C006488
+#define ALT_CCU_DCE1_DCEUGPRAR8_ADDR		0x1C006480
+#define ALT_CCU_DCE1_DCEUGPRBLR10_ADDR		0x1C0064A4
+#define ALT_CCU_DCE1_DCEUGPRBHR10_ADDR		0x1C0064A8
+#define ALT_CCU_DCE1_DCEUGPRAR10_ADDR		0x1C0064A0
+#define offset_NRS_GPRAR0			(0x400)
+#define offset_NRS_GPRBLR0			(0x404)
+#define offset_NRS_GPRBHR0			(0x408)
+#define offset_NRS_GPRAR1			(0x410)
+#define offset_NRS_GPRBLR1			(0x414)
+#define offset_NRS_GPRBHR1			(0x418)
+#define offset_NRS_GPRAR2			(0x420)
+#define offset_NRS_GPRBLR2			(0x424)
+#define offset_NRS_GPRBHR2			(0x428)
+#define offset_NRS_GPRAR3			(0x430)
+#define offset_NRS_GPRBLR3			(0x434)
+#define offset_NRS_GPRBHR3			(0x438)
+#define offset_NRS_GPRAR4			(0x440)
+#define offset_NRS_GPRBLR4			(0x444)
+#define offset_NRS_GPRBHR4			(0x448)
+#define offset_NRS_GPRAR5			(0x450)
+#define offset_NRS_GPRBLR5			(0x454)
+#define offset_NRS_GPRBHR5			(0x458)
+#define offset_NRS_GPRAR6			(0x460)
+#define offset_NRS_GPRBLR6			(0x464)
+#define offset_NRS_GPRBHR6			(0x468)
+#define offset_NRS_GPRAR7			(0x470)
+#define offset_NRS_GPRBLR7			(0x474)
+#define offset_NRS_GPRBHR7			(0x478)
+#define offset_NRS_GPRAR8			(0x480)
+#define offset_NRS_GPRBLR8			(0x484)
+#define offset_NRS_GPRBHR8			(0x488)
+#define offset_NRS_GPRAR9			(0x490)
+#define offset_NRS_GPRBLR9			(0x494)
+#define offset_NRS_GPRBHR9			(0x498)
+#define offset_NRS_GPRAR10			(0x4a0)
+#define offset_NRS_GPRBLR10			(0x4a4)
+#define offset_NRS_GPRBHR10			(0x4a8)
+#define offset_NRS_AMIGR			(0x3c0)
+#define offset_NRS_MIFSR			(0x3c4)
+#define offset_NRS_DMIUSMCTCR			(0x300)
+#define base_addr_DII0_PSSPERIPHS		(0x10000)
+#define base_addr_DII0_LWHPS2FPGA		(0x20000)
+#define base_addr_DII0_HPS2FPGA_1G		(0x40000)
+#define base_addr_DII0_HPS2FPGA_15G		(0x400000)
+#define base_addr_DII0_HPS2FPGA_240G		(0x4000000)
+#define base_addr_DII1_MPFEREGS			(0x18000)
+#define base_addr_DII2_GICREGS			(0x1D000)
+#define base_addr_DII3_OCRAM			(0x0)
+#define base_addr_BHR				(0x0)
+#define base_addr_DMI_SDRAM_2G			(0x80000)
+#define base_addr_DMI_SDRAM_30G			(0x800000)
+#define base_addr_DMI_SDRAM_480G		(0x8000000)
+// ((0x0<<9) | (0xf<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_PSSPERIPHS			0xC0F00000
+// ((0x0<<9) | (0x11<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_LWHPS2FPGA			0xC1100000
+// ((0x0<<9) | (0x12<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_HPS2FPGA_1G			0xC1200000
+// ((0x0<<9) | (0x16<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_HPS2FPGA_15G			0xC1600000
+// ((0x0<<9) | (0x1a<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_HPS2FPGA_240G			0xC1A00000
+// ((0x1<<9) | (0xe<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII1_MPFEREGS			0xC0E00200
+// ((0x2<<9) | (0x8<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII2_GICREGS				0xC0800400
+// ((0x3<<9) | (0x9<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII3_OCRAM				0xC0900600
+// ((0x0<<9) | (0x12<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_1G_ORDERED			0x81200000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x12<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_1G				0x81200006
+// ((0x0<<9) | (0x13<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_2G_ORDERED			0x81300000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x13<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_2G				0x81300006
+// ((0x0<<9) | (0x16<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_15G_ORDERED		0x81600000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x16<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_15G			0x81600006
+// ((0x0<<9) | (0x17<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_30G_ORDERED		0x81700000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x17<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_30G			0x81700006
+// ((0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_240G_ORDERED		0x81a00000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_240G			0x81a00006
+// ((0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_480G_ORDERED		0x81b00000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_480G			0x81b00006
 
+typedef enum CCU_REGION_SECURITY_e {
+    //
+    // Allow secure accesses only.
+    //
+	CCU_REGION_SECURITY_SECURE_ONLY,
+    //
+    // Allow non-secure accesses only.
+    //
+	CCU_REGION_SECURITY_NON_SECURE_ONLY,
+    //
+    // Allow accesses of any security state.
+    //
+	CCU_REGION_SECURITY_DONT_CARE
+} CCU_REGION_SECURITY_t;
+typedef enum CCU_REGION_PRIVILEGE_e {
+    //
+    // Allow privileged accesses only.
+    //
+	CCU_REGION_PRIVILEGE_PRIVILEGED_ONLY,
+    //
+    // Allow unprivileged accesses only.
+    //
+	CCU_REGION_PRIVILEGE_NON_PRIVILEGED_ONLY,
+    //
+    // Allow accesses of any privilege.
+    //
+	CCU_REGION_PRIVILEGE_DONT_CARE
+} CCU_REGION_PRIVILEGE_t;
+//
+// Initializes the CCU by enabling all regions except RAM 1 - 5.
+// This is needed because of an RTL change around 2016.02.24.
+//
+// Runtime measurement:
+//  - arm     : 14,830,000 ps (2016.05.31; sanity/printf_aarch32)
+//  - aarch64 : 14,837,500 ps (2016.05.31; sanity/printf)
+//
+// Runtime history:
+//  - arm     : 20,916,668 ps (2016.05.30; sanity/printf_aarch32)
+//  - aarch64 : 20,924,168 ps (2016.05.30; sanity/printf)
+//
+int ccu_hps_init(void);
 
-/* Coherent Sub-System Address Map */
-#define NCORE_CAIU_OFFSET		0x00000
-#define NCORE_CAIU_SIZE			0x01000
+typedef enum ccu_hps_ram_region_e {
+	ccu_hps_ram_region_ramspace0 = 0,
+	ccu_hps_ram_region_ramspace1 = 1,
+	ccu_hps_ram_region_ramspace2 = 2,
+	ccu_hps_ram_region_ramspace3 = 3,
+	ccu_hps_ram_region_ramspace4 = 4,
+	ccu_hps_ram_region_ramspace5 = 5,
+} ccu_hps_ram_region_t;
 
-#define NCORE_NCBU_OFFSET		0x60000
-#define NCORE_NCBU_SIZE			0x01000
+// Disables a RAM (OCRAM) region with the given ID.
+int ccu_hps_ram_region_disable(int id);
 
-#define NCORE_DIRU_OFFSET		0x80000
-#define NCORE_DIRU_SIZE			0x01000
+// Enables a RAM (OCRAM) region with the given ID.
+int ccu_hps_ram_region_enable(int id);
 
-#define NCORE_CMIU_OFFSET		0xc0000
-#define NCORE_CMIU_SIZE			0x01000
+// Attempts to remap a RAM (OCRAM) region with the given ID to span the given
+// start and end address. It also assigns the security and privilege policy.
+// Regions must be a power-of-two size with a minimum size of 64B.
+int ccu_hps_ram_region_remap(int id, uintptr_t start, uintptr_t end,
+CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-#define NCORE_CSR_OFFSET		0xff000
-#define NCORE_CSADSERO			0x00040
-#define NCORE_CSUIDR			0x00ff8
-#define NCORE_CSIDR			0x00ffc
+// Verifies that all enabled RAM (OCRAM) regions does not overlap.
+int ccu_hps_ram_validate(void);
 
-/* Directory Unit Register Map */
-#define NCORE_DIRUSFER			0x00010
-#define NCORE_DIRUMRHER			0x00070
-#define NCORE_DIRUSFMCR			0x00080
-#define NCORE_DIRUSFMAR			0x00084
+typedef enum ccu_hps_mem_region_e {
+	ccu_hps_mem_region_ddrspace0  = 0,
+	ccu_hps_mem_region_memspace0  = 1,
+	ccu_hps_mem_region_memspace1a = 2,
+	ccu_hps_mem_region_memspace1b = 3,
+	ccu_hps_mem_region_memspace1c = 4,
+	ccu_hps_mem_region_memspace1d = 5,
+	ccu_hps_mem_region_memspace1e = 6,
+} ccu_hps_mem_region_t;
 
-/* Coherent Agent Interface Unit Register Map */
-#define NCORE_CAIUIDR			0x00ffc
+// Disables mem0 (DDR) region with the given ID.
+int ccu_hps_mem0_region_disable(int id);
 
-/* Snoop Enable Register */
-#define NCORE_DIRUCASER0		0x00040
-#define NCORE_DIRUCASER1		0x00044
-#define NCORE_DIRUCASER2		0x00048
-#define NCORE_DIRUCASER3		0x0004c
+// Enables mem0 (DDR) region with the given ID.
+int ccu_hps_mem0_region_enable(int id);
 
-#define NCORE_CSADSER0			0x00040
-#define NCORE_CSADSER1			0x00044
-#define NCORE_CSADSER2			0x00048
-#define NCORE_CSADSER3			0x0004c
+// Attempts to remap mem0 (DDR) region with the given ID to span the given
+// start and end address. It also assigns the security nad privlege policy.
+// Regions must be a power-of-two in size with a minimum size of 64B.
+int ccu_hps_mem0_region_remap(int id, uintptr_t start, uintptr_t end,
+CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-/* Protocols Definition */
-#define ACE_W_DVM			0
-#define ACE_L_W_DVM			1
-#define ACE_WO_DVM			2
-#define ACE_L_WO_DVM			3
+// Verifies that all enabled mem0 (DDR) regions does not overlap.
+int ccu_hps_mem0_validate(void);
 
-/* Bypass OC Ram Firewall */
-#define NCORE_FW_OCRAM_BLK_BASE		0x100200
-#define NCORE_FW_OCRAM_BLK_CGF1		0x04
-#define NCORE_FW_OCRAM_BLK_CGF2		0x08
-#define NCORE_FW_OCRAM_BLK_CGF3		0x0c
-#define NCORE_FW_OCRAM_BLK_CGF4		0x10
+typedef enum ccu_hps_ios_region_e {
+	ccu_hps_ios_region_iospace0a = 0,
+	ccu_hps_ios_region_iospace0b = 1,
+	ccu_hps_ios_region_iospace1a = 2,
+	ccu_hps_ios_region_iospace1b = 3,
+	ccu_hps_ios_region_iospace1c = 4,
+	ccu_hps_ios_region_iospace1d = 5,
+	ccu_hps_ios_region_iospace1e = 6,
+	ccu_hps_ios_region_iospace1f = 7,
+	ccu_hps_ios_region_iospace1g = 8,
+	ccu_hps_ios_region_iospace2a = 9,
+	ccu_hps_ios_region_iospace2b = 10,
+	ccu_hps_ios_region_iospace2c = 11,
+} ccu_hps_ios_region_t;
+
+// Disables the IOS (IO Slave) region with the given ID.
+int ccu_hps_ios_region_disable(int id);
+
+// Enables the IOS (IO Slave) region with the given ID.
+int ccu_hps_ios_region_enable(int id);
 
-#define OCRAM_PRIVILEGED_MASK		BIT(29)
-#define OCRAM_SECURE_MASK		BIT(30)
 
+#define NCORE_CCU_OFFSET			0xf7000000
+
+/* Coherent Sub-System Address Map */
+#define NCORE_CAIU_OFFSET			0x00000
+#define NCORE_CAIU_SIZE				0x01000
+#define NCORE_NCBU_OFFSET			0x60000
+#define NCORE_NCBU_SIZE				0x01000
+#define NCORE_DIRU_OFFSET			0x80000
+#define NCORE_DIRU_SIZE				0x01000
+#define NCORE_CMIU_OFFSET			0xc0000
+#define NCORE_CMIU_SIZE				0x01000
+#define NCORE_CSR_OFFSET			0xff000
+#define NCORE_CSADSERO				0x00040
+#define NCORE_CSUIDR				0x00ff8
+#define NCORE_CSIDR				0x00ffc
+/* Directory Unit Register Map */
+#define NCORE_DIRUSFER				0x00010
+#define NCORE_DIRUMRHER				0x00070
+#define NCORE_DIRUSFMCR				0x00080
+#define NCORE_DIRUSFMAR				0x00084
+/* Coherent Agent Interface Unit Register Map */
+#define NCORE_CAIUIDR				0x00ffc
+/* Snoop Enable Register */
+#define NCORE_DIRUCASER0			0x00040
+#define NCORE_DIRUCASER1			0x00044
+#define NCORE_DIRUCASER2			0x00048
+#define NCORE_DIRUCASER3			0x0004c
+#define NCORE_CSADSER0				0x00040
+#define NCORE_CSADSER1				0x00044
+#define NCORE_CSADSER2				0x00048
+#define NCORE_CSADSER3				0x0004c
+/* Protocols Definition */
+#define ACE_W_DVM				0
+#define ACE_L_W_DVM				1
+#define ACE_WO_DVM				2
+#define ACE_L_WO_DVM				3
+/* Bypass OC Ram Firewall */
+#define NCORE_FW_OCRAM_BLK_BASE			0x100200
+#define NCORE_FW_OCRAM_BLK_CGF1			0x04
+#define NCORE_FW_OCRAM_BLK_CGF2			0x08
+#define NCORE_FW_OCRAM_BLK_CGF3			0x0c
+#define NCORE_FW_OCRAM_BLK_CGF4			0x10
+#define OCRAM_PRIVILEGED_MASK			BIT(29)
+#define OCRAM_SECURE_MASK			BIT(30)
 /* Macros */
-#define NCORE_CCU_REG(base)		(NCORE_CCU_OFFSET + (base))
-#define NCORE_CCU_CSR(reg)		(NCORE_CCU_REG(NCORE_CSR_OFFSET)\
+#define NCORE_CCU_REG(base)			(NCORE_CCU_OFFSET + (base))
+#define NCORE_CCU_CSR(reg)			(NCORE_CCU_REG(NCORE_CSR_OFFSET)\
 						+ (reg))
-#define NCORE_CCU_DIR(reg)		(NCORE_CCU_REG(NCORE_DIRU_OFFSET)\
+#define NCORE_CCU_DIR(reg)			(NCORE_CCU_REG(NCORE_DIRU_OFFSET)\
 						+ (reg))
-#define NCORE_CCU_CAI(reg)		(NCORE_CCU_REG(NCORE_CAIU_OFFSET)\
+#define NCORE_CCU_CAI(reg)			(NCORE_CCU_REG(NCORE_CAIU_OFFSET)\
 						+ (reg))
-
-#define DIRECTORY_UNIT(x, reg)		(NCORE_CCU_DIR(reg)\
+#define DIRECTORY_UNIT(x, reg)			(NCORE_CCU_DIR(reg)\
 						+ NCORE_DIRU_SIZE * (x))
-#define COH_AGENT_UNIT(x, reg)		(NCORE_CCU_CAI(reg)\
+#define COH_AGENT_UNIT(x, reg)			(NCORE_CCU_CAI(reg)\
 						+ NCORE_CAIU_SIZE * (x))
-
-#define COH_CPU0_BYPASS_REG(reg)	(NCORE_CCU_REG(NCORE_FW_OCRAM_BLK_BASE)\
+#define COH_CPU0_BYPASS_REG(reg)		(NCORE_CCU_REG(NCORE_FW_OCRAM_BLK_BASE)\
 						+ (reg))
-
-#define CSUIDR_NUM_CMI(x)		(((x) & 0x3f000000) >> 24)
-#define CSUIDR_NUM_DIR(x)		(((x) & 0x003f0000) >> 16)
-#define CSUIDR_NUM_NCB(x)		(((x) & 0x00003f00) >> 8)
-#define CSUIDR_NUM_CAI(x)		(((x) & 0x0000007f) >> 0)
-
-#define CSIDR_NUM_SF(x)			(((x) & 0x007c0000) >> 18)
-
-#define SNOOP_FILTER_ID(x)		(((x) << 16))
-
-#define CACHING_AGENT_BIT(x)		(((x) & 0x08000) >> 15)
-#define CACHING_AGENT_TYPE(x)		(((x) & 0xf0000) >> 16)
-
+#define CSUIDR_NUM_CMI(x)			(((x) & 0x3f000000) >> 24)
+#define CSUIDR_NUM_DIR(x)			(((x) & 0x003f0000) >> 16)
+#define CSUIDR_NUM_NCB(x)			(((x) & 0x00003f00) >> 8)
+#define CSUIDR_NUM_CAI(x)			(((x) & 0x0000007f) >> 0)
+#define CSIDR_NUM_SF(x)				(((x) & 0x007c0000) >> 18)
+#define SNOOP_FILTER_ID(x)			(((x) << 16))
+#define CACHING_AGENT_BIT(x)			(((x) & 0x08000) >> 15)
+#define CACHING_AGENT_TYPE(x)			(((x) & 0xf0000) >> 16)
 
 typedef struct coh_ss_id {
 	uint8_t num_coh_mem;
@@ -105,5 +426,6 @@
 
 uint32_t init_ncore_ccu(void);
 void ncore_enable_ocram_firewall(void);
+void setup_smmu_stream_id(void);
 
 #endif
diff --git a/plat/intel/soc/common/drivers/combophy/combophy.c b/plat/intel/soc/common/drivers/combophy/combophy.c
new file mode 100644
index 0000000..6c53bc1
--- /dev/null
+++ b/plat/intel/soc/common/drivers/combophy/combophy.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "combophy.h"
+#include "sdmmc/sdmmc.h"
+
+/* Temp assigned handoff data, need to remove when SDM up and run. */
+void config_nand(handoff *hoff_ptr)
+{
+	/* This is hardcoded input value for Combo PHY and SD host controller. */
+	hoff_ptr->peripheral_pwr_gate_array = 0x40;
+
+}
+
+/* DFI configuration */
+int dfi_select(handoff *hoff_ptr)
+{
+	uint32_t data = 0;
+
+	/* Temp assigned handoff data, need to remove when SDM up and run. */
+	handoff reverse_handoff_ptr;
+
+	/* Temp assigned handoff data, need to remove when SDM up and run. */
+	config_nand(&reverse_handoff_ptr);
+
+	if (((reverse_handoff_ptr.peripheral_pwr_gate_array) & PERIPHERAL_SDMMC_MASK) == 0U) {
+		ERROR("SDMMC/NAND is not set properly\n");
+		return -ENXIO;
+	}
+
+	mmio_setbits_32(SOCFPGA_SYSMGR(DFI_INTF),
+		(((reverse_handoff_ptr.peripheral_pwr_gate_array) &
+		PERIPHERAL_SDMMC_MASK) >> PERIPHERAL_SDMMC_OFFSET));
+	data = mmio_read_32(SOCFPGA_SYSMGR(DFI_INTF));
+	if ((data & DFI_INTF_MASK) != (((reverse_handoff_ptr.peripheral_pwr_gate_array) &
+		PERIPHERAL_SDMMC_MASK) >> PERIPHERAL_SDMMC_OFFSET)) {
+		ERROR("DFI is not set properly\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int combo_phy_init(handoff *hoff_ptr)
+{
+	/* SDMMC/NAND DFI selection based on system manager DFI register */
+	int ret = dfi_select(hoff_ptr);
+
+	if (ret != 0U) {
+		ERROR("DFI configuration failed\n");
+		return ret;
+	}
+
+	return 0;
+}
diff --git a/plat/intel/soc/common/drivers/combophy/combophy.h b/plat/intel/soc/common/drivers/combophy/combophy.h
new file mode 100644
index 0000000..ca571f7
--- /dev/null
+++ b/plat/intel/soc/common/drivers/combophy/combophy.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef COMBOPHY_H
+#define COMBOPHY_H
+
+#include <lib/mmio.h>
+
+#include "socfpga_handoff.h"
+
+#define PERIPHERAL_SDMMC_MASK		0x60
+#define PERIPHERAL_SDMMC_OFFSET		6
+#define DFI_INTF_MASK			0x1
+
+/* FUNCTION DEFINATION */
+/*
+ * @brief Nand controller initialization function
+ *
+ * @hoff_ptr: Pointer to the hand-off data
+ * Return: 0 on success, a negative errno on failure
+ */
+int combo_phy_init(handoff *hoff_ptr);
+int dfi_select(handoff *hoff_ptr);
+
+#endif
diff --git a/plat/intel/soc/common/drivers/ddr/ddr.c b/plat/intel/soc/common/drivers/ddr/ddr.c
new file mode 100644
index 0000000..188302f
--- /dev/null
+++ b/plat/intel/soc/common/drivers/ddr/ddr.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include "ddr.h"
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+int ddr_calibration_check(void)
+{
+	// DDR calibration check
+	int status = 0;
+	uint32_t u32data_read = 0;
+
+	NOTICE("DDR: Access address 0x%x:...\n", IO96B_0_REG_BASE);
+	u32data_read = mmio_read_32(IO96B_0_REG_BASE);
+	NOTICE("DDR: Access address 0x%x: read 0x%04x\n", IO96B_0_REG_BASE, u32data_read);
+
+	if (u32data_read == -EPERM) {
+		status = -EPERM;
+		assert(u32data_read);
+	}
+
+	u32data_read = 0x0;
+	NOTICE("DDR: Access address 0x%x: ...\n", IO96B_1_REG_BASE);
+	u32data_read = mmio_read_32(IO96B_1_REG_BASE);
+	NOTICE("DDR: Access address 0x%x: read 0x%04x\n", IO96B_1_REG_BASE, u32data_read);
+
+	if (u32data_read == -EPERM) {
+		status = -EPERM;
+		assert(u32data_read);
+	}
+
+	return status;
+}
+
+int iossm_mb_init(void)
+{
+	// int status;
+
+	// Update according to IOSSM mailbox spec
+
+	// if (status) {
+		// return status;
+	// }
+
+	return 0;
+}
+
+int wait_respond(uint16_t timeout)
+{
+	uint32_t status = 0;
+	uint32_t count = 0;
+	uint32_t data = 0;
+
+	/* Wait status command response ready */
+	do {
+		data = mmio_read_32(IO96B_CSR_REG(CMD_RESPONSE_STATUS));
+		count++;
+		if (count >= timeout) {
+			return -ETIMEDOUT;
+		}
+
+	} while (STATUS_COMMAND_RESPONSE(data) != STATUS_COMMAND_RESPONSE_READY);
+
+	status = (data & STATUS_GENERAL_ERROR_MASK) >> STATUS_GENERAL_ERROR_OFFSET;
+	if (status != 0) {
+		return status;
+	}
+
+	status = (data & STATUS_CMD_RESPONSE_ERROR_MASK) >> STATUS_CMD_RESPONSE_ERROR_OFFSET;
+	if (status != 0) {
+		return status;
+	}
+
+	return status;
+}
+
+int iossm_mb_read_response(void)
+{
+	uint32_t status = 0;
+	unsigned int i;
+	uint32_t resp_data[IOSSM_RESP_MAX_WORD_SIZE];
+	uint32_t resp_param_reg;
+
+	// Check STATUS_CMD_RESPONSE_DATA_PTR_VALID in
+	// STATUS_COMMAND_RESPONSE to ensure data pointer response
+
+	/* Read CMD_RESPONSE_STATUS and CMD_RESPONSE_DATA_* */
+	resp_data[0] = mmio_read_32(IO96B_CSR_REG(CMD_RESPONSE_STATUS));
+	resp_data[0] = (resp_data[0] & CMD_RESPONSE_DATA_SHORT_MASK) >>
+			CMD_RESPONSE_DATA_SHORT_OFFSET;
+	resp_param_reg = CMD_RESPONSE_STATUS;
+	for (i = 1; i < IOSSM_RESP_MAX_WORD_SIZE; i++) {
+		resp_param_reg = resp_param_reg - CMD_RESPONSE_OFFSET;
+		resp_data[i] = mmio_read_32(IO96B_CSR_REG(resp_param_reg));
+	}
+
+	/* Wait for STATUS_COMMAND_RESPONSE_READY*/
+	status = wait_respond(1000);
+
+	/* Read CMD_RESPONSE_STATUS and CMD_RESPONSE_DATA_* */
+	mmio_setbits_32(STATUS_COMMAND_RESPONSE(IO96B_CSR_REG(
+			CMD_RESPONSE_STATUS)),
+			STATUS_COMMAND_RESPONSE_READY_CLEAR);
+
+	return status;
+}
+
+int iossm_mb_send(uint32_t cmd_target_ip_type, uint32_t cmd_target_ip_instance_id,
+			uint32_t cmd_type, uint32_t cmd_opcode, uint32_t *args,
+			unsigned int len)
+{
+	unsigned int i;
+	uint32_t status = 0;
+	uint32_t cmd_req;
+	uint32_t cmd_param_reg;
+
+	cmd_target_ip_type = (cmd_target_ip_type & CMD_TARGET_IP_TYPE_MASK) <<
+				CMD_TARGET_IP_TYPE_OFFSET;
+	cmd_target_ip_instance_id = (cmd_target_ip_instance_id &
+				CMD_TARGET_IP_INSTANCE_ID_MASK) <<
+				CMD_TARGET_IP_INSTANCE_ID_OFFSET;
+	cmd_type = (cmd_type & CMD_TYPE_MASK) << CMD_TYPE_OFFSET;
+	cmd_opcode = (cmd_opcode & CMD_OPCODE_MASK) << CMD_OPCODE_OFFSET;
+	cmd_req = cmd_target_ip_type | cmd_target_ip_instance_id | cmd_type |
+			cmd_opcode;
+
+	/* send mailbox request */
+	IOSSM_MB_WRITE(IO96B_CSR_REG(CMD_REQ), cmd_req);
+	if (len != 0) {
+		cmd_param_reg = CMD_REQ;
+		for (i = 0; i < len; i++) {
+			cmd_param_reg = cmd_param_reg - CMD_PARAM_OFFSET;
+			IOSSM_MB_WRITE(IO96B_CSR_REG(cmd_param_reg), args[i]);
+		}
+	}
+
+	status = iossm_mb_read_response();
+	if (status != 0) {
+		return status;
+	}
+
+	return status;
+}
+
+int ddr_iossm_mailbox_cmd(uint32_t cmd_opcode)
+{
+	// IOSSM
+	uint32_t status = 0;
+	unsigned int i = 0;
+	uint32_t payload[IOSSM_CMD_MAX_WORD_SIZE] = {0U};
+
+	switch (cmd_opcode) {
+	case CMD_INIT:
+		status = iossm_mb_init();
+		break;
+
+	case OPCODE_GET_MEM_INTF_INFO:
+		status = iossm_mb_send(0, 0, MBOX_CMD_GET_SYS_INFO,
+		OPCODE_GET_MEM_INTF_INFO, payload, i);
+		break;
+
+	case OPCODE_GET_MEM_TECHNOLOGY:
+		status = iossm_mb_send(0, 0, MBOX_CMD_GET_MEM_INFO,
+		OPCODE_GET_MEM_TECHNOLOGY, payload, i);
+		break;
+
+	case OPCODE_GET_MEM_WIDTH_INFO:
+		status = iossm_mb_send(0, 0, MBOX_CMD_GET_MEM_INFO,
+		OPCODE_GET_MEM_WIDTH_INFO, payload, i);
+		break;
+
+	case OPCODE_ECC_ENABLE_STATUS:
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_ENABLE_STATUS,
+		payload, i);
+		break;
+
+	case OPCODE_ECC_INTERRUPT_MASK:
+		// payload[i] = CMD_PARAM_0 [16:0]: ECC_INTERRUPT_MASK
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_INTERRUPT_MASK,
+		payload, i);
+		break;
+
+	case OPCODE_ECC_SCRUB_MODE_0_START:
+		// payload[i] = CMD_PARAM_0 [15:0]: ECC_SCRUB_INTERVAL
+		//i++;
+		// payload[i] = CMD_PARAM_1 [11:0]: ECC_SCRUB_LEN
+		//i++;
+		// payload[i] = CMD_PARAM_2 [0:0]: ECC_SCRUB_FULL_MEM
+		//i++;
+		// payload[i]= CMD_PARAM_3 [31:0]: ECC_SCRUB_START_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_4 [5:0]: ECC_SCRUB_START_ADDR [36:32]
+		//i++;
+		// payload[i] = CMD_PARAM_5 [31:0]: ECC_SCRUB_END_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_6 [5:0]: ECC_SCRUB_END_ADDR [36:32]
+		//i++;
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_SCRUB_MODE_0_START,
+		payload, i);
+		break;
+
+	case OPCODE_ECC_SCRUB_MODE_1_START:
+		// payload[i] = CMD_PARAM_0 [15:0]: ECC_SCRUB_IDLE_CNT
+		//i++;
+		// payload[i] = CMD_PARAM_1 [11:0]: ECC_SCRUB_LEN
+		//i++;
+		// payload[i] = CMD_PARAM_2 [0:0]: ECC_SCRUB_FULL_MEM
+		//i++;
+		// payload[i] = CMD_PARAM_3 [31:0]: ECC_SCRUB_START_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_4 [5:0]: ECC_SCRUB_START_ADDR [36:32]
+		//i++;
+		// payload[i] = CMD_PARAM_5 [31:0]: ECC_SCRUB_END_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_6 [5:0]: ECC_SCRUB_END_ADDR [36:32]
+		//i++;
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_SCRUB_MODE_1_START,
+		payload, i);
+		break;
+
+	case OPCODE_BIST_RESULTS_STATUS:
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_BIST_RESULTS_STATUS,
+		payload, i);
+		break;
+
+	case OPCODE_BIST_MEM_INIT_START:
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_BIST_MEM_INIT_START,
+		payload, i);
+		break;
+
+	case OPCODE_TRIG_MEM_CAL:
+		status = iossm_mb_send(0, 0, MBOX_CMD_TRIG_MEM_CAL_OP,
+		OPCODE_TRIG_MEM_CAL, payload, i);
+		break;
+
+	default:
+		break;
+	}
+
+	if (status == -EPERM) {
+		assert(status);
+	}
+
+	return status;
+}
+
+int ddr_config_handoff(handoff *hoff_ptr)
+{
+	/* Populate DDR handoff data */
+	/* TODO: To add in DDR handoff configuration once available */
+	return 0;
+}
+
+// DDR firewall and non secure access
+void ddr_enable_ns_access(void)
+{
+	/* Please set the ddr non secure registers accordingly */
+
+	mmio_setbits_32(CCU_REG(DMI0_DMIUSMCTCR),
+			CCU_DMI_ALLOCEN | CCU_DMI_LOOKUPEN);
+	mmio_setbits_32(CCU_REG(DMI1_DMIUSMCTCR),
+			CCU_DMI_ALLOCEN | CCU_DMI_LOOKUPEN);
+
+	/* TODO: To add in CCU NCORE OCRAM bypass mask for non secure registers */
+	NOTICE("DDR non secure configured\n");
+}
+
+void ddr_enable_firewall(void)
+{
+	/* Please set the ddr firewall registers accordingly */
+	/* TODO: To add in CCU NCORE OCRAM bypass mask for firewall registers */
+	NOTICE("DDR firewall enabled\n");
+}
+
+bool is_ddr_init_in_progress(void)
+{
+	uint32_t reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
+
+	if (reg & SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0_MASK) {
+		return true;
+	}
+	return false;
+}
+
+int ddr_init(void)
+{
+	// DDR driver initialization
+	int status = -EPERM;
+	uint32_t cmd_opcode = 0;
+
+	// Check and set Boot Scratch Register
+	if (is_ddr_init_in_progress()) {
+		return status;
+	}
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0), 0x01);
+
+	// Populate DDR handoff data
+	handoff reverse_handoff_ptr;
+
+	if (!socfpga_get_handoff(&reverse_handoff_ptr)) {
+		assert(status);
+	}
+	status = ddr_config_handoff(&reverse_handoff_ptr);
+	if (status == -EPERM) {
+		assert(status);
+	}
+
+	// CCU and firewall setup
+	ddr_enable_ns_access();
+	ddr_enable_firewall();
+
+	// DDR calibration check
+	status = ddr_calibration_check();
+	if (status == -EPERM) {
+		assert(status);
+	}
+
+	// DDR mailbox command
+	status = ddr_iossm_mailbox_cmd(cmd_opcode);
+	if (status != 0) {
+		assert(status);
+	}
+
+	// Check and set Boot Scratch Register
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0), 0x00);
+
+	NOTICE("DDR init successfully\n");
+	return status;
+}
diff --git a/plat/intel/soc/common/drivers/ddr/ddr.h b/plat/intel/soc/common/drivers/ddr/ddr.h
new file mode 100644
index 0000000..416b64e
--- /dev/null
+++ b/plat/intel/soc/common/drivers/ddr/ddr.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDR_H
+#define DDR_H
+
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+/* MACRO DEFINATION */
+#define IO96B_0_REG_BASE				0x18400000
+#define IO96B_1_REG_BASE				0x18800000
+#define IO96B_CSR_BASE					0x05000000
+#define IO96B_CSR_REG(reg)				(IO96B_CSR_BASE + reg)
+
+#define IOSSM_CMD_MAX_WORD_SIZE				7U
+#define IOSSM_RESP_MAX_WORD_SIZE			4U
+
+#define CCU_REG_BASE					0x1C000000
+#define DMI0_DMIUSMCTCR					0x7300
+#define DMI1_DMIUSMCTCR					0x8300
+#define CCU_DMI_ALLOCEN					BIT(1)
+#define CCU_DMI_LOOKUPEN				BIT(2)
+#define CCU_REG(reg)					(CCU_REG_BASE + reg)
+
+// CMD_RESPONSE_STATUS Register
+#define CMD_RESPONSE_STATUS				0x45C
+#define CMD_RESPONSE_OFFSET				0x4
+#define CMD_RESPONSE_DATA_SHORT_MASK			GENMASK(31, 16)
+#define CMD_RESPONSE_DATA_SHORT_OFFSET			16
+#define STATUS_CMD_RESPONSE_ERROR_MASK			GENMASK(7, 5)
+#define STATUS_CMD_RESPONSE_ERROR_OFFSET		5
+#define STATUS_GENERAL_ERROR_MASK			GENMASK(4, 1)
+#define STATUS_GENERAL_ERROR_OFFSET			1
+#define STATUS_COMMAND_RESPONSE_READY			0x1
+#define STATUS_COMMAND_RESPONSE_READY_CLEAR		0x0
+#define STATUS_COMMAND_RESPONSE_READY_MASK		0x1
+#define STATUS_COMMAND_RESPONSE_READY_OFFSET		0
+#define STATUS_COMMAND_RESPONSE(x)			(((x) & \
+							STATUS_COMMAND_RESPONSE_READY_MASK) >> \
+							STATUS_COMMAND_RESPONSE_READY_OFFSET)
+
+// CMD_REQ Register
+#define CMD_STATUS					0x400
+#define CMD_PARAM					0x438
+#define CMD_REQ						0x43C
+#define CMD_PARAM_OFFSET				0x4
+#define CMD_TARGET_IP_TYPE_MASK				GENMASK(31, 29)
+#define CMD_TARGET_IP_TYPE_OFFSET			29
+#define CMD_TARGET_IP_INSTANCE_ID_MASK			GENMASK(28, 24)
+#define CMD_TARGET_IP_INSTANCE_ID_OFFSET		24
+#define CMD_TYPE_MASK					GENMASK(23, 16)
+#define CMD_TYPE_OFFSET					16
+#define CMD_OPCODE_MASK					GENMASK(15, 0)
+#define CMD_OPCODE_OFFSET				0
+
+#define CMD_INIT					0
+
+#define OPCODE_GET_MEM_INTF_INFO			0x0001
+#define OPCODE_GET_MEM_TECHNOLOGY			0x0002
+#define OPCODE_GET_MEM_WIDTH_INFO			0x0004
+#define OPCODE_TRIG_MEM_CAL				0x000A
+#define OPCODE_ECC_ENABLE_STATUS			0x0102
+#define OPCODE_ECC_INTERRUPT_MASK			0x0105
+#define OPCODE_ECC_SCRUB_MODE_0_START			0x0202
+#define OPCODE_ECC_SCRUB_MODE_1_START			0x0203
+#define OPCODE_BIST_RESULTS_STATUS			0x0302
+#define OPCODE_BIST_MEM_INIT_START			0x0303
+// Please update according to IOSSM mailbox spec
+#define MBOX_ID_IOSSM					0x00
+#define MBOX_CMD_GET_SYS_INFO				0x01
+// Please update according to IOSSM mailbox spec
+#define MBOX_CMD_GET_MEM_INFO				0x02
+#define MBOX_CMD_TRIG_CONTROLLER_OP			0x04
+#define MBOX_CMD_TRIG_MEM_CAL_OP			0x05
+#define MBOX_CMD_POKE_REG				0xFD
+#define MBOX_CMD_PEEK_REG				0xFE
+#define MBOX_CMD_GET_DEBUG_LOG				0xFF
+// Please update according to IOSSM mailbox spec
+#define MBOX_CMD_DIRECT					0x00
+
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0_MASK		0x01
+
+#define IOSSM_MB_WRITE(addr, data)			mmio_write_32(addr, data)
+
+/* FUNCTION DEFINATION */
+int ddr_calibration_check(void);
+
+int iossm_mb_init(void);
+
+int iossm_mb_read_response(void);
+
+int iossm_mb_send(uint32_t cmd_target_ip_type, uint32_t cmd_target_ip_instance_id,
+			uint32_t cmd_type, uint32_t cmd_opcode, uint32_t *args,
+			unsigned int len);
+
+int ddr_iossm_mailbox_cmd(uint32_t cmd);
+
+int ddr_init(void);
+
+int ddr_config_handoff(handoff *hoff_ptr);
+
+void ddr_enable_ns_access(void);
+
+void ddr_enable_firewall(void);
+
+bool is_ddr_init_in_progress(void);
+
+#endif
diff --git a/plat/intel/soc/common/drivers/nand/nand.c b/plat/intel/soc/common/drivers/nand/nand.c
new file mode 100644
index 0000000..c6acbe3
--- /dev/null
+++ b/plat/intel/soc/common/drivers/nand/nand.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_nand.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include "nand.h"
+
+#include "agilex5_pinmux.h"
+#include "combophy/combophy.h"
+
+/* Pinmux configuration */
+static void nand_pinmux_config(void)
+{
+	mmio_write_32(SOCFPGA_PINMUX(PIN0SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN1SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN2SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN3SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN4SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN5SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN6SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN7SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN8SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN9SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN10SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN11SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN12SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN13SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN14SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN16SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN17SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN18SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN19SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN20SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN21SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN22SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN23SEL), SOCFPGA_PINMUX_SEL_NAND);
+}
+
+int nand_init(handoff *hoff_ptr)
+{
+	/* NAND pin mux configuration */
+	nand_pinmux_config();
+
+	return cdns_nand_host_init();
+}
diff --git a/plat/intel/soc/common/drivers/nand/nand.h b/plat/intel/soc/common/drivers/nand/nand.h
new file mode 100644
index 0000000..b060a72
--- /dev/null
+++ b/plat/intel/soc/common/drivers/nand/nand.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDR_H
+#define DDR_H
+
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+/* FUNCTION DEFINATION */
+/*
+ * @brief Nand controller initialization function
+ *
+ * @hoff_ptr: Pointer to the hand-off data
+ * Return: 0 on success, a negative errno on failure
+ */
+int nand_init(handoff *hoff_ptr);
+
+#endif
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
index cecf560..da8a8bd 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
@@ -13,6 +13,7 @@
 #include <drivers/console.h>
 
 #include "cadence_qspi.h"
+#include "socfpga_plat_def.h"
 
 #define LESS(a, b)   (((a) < (b)) ? (a) : (b))
 #define MORE(a, b)   (((a) > (b)) ? (a) : (b))
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.h b/plat/intel/soc/common/drivers/qspi/cadence_qspi.h
index cfef585..104ab5f 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.h
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.h
@@ -10,8 +10,6 @@
 
 #define CAD_QSPI_MICRON_N25Q_SUPPORT		1
 
-#define CAD_QSPI_OFFSET				0xff8d2000
-
 #define CAD_INVALID				-1
 #define CAD_QSPI_ERROR				-2
 
@@ -38,8 +36,6 @@
 #define CAD_QSPI_CFG_SELCLKPHASE_CLR_MSK	0xfffffffb
 #define CAD_QSPI_CFG_SELCLKPOL_CLR_MSK		0xfffffffd
 
-#define CAD_QSPIDATA_OFST			0xff900000
-
 #define CAD_QSPI_DELAY				0xc
 #define CAD_QSPI_DELAY_CSSOT(x)			(((x) & 0xff) << 0)
 #define CAD_QSPI_DELAY_CSEOT(x)			(((x) & 0xff) << 8)
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
new file mode 100644
index 0000000..8666f54
--- /dev/null
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
@@ -0,0 +1,769 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_combo_phy.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "agilex5_pinmux.h"
+#include "sdmmc.h"
+
+static const struct mmc_ops *ops;
+static unsigned int mmc_ocr_value;
+static struct mmc_csd_emmc mmc_csd;
+static struct sd_switch_status sd_switch_func_status;
+static unsigned char mmc_ext_csd[512] __aligned(16);
+static unsigned int mmc_flags;
+static struct mmc_device_info *mmc_dev_info;
+static unsigned int rca;
+static unsigned int scr[2]__aligned(16) = { 0 };
+
+extern const struct mmc_ops cdns_sdmmc_ops;
+extern struct cdns_sdmmc_params cdns_params;
+extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
+extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
+
+static bool is_cmd23_enabled(void)
+{
+	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
+}
+
+static bool is_sd_cmd6_enabled(void)
+{
+	return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
+}
+
+/* TODO: Will romove once ATF driver is developed */
+void sdmmc_pin_config(void)
+{
+	/* temp use base + addr. Official must change to common method */
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x00, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x04, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x08, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x0C, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x10, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x14, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x18, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x1C, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x20, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x24, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x28, 0x0);
+}
+
+static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+			unsigned int r_type, unsigned int *r_data)
+{
+	struct mmc_cmd cmd;
+	int ret;
+
+	zeromem(&cmd, sizeof(struct mmc_cmd));
+
+	cmd.cmd_idx = idx;
+	cmd.cmd_arg = arg;
+	cmd.resp_type = r_type;
+
+	ret = ops->send_cmd(&cmd);
+
+	if ((ret == 0) && (r_data != NULL)) {
+		int i;
+
+		for (i = 0; i < 4; i++) {
+			*r_data = cmd.resp_data[i];
+			r_data++;
+		}
+	}
+
+	if (ret != 0) {
+		VERBOSE("Send command %u error: %d\n", idx, ret);
+	}
+
+	return ret;
+}
+
+static int sdmmc_device_state(void)
+{
+	int retries = DEFAULT_SDMMC_MAX_RETRIES;
+	unsigned int resp_data[4];
+
+	do {
+		int ret;
+
+		if (retries == 0) {
+			ERROR("CMD13 failed after %d retries\n",
+			      DEFAULT_SDMMC_MAX_RETRIES);
+			return -EIO;
+		}
+
+		ret = sdmmc_send_cmd(MMC_CMD(13), rca << RCA_SHIFT_OFFSET,
+				   MMC_RESPONSE_R1, &resp_data[0]);
+		if (ret != 0) {
+			retries--;
+			continue;
+		}
+
+		if ((resp_data[0] & STATUS_SWITCH_ERROR) != 0U) {
+			return -EIO;
+		}
+
+		retries--;
+	} while ((resp_data[0] & STATUS_READY_FOR_DATA) == 0U);
+
+	return MMC_GET_STATE(resp_data[0]);
+}
+
+static int sdmmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
+{
+	int ret;
+
+	ret = sdmmc_send_cmd(MMC_CMD(6),
+			   EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
+			   EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
+			   MMC_RESPONSE_R1B, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
+static int sdmmc_mmc_sd_switch(unsigned int bus_width)
+{
+	int ret;
+	int retries = DEFAULT_SDMMC_MAX_RETRIES;
+	unsigned int bus_width_arg = 0;
+
+	/* CMD55: Application Specific Command */
+	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R5, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACMD51: SEND_SCR */
+	do {
+		ret = sdmmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
+		if ((ret != 0) && (retries == 0)) {
+			ERROR("ACMD51 failed after %d retries (ret=%d)\n",
+			      DEFAULT_SDMMC_MAX_RETRIES, ret);
+			return ret;
+		}
+
+		retries--;
+	} while (ret != 0);
+
+	ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
+	    (bus_width == MMC_BUS_WIDTH_4)) {
+		bus_width_arg = 2;
+	}
+
+	/* CMD55: Application Specific Command */
+	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R5, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACMD6: SET_BUS_WIDTH */
+	ret = sdmmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
+static int sdmmc_set_ios(unsigned int clk, unsigned int bus_width)
+{
+	int ret;
+	unsigned int width = bus_width;
+
+	if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
+		if (width == MMC_BUS_WIDTH_8) {
+			WARN("Wrong bus config for SD-card, force to 4\n");
+			width = MMC_BUS_WIDTH_4;
+		}
+		ret = sdmmc_mmc_sd_switch(width);
+		if (ret != 0) {
+			return ret;
+		}
+	} else if (mmc_csd.spec_vers == 4U) {
+		ret = sdmmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
+				      (unsigned int)width);
+		if (ret != 0) {
+			return ret;
+		}
+	} else {
+		VERBOSE("Wrong MMC type or spec version\n");
+	}
+
+	return ops->set_ios(clk, width);
+}
+
+static int sdmmc_fill_device_info(void)
+{
+	unsigned long long c_size;
+	unsigned int speed_idx;
+	unsigned int nb_blocks;
+	unsigned int freq_unit;
+	int ret = 0;
+	struct mmc_csd_sd_v2 *csd_sd_v2;
+
+	switch (mmc_dev_info->mmc_dev_type) {
+	case MMC_IS_EMMC:
+		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
+
+		ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
+				   sizeof(mmc_ext_csd));
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* MMC CMD8: SEND_EXT_CSD */
+		ret = sdmmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
+				sizeof(mmc_ext_csd));
+		if (ret != 0) {
+			return ret;
+		}
+
+		do {
+			ret = sdmmc_device_state();
+			if (ret < 0) {
+				return ret;
+			}
+		} while (ret != MMC_STATE_TRAN);
+
+		nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
+
+		mmc_dev_info->device_size = (unsigned long long)nb_blocks *
+			mmc_dev_info->block_size;
+
+		break;
+
+	case MMC_IS_SD:
+		/*
+		 * Use the same mmc_csd struct, as required fields here
+		 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
+		 */
+		mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
+
+		c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
+			 (unsigned long long)mmc_csd.c_size_low;
+		assert(c_size != 0xFFFU);
+
+		mmc_dev_info->device_size = (c_size + 1U) *
+					    BIT_64(mmc_csd.c_size_mult + 2U) *
+					    mmc_dev_info->block_size;
+
+		break;
+
+	case MMC_IS_SD_HC:
+		assert(mmc_csd.csd_structure == 1U);
+
+		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
+
+		/* Need to use mmc_csd_sd_v2 struct */
+		csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
+		c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
+			 (unsigned long long)csd_sd_v2->c_size_low;
+
+		mmc_dev_info->device_size = (c_size + 1U) << SDMMC_MULT_BY_512K_SHIFT;
+
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret < 0) {
+		return ret;
+	}
+
+	speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
+			 CSD_TRAN_SPEED_MULT_SHIFT;
+
+	assert(speed_idx > 0U);
+
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
+	} else {
+		mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
+	}
+
+	freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
+	while (freq_unit != 0U) {
+		mmc_dev_info->max_bus_freq *= 10U;
+		--freq_unit;
+	}
+
+	mmc_dev_info->max_bus_freq *= 10000U;
+
+	return 0;
+}
+
+static int sdmmc_sd_switch(unsigned int mode, unsigned char group,
+		     unsigned char func)
+{
+	unsigned int group_shift = (group - 1U) * 4U;
+	unsigned int group_mask = GENMASK(group_shift + 3U,  group_shift);
+	unsigned int arg;
+	int ret;
+
+	ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
+			   sizeof(sd_switch_func_status));
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* MMC CMD6: SWITCH_FUNC */
+	arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
+	arg &= ~group_mask;
+	arg |= func << group_shift;
+	ret = sdmmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ops->read(0, (uintptr_t)&sd_switch_func_status,
+			 sizeof(sd_switch_func_status));
+}
+
+static int sdmmc_sd_send_op_cond(void)
+{
+	int n;
+	unsigned int resp_data[4];
+
+	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
+		int ret;
+
+		/* CMD55: Application Specific Command */
+		ret = sdmmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* ACMD41: SD_SEND_OP_COND */
+		ret = sdmmc_send_cmd(MMC_ACMD(41), OCR_HCS |
+			mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
+			&resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((resp_data[0] & OCR_POWERUP) != 0U) {
+			mmc_ocr_value = resp_data[0];
+
+			if ((mmc_ocr_value & OCR_HCS) != 0U) {
+				mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
+			} else {
+				mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+			}
+
+			return 0;
+		}
+
+		mdelay(10);
+	}
+
+	ERROR("ACMD41 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
+
+	return -EIO;
+}
+
+static int sdmmc_reset_to_idle(void)
+{
+	int ret;
+
+	/* CMD0: reset to IDLE */
+	ret = sdmmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	mdelay(2);
+
+	return 0;
+}
+
+static int sdmmc_send_op_cond(void)
+{
+	int ret, n;
+	unsigned int resp_data[4];
+
+	ret = sdmmc_reset_to_idle();
+	if (ret != 0) {
+		return ret;
+	}
+
+	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
+		ret = sdmmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
+				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
+				   MMC_RESPONSE_R3, &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((resp_data[0] & OCR_POWERUP) != 0U) {
+			mmc_ocr_value = resp_data[0];
+			return 0;
+		}
+
+		mdelay(10);
+	}
+
+	ERROR("CMD1 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
+
+	return -EIO;
+}
+
+static int sdmmc_enumerate(unsigned int clk, unsigned int bus_width)
+{
+	int ret;
+	unsigned int resp_data[4];
+
+	ops->init();
+
+	ret = sdmmc_reset_to_idle();
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		ret = sdmmc_send_op_cond();
+	} else {
+		/* CMD8: Send Interface Condition Command */
+		ret = sdmmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
+				   MMC_RESPONSE_R5, &resp_data[0]);
+
+		if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
+			ret = sdmmc_sd_send_op_cond();
+		}
+	}
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD2: Card Identification */
+	ret = sdmmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD3: Set Relative Address */
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		rca = MMC_FIX_RCA;
+		ret = sdmmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
+				   MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return ret;
+		}
+	} else {
+		ret = sdmmc_send_cmd(MMC_CMD(3), 0,
+				   MMC_RESPONSE_R6, &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		rca = (resp_data[0] & 0xFFFF0000U) >> 16;
+	}
+
+	/* CMD9: CSD Register */
+	ret = sdmmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R2, &resp_data[0]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	memcpy(&mmc_csd, &resp_data, sizeof(resp_data));
+
+	/* CMD7: Select Card */
+	ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret != MMC_STATE_TRAN);
+
+	ret = sdmmc_set_ios(clk, bus_width);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = sdmmc_fill_device_info();
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (is_sd_cmd6_enabled() &&
+	    (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
+		/* Try to switch to High Speed Mode */
+		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
+			/* High speed not supported, keep default speed */
+			return 0;
+		}
+
+		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
+			/* Cannot switch to high speed, keep default speed */
+			return 0;
+		}
+
+		mmc_dev_info->max_bus_freq = 50000000U;
+		ret = ops->set_ios(clk, bus_width);
+	}
+
+	return ret;
+}
+
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size)
+{
+	int ret;
+	unsigned int cmd_idx, cmd_arg;
+
+	assert((ops != NULL) &&
+	       (ops->read != NULL) &&
+	       (size != 0U) &&
+	       ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = ops->prepare(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	if (is_cmd23_enabled()) {
+		/* Set block count */
+		ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
+				   MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+
+		cmd_idx = MMC_CMD(18);
+	} else {
+		if (size > MMC_BLOCK_SIZE) {
+			cmd_idx = MMC_CMD(18);
+		} else {
+			cmd_idx = MMC_CMD(17);
+		}
+	}
+
+	if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
+	    (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
+		cmd_arg = lba * MMC_BLOCK_SIZE;
+	} else {
+		cmd_arg = lba;
+	}
+
+	ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = ops->read(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	/* Wait buffer empty */
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
+
+	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
+		ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size)
+{
+	int ret;
+	unsigned int cmd_idx, cmd_arg;
+
+	assert((ops != NULL) &&
+	       (ops->write != NULL) &&
+	       (size != 0U) &&
+	       ((buf & MMC_BLOCK_MASK) == 0U) &&
+	       ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = ops->prepare(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	if (is_cmd23_enabled()) {
+		/* Set block count */
+		ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
+				   MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+
+		cmd_idx = MMC_CMD(25);
+	} else {
+		if (size > MMC_BLOCK_SIZE) {
+			cmd_idx = MMC_CMD(25);
+		} else {
+			cmd_idx = MMC_CMD(24);
+		}
+	}
+
+	if ((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) {
+		cmd_arg = lba * MMC_BLOCK_SIZE;
+	} else {
+		cmd_arg = lba;
+	}
+
+	ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = ops->write(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	/* Wait buffer empty */
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_RCV));
+
+	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
+		ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
+	     unsigned int width, unsigned int flags,
+	     struct mmc_device_info *device_info)
+{
+	assert((ops_ptr != NULL) &&
+	       (ops_ptr->init != NULL) &&
+	       (ops_ptr->send_cmd != NULL) &&
+	       (ops_ptr->set_ios != NULL) &&
+	       (ops_ptr->prepare != NULL) &&
+	       (ops_ptr->read != NULL) &&
+	       (ops_ptr->write != NULL) &&
+	       (device_info != NULL) &&
+	       (clk != 0) &&
+	       ((width == MMC_BUS_WIDTH_1) ||
+		(width == MMC_BUS_WIDTH_4) ||
+		(width == MMC_BUS_WIDTH_8) ||
+		(width == MMC_BUS_WIDTH_DDR_4) ||
+		(width == MMC_BUS_WIDTH_DDR_8)));
+
+	ops = ops_ptr;
+	mmc_flags = flags;
+	mmc_dev_info = device_info;
+
+	return sdmmc_enumerate(clk, width);
+}
+
+int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params, struct mmc_device_info *info)
+{
+	int result = 0;
+
+	/* SDMMC pin mux configuration */
+	sdmmc_pin_config();
+	cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (result < 0) {
+		return result;
+	}
+
+	assert((params != NULL) &&
+	       ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
+	       ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
+	       ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
+		   ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
+		   ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
+	       (params->desc_size > 0) &&
+	       (params->clk_rate > 0) &&
+	       ((params->bus_width == MMC_BUS_WIDTH_1) ||
+		(params->bus_width == MMC_BUS_WIDTH_4) ||
+		(params->bus_width == MMC_BUS_WIDTH_8)));
+
+	memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
+	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
+	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
+
+	result = sd_or_mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
+		params->flags, info);
+
+	return result;
+}
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
new file mode 100644
index 0000000..16c6b04
--- /dev/null
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SDMMC_H
+#define SDMMC_H
+
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+#define PERIPHERAL_SDMMC_MASK			0x60
+#define PERIPHERAL_SDMMC_OFFSET			6
+
+#define DEFAULT_SDMMC_MAX_RETRIES		5
+#define SEND_SDMMC_OP_COND_MAX_RETRIES		100
+#define SDMMC_MULT_BY_512K_SHIFT		19
+
+static const unsigned char tran_speed_base[16] = {
+	0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
+};
+
+static const unsigned char sd_tran_speed_base[16] = {
+	0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
+};
+
+
+/* FUNCTION DEFINATION */
+/*
+ * @brief SDMMC controller initialization function
+ *
+ * @hoff_ptr: Pointer to the hand-off data
+ * Return: 0 on success, a negative errno on failure
+ */
+int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params,
+	     struct mmc_device_info *info);
+int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
+	     unsigned int width, unsigned int flags,
+	     struct mmc_device_info *device_info);
+void sdmmc_pin_config(void);
+#endif
diff --git a/plat/intel/soc/common/drivers/wdt/watchdog.h b/plat/intel/soc/common/drivers/wdt/watchdog.h
index 2c72463..4ee4cff 100644
--- a/plat/intel/soc/common/drivers/wdt/watchdog.h
+++ b/plat/intel/soc/common/drivers/wdt/watchdog.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,11 @@
 #ifndef CAD_WATCHDOG_H
 #define CAD_WATCHDOG_H
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define WDT_BASE			(0x10D00200)
+#else
 #define WDT_BASE			(0xFFD00200)
+#endif
 #define WDT_REG_SIZE_OFFSET		(0x4)
 #define WDT_MIN_CYCLES			(65536)
 #define WDT_PERIOD			(20)
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 2b3f144..49fc567 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,28 +12,37 @@
 #include <common/interrupt_props.h>
 #include <common/tbbr/tbbr_img_def.h>
 #include <plat/common/common_def.h>
+#include "socfpga_plat_def.h"
 
 /* Platform Type */
 #define PLAT_SOCFPGA_STRATIX10			1
 #define PLAT_SOCFPGA_AGILEX			2
 #define PLAT_SOCFPGA_N5X			3
-#define PLAT_SOCFPGA_EMULATOR			0
+#define PLAT_SOCFPGA_AGILEX5			4
+#define SIMICS_RUN				1
+#define MAX_IO_MTD_DEVICES			U(1)
 
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
 
-/*
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
- * is done and HPS should trigger warm reset via RMR_EL3.
- */
-#define L2_RESET_DONE_REG			0xFFD12218
-
 /* Magic word to indicate L2 reset is completed */
 #define L2_RESET_DONE_STATUS			0x1228E5E7
 
 /* Define next boot image name and offset */
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+
+#ifndef PRELOADED_BL33_BASE
+#define PLAT_NS_IMAGE_OFFSET			0x80200000
+#else
+#define PLAT_NS_IMAGE_OFFSET			PRELOADED_BL33_BASE
+#endif
+#define PLAT_HANDOFF_OFFSET 0x0003F000
+
+#else
 #define PLAT_NS_IMAGE_OFFSET			0x10000000
 #define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#endif
 
 /*******************************************************************************
  * Platform binary types for linking
@@ -49,7 +58,6 @@
 /*******************************************************************************
  * Generic platform constants
  ******************************************************************************/
-#define PLAT_PRIMARY_CPU			0
 #define PLAT_SECONDARY_ENTRY_BASE		0x01f78bf0
 
 /* Size of cacheable stacks */
@@ -64,49 +72,27 @@
 #define PLATFORM_CLUSTER_COUNT			U(1)
 #define PLATFORM_CLUSTER0_CORE_COUNT		U(4)
 #define PLATFORM_CLUSTER1_CORE_COUNT		U(0)
-#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT + \
-					PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_CORE_COUNT			(PLATFORM_CLUSTER1_CORE_COUNT + \
+						PLATFORM_CLUSTER0_CORE_COUNT)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER		U(4)
 
 /* Interrupt related constant */
 
 #define INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER		29
 
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_0			8
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_1			9
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_2			10
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_3			11
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_4			12
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_5			13
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_6			14
-#define INTEL_SOCFPGA_IRQ_SEC_SGI_7			15
-
-#define TSP_IRQ_SEC_PHY_TIMER		INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER
-#define TSP_SEC_MEM_BASE		BL32_BASE
-#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1)
-/*******************************************************************************
- * Platform memory map related constants
- ******************************************************************************/
-#define DRAM_BASE				(0x0)
-#define DRAM_SIZE				(0x80000000)
-
-#define OCRAM_BASE				(0xFFE00000)
-#define OCRAM_SIZE				(0x00040000)
-
-#define MEM64_BASE				(0x0100000000)
-#define MEM64_SIZE				(0x1F00000000)
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_0		8
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_1		9
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_2		10
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_3		11
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_4		12
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_5		13
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_6		14
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_7		15
 
-#define DEVICE1_BASE				(0x80000000)
-#define DEVICE1_SIZE				(0x60000000)
+#define TSP_IRQ_SEC_PHY_TIMER			INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER
+#define TSP_SEC_MEM_BASE			BL32_BASE
+#define TSP_SEC_MEM_SIZE			(BL32_LIMIT - BL32_BASE + 1)
 
-#define DEVICE2_BASE				(0xF7000000)
-#define DEVICE2_SIZE				(0x08E00000)
-
-#define DEVICE3_BASE				(0xFFFC0000)
-#define DEVICE3_SIZE				(0x00008000)
-
-#define DEVICE4_BASE				(0x2000000000)
-#define DEVICE4_SIZE				(0x0100000000)
 
 /*******************************************************************************
  * BL31 specific defines.
@@ -117,33 +103,28 @@
  * little space for growth.
  */
 
+#define FIRMWARE_WELCOME_STR			"Booting Trusted Firmware\n"
 
-#define FIRMWARE_WELCOME_STR	"Booting Trusted Firmware\n"
+#define BL1_RO_BASE				(0xffe00000)
+#define BL1_RO_LIMIT				(0xffe0f000)
+#define BL1_RW_BASE				(0xffe10000)
+#define BL1_RW_LIMIT				(0xffe1ffff)
+#define BL1_RW_SIZE				(0x14000)
 
-#define BL1_RO_BASE		(0xffe00000)
-#define BL1_RO_LIMIT		(0xffe0f000)
-#define BL1_RW_BASE		(0xffe10000)
-#define BL1_RW_LIMIT		(0xffe1ffff)
-#define BL1_RW_SIZE		(0x14000)
+#define BL_DATA_LIMIT				PLAT_HANDOFF_OFFSET
 
-#define BL2_BASE		(0xffe00000)
-#define BL2_LIMIT		(0xffe1b000)
+#define PLAT_CPUID_RELEASE			(BL_DATA_LIMIT - 16)
+#define PLAT_SEC_ENTRY				(BL_DATA_LIMIT - 8)
 
-#define BL31_BASE		(0x1000)
-#define BL31_LIMIT		(0x81000)
+#define CMP_ENTRY				0xFFE3EFF8
 
-#define BL_DATA_LIMIT		PLAT_HANDOFF_OFFSET
-
-#define PLAT_CPUID_RELEASE	(BL_DATA_LIMIT - 16)
-#define PLAT_SEC_ENTRY		(BL_DATA_LIMIT - 8)
-
-#define PLAT_SEC_WARM_ENTRY	0
+#define PLAT_SEC_WARM_ENTRY			0
 
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define MAX_XLAT_TABLES			8
-#define MAX_MMAP_REGIONS		16
+#define MAX_XLAT_TABLES				8
+#define MAX_MMAP_REGIONS			16
 
 /*******************************************************************************
  * Declarations and constants to access the mailboxes safely. Each mailbox is
@@ -155,46 +136,34 @@
  * a valid mailbox address.
  ******************************************************************************/
 #define CACHE_WRITEBACK_SHIFT			6
-#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
-
-#define PLAT_GIC_BASE			(0xFFFC0000)
-#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
-#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
-#define PLAT_GICR_BASE			0
+#define CACHE_WRITEBACK_GRANULE			(1 << CACHE_WRITEBACK_SHIFT)
 
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
-#define PLAT_UART0_BASE		(0xFFC02000)
-#define PLAT_UART1_BASE		(0xFFC02100)
+#define CRASH_CONSOLE_BASE			PLAT_UART0_BASE
+#define PLAT_INTEL_UART_BASE			PLAT_UART0_BASE
 
-#define CRASH_CONSOLE_BASE	PLAT_UART0_BASE
-#define PLAT_INTEL_UART_BASE	PLAT_UART0_BASE
-
-#if PLAT_SOCFPGA_EMULATOR
-#define PLAT_BAUDRATE		(4800)
-#define PLAT_UART_CLOCK		(76800)
-#else
-#define PLAT_BAUDRATE		(115200)
-#define PLAT_UART_CLOCK		(100000000)
-#endif
+#define PLAT_BAUDRATE				(115200)
+#define PLAT_UART_CLOCK				(100000000)
 
 /*******************************************************************************
  * PHY related constants
  ******************************************************************************/
 
-#define EMAC0_PHY_MODE			PHY_INTERFACE_MODE_RGMII
-#define EMAC1_PHY_MODE			PHY_INTERFACE_MODE_RGMII
-#define EMAC2_PHY_MODE			PHY_INTERFACE_MODE_RGMII
+#define EMAC0_PHY_MODE				PHY_INTERFACE_MODE_RGMII
+#define EMAC1_PHY_MODE				PHY_INTERFACE_MODE_RGMII
+#define EMAC2_PHY_MODE				PHY_INTERFACE_MODE_RGMII
 
 /*******************************************************************************
- * System counter frequency related constants
+ * GIC related constants
  ******************************************************************************/
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
-#define PLAT_SYS_COUNTER_CONVERT_TO_MHZ	(1000000)
+#define PLAT_INTEL_SOCFPGA_GICD_BASE		PLAT_GICD_BASE
+#define PLAT_INTEL_SOCFPGA_GICC_BASE		PLAT_GICC_BASE
 
-#define PLAT_INTEL_SOCFPGA_GICD_BASE	PLAT_GICD_BASE
-#define PLAT_INTEL_SOCFPGA_GICC_BASE	PLAT_GICC_BASE
+/*******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -223,9 +192,9 @@
 
 #define PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(grp)
 
-#define MAX_IO_HANDLES			4
-#define MAX_IO_DEVICES			4
-#define MAX_IO_BLOCK_DEVICES		2
+#define MAX_IO_HANDLES				4
+#define MAX_IO_DEVICES				4
+#define MAX_IO_BLOCK_DEVICES			2
 
 #ifndef __ASSEMBLER__
 struct socfpga_bl31_params {
@@ -239,4 +208,3 @@
 #endif
 
 #endif /* PLATFORM_DEF_H */
-
diff --git a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
index 82bb6cb..1bebfc9 100644
--- a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
+++ b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGOUTCLR0	0x54
 #define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGOUTSET0	0x50
 
+#define FLAGOUTCLR0_F2SDRAM0_ENABLE		(BIT(8))
 #define FLAGOUTSETCLR_F2SDRAM0_ENABLE		(BIT(1))
 #define FLAGOUTSETCLR_F2SDRAM1_ENABLE		(BIT(4))
 #define FLAGOUTSETCLR_F2SDRAM2_ENABLE		(BIT(7))
@@ -21,17 +22,25 @@
 #define FLAGOUTSETCLR_F2SDRAM0_IDLEREQ		(BIT(0))
 #define FLAGOUTSETCLR_F2SDRAM1_IDLEREQ		(BIT(3))
 #define FLAGOUTSETCLR_F2SDRAM2_IDLEREQ		(BIT(6))
-#define FLAGINTSTATUS_F2SDRAM0_IDLEACK		(BIT(1))
-#define FLAGINTSTATUS_F2SDRAM1_IDLEACK		(BIT(5))
-#define FLAGINTSTATUS_F2SDRAM2_IDLEACK		(BIT(9))
+#define FLAGINSTATUS_F2SDRAM0_IDLEACK		(BIT(1))
+#define FLAGINSTATUS_F2SDRAM1_IDLEACK		(BIT(5))
+#define FLAGINSTATUS_F2SDRAM2_IDLEACK		(BIT(9))
+#define FLAGINSTATUS_F2SDRAM0_CMDIDLE		(BIT(2))
+#define FLAGINSTATUS_F2SDRAM1_CMDIDLE		(BIT(6))
+#define FLAGINSTATUS_F2SDRAM2_CMDIDLE		(BIT(10))
+#define FLAGINSTATUS_F2SDRAM0_NOCIDLE		(BIT(0))
+#define FLAGINSTATUS_F2SDRAM1_NOCIDLE		(BIT(4))
+#define FLAGINSTATUS_F2SDRAM2_NOCIDLE		(BIT(8))
+
 #define FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN	(BIT(2))
 #define FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN	(BIT(5))
 #define FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN	(BIT(8))
 
-#define FLAGINTSTATUS_F2SOC_RESPEMPTY		(BIT(3))
-#define FLAGINTSTATUS_F2SDRAM0_RESPEMPTY	(BIT(3))
-#define FLAGINTSTATUS_F2SDRAM1_RESPEMPTY	(BIT(7))
-#define FLAGINTSTATUS_F2SDRAM2_RESPEMPTY	(BIT(11))
+#define FLAGINSTATUS_F2SOC_RESPEMPTY		(BIT(3))
+#define FLAGINSTATUS_F2SDRAM0_RESPEMPTY		(BIT(3))
+#define FLAGINSTATUS_F2SDRAM1_RESPEMPTY		(BIT(7))
+#define FLAGINSTATUS_F2SDRAM2_RESPEMPTY		(BIT(11))
+#define FLAGINSTATUS_F2S_FM_TRACKERIDLE		(BIT(4))
 
 #define SOCFPGA_F2SDRAMMGR(_reg)	(SOCFPGA_F2SDRAMMGR_REG_BASE \
 						+ (SOCFPGA_F2SDRAMMGR_##_reg))
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index 8a8f348..6bb70e0 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -72,6 +72,9 @@
 #define FCS_AES_MIN_DATA_SIZE					0x20		/* 32 Byte */
 #define FCS_AES_CMD_MAX_WORD_SIZE				15U
 
+#define FCS_MAX_DATA_SIZE					0x20000000	/* 512 MB */
+#define FCS_MIN_DATA_SIZE					0x8	/* 8 Bytes */
+
 #define FCS_GET_DIGEST_CMD_MAX_WORD_SIZE			7U
 #define FCS_GET_DIGEST_RESP_MAX_WORD_SIZE			19U
 #define FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE			23U
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index ba0f7f3..b2913c7 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,15 @@
 #ifndef	HANDOFF_H
 #define	HANDOFF_H
 
-#define HANDOFF_MAGIC_HEADER		0x424f4f54	/* BOOT */
-#define HANDOFF_MAGIC_PINMUX_SEL	0x504d5558	/* PMUX */
-#define HANDOFF_MAGIC_IOCTLR		0x494f4354	/* IOCT */
-#define HANDOFF_MAGIC_FPGA		0x46504741	/* FPGA */
-#define HANDOFF_MAGIC_IODELAY		0x444c4159	/* DLAY */
-#define HANDOFF_MAGIC_CLOCK		0x434c4b53	/* CLKS */
-#define HANDOFF_MAGIC_MISC		0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_HEADER			0x424f4f54	/* BOOT */
+#define HANDOFF_MAGIC_PINMUX_SEL		0x504d5558	/* PMUX */
+#define HANDOFF_MAGIC_IOCTLR			0x494f4354	/* IOCT */
+#define HANDOFF_MAGIC_FPGA				0x46504741	/* FPGA */
+#define HANDOFF_MAGIC_IODELAY			0x444c4159	/* DLAY */
+#define HANDOFF_MAGIC_CLOCK				0x434c4b53	/* CLKS */
+#define HANDOFF_MAGIC_MISC				0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_PERIPHERAL		0x50455249	/* PERIPHERAL */
+#define HANDOFF_MAGIC_DDR				0x5344524d	/* DDR */
 
 #include <socfpga_plat_def.h>
 
@@ -39,8 +41,9 @@
 	uint32_t	pinmux_fpga_magic;
 	uint32_t	pinmux_fpga_length;
 	uint32_t	_pad_0x338_0x340[2];
-	uint32_t	pinmux_fpga_array[42];	/* offset, value */
-	uint32_t	_pad_0x3e8_0x3f0[2];
+	uint32_t	pinmux_fpga_array[44];	/* offset, value */
+	/* TODO: Temp remove due to add in extra handoff data */
+	// uint32_t	_pad_0x3e8_0x3f0[2];
 
 	/* pinmux configuration - io delay */
 	uint32_t	pinmux_delay_magic;
@@ -49,7 +52,6 @@
 	uint32_t	pinmux_iodelay_array[96];	/* offset, value */
 
 	/* clock configuration */
-
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 	uint32_t	clock_magic;
 	uint32_t	clock_length;
@@ -120,16 +122,68 @@
 	uint32_t	hps_osc_clk_h;
 	uint32_t	fpga_clk_hz;
 	uint32_t	_pad_0x604_0x610[3];
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	uint32_t	clock_magic;
+	uint32_t	clock_length;
+	uint32_t	_pad_0x588_0x590[2];
+	uint32_t	main_pll_nocclk;
+	uint32_t	main_pll_nocdiv;
+	uint32_t	main_pll_pllglob;
+	uint32_t	main_pll_fdbck;
+	uint32_t	main_pll_pllc0;
+	uint32_t	main_pll_pllc1;
+	uint32_t	main_pll_pllc2;
+	uint32_t	main_pll_pllc3;
+	uint32_t	main_pll_pllm;
+	uint32_t	per_pll_emacctl;
+	uint32_t	per_pll_gpiodiv;
+	uint32_t	per_pll_pllglob;
+	uint32_t	per_pll_fdbck;
+	uint32_t	per_pll_pllc0;
+	uint32_t	per_pll_pllc1;
+	uint32_t	per_pll_pllc2;
+	uint32_t	per_pll_pllc3;
+	uint32_t	per_pll_pllm;
+	uint32_t	alt_emacactr;
+	uint32_t	alt_emacbctr;
+	uint32_t	alt_emacptpctr;
+	uint32_t	alt_gpiodbctr;
+	uint32_t	alt_sdmmcctr;
+	uint32_t	alt_s2fuser0ctr;
+	uint32_t	alt_s2fuser1ctr;
+	uint32_t	alt_psirefctr;
+	/* TODO: Temp added for clk manager. */
+	uint32_t	qspi_clk_khz;
+	uint32_t	hps_osc_clk_hz;
+	uint32_t	fpga_clk_hz;
+	/* TODO: Temp added for clk manager. */
+	uint32_t	ddr_reset_type;
+	/* TODO: Temp added for clk manager. */
+	uint32_t	hps_status_coldreset;
+	/* TODO: Temp remove due to add in extra handoff data */
+	//uint32_t	_pad_0x604_0x610[3];
 #endif
 	/* misc configuration */
 	uint32_t	misc_magic;
 	uint32_t	misc_length;
 	uint32_t	_pad_0x618_0x620[2];
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* peripheral configuration - select */
+	uint32_t	peripheral_pwr_gate_magic;
+	uint32_t	peripheral_pwr_gate_length;
+	uint32_t	_pad_0x08_0x0C[2];
+	uint32_t	peripheral_pwr_gate_array;	/* offset, value */
+
+	/* ddr configuration - select */
+	uint32_t	ddr_magic;
+	uint32_t	ddr_length;
+	uint32_t	_pad_0x1C_0x20[2];
+	uint32_t	ddr_array[4];	/* offset, value */
+#endif
 } handoff;
 
 int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
 int socfpga_get_handoff(handoff *hoff_ptr);
 
 #endif
-
-
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 3abf39d..77d3af9 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,11 @@
 
 #include <lib/utils_def.h>
 
-
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define MBOX_OFFSET					0x10a30000
+#else
 #define MBOX_OFFSET					0xffa30000
+#endif
 
 #define MBOX_ATF_CLIENT_ID				0x1U
 #define MBOX_MAX_JOB_ID					0xFU
@@ -63,6 +66,9 @@
 #define MBOX_CMD_QSPI_SET_CS				0x34
 #define MBOX_CMD_QSPI_DIRECT				0x3B
 
+/* SEU Commands */
+#define MBOX_CMD_SEU_ERR_READ				0x3C
+
 /* RSU Commands */
 #define MBOX_GET_SUBPARTITION_TABLE			0x5A
 #define MBOX_RSU_STATUS					0x5B
@@ -190,9 +196,9 @@
 #define RSU_VERSION_ACMF_MASK				0xff00
 
 /* Config Status Macros */
-#define CONFIG_STATUS_WORD_SIZE		16U
-#define CONFIG_STATUS_FW_VER_OFFSET	1
-#define CONFIG_STATUS_FW_VER_MASK	0x00FFFFFF
+#define CONFIG_STATUS_WORD_SIZE			16U
+#define CONFIG_STATUS_FW_VER_OFFSET		1
+#define CONFIG_STATUS_FW_VER_MASK		0x00FFFFFF
 
 /* Data structure */
 
@@ -230,6 +236,7 @@
 			unsigned int *resp_len);
 
 void mailbox_reset_cold(void);
+void mailbox_reset_warm(uint32_t reset_type);
 void mailbox_clear_response(void);
 
 int intel_mailbox_get_config_status(uint32_t cmd, bool init_done);
@@ -241,5 +248,6 @@
 int mailbox_hps_stage_notify(uint32_t execution_stage);
 int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
 int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
+int mailbox_seu_err_status(uint32_t *resp_buf, uint32_t resp_buf_len);
 
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_noc.h b/plat/intel/soc/common/include/socfpga_noc.h
index e3c0f73..3fc3f81 100644
--- a/plat/intel/soc/common/include/socfpga_noc.h
+++ b/plat/intel/soc/common/include/socfpga_noc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -74,6 +74,10 @@
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2			0x0070
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3			0x0074
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP				0x0078
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG4			0x007c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_PWRMGR			0x0080
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_RXECC			0x0084
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_TXECC			0x0088
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES			0x0090
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS			0x0094
 
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
index cce16ab..9d06a3d 100644
--- a/plat/intel/soc/common/include/socfpga_reset_manager.h
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,10 @@
 
 #include "socfpga_plat_def.h"
 
+/* Status Response */
+#define RSTMGR_RET_OK				0
+#define RSTMGR_RET_ERROR			-1
+
 #define SOCFPGA_BRIDGE_ENABLE			BIT(0)
 #define SOCFPGA_BRIDGE_HAS_MASK			BIT(1)
 
@@ -22,28 +26,51 @@
 /* Register Mapping */
 
 #define SOCFPGA_RSTMGR_STAT			0x000
+#define SOCFPGA_RSTMGR_MISCSTAT			0x008
 #define SOCFPGA_RSTMGR_HDSKEN			0x010
 #define SOCFPGA_RSTMGR_HDSKREQ			0x014
 #define SOCFPGA_RSTMGR_HDSKACK			0x018
+#define SOCFPGA_RSTMGR_HDSKSTALL		0x01C
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 #define SOCFPGA_RSTMGR_MPUMODRST		0x020
+#endif
 #define SOCFPGA_RSTMGR_PER0MODRST		0x024
 #define SOCFPGA_RSTMGR_PER1MODRST		0x028
-#define SOCFPGA_RSTMGR_BRGMODRST		0x02c
+#define SOCFPGA_RSTMGR_BRGMODRST		0x02C
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 #define SOCFPGA_RSTMGR_COLDMODRST		0x034
+#endif
+#define SOCFPGA_RSTMGR_DBGMODRST		0x03C
+#define SOCFPGA_RSTMGR_BRGWARMMASK		0x04C
+#define SOCFPGA_RSTMGR_TSTSTA			0x05C
 #define SOCFPGA_RSTMGR_HDSKTIMEOUT		0x064
+#define SOCFPGA_RSTMGR_DBGHDSKTIMEOUT		0x06C
+#define SOCFPGA_RSTMGR_DBGRSTCMPLT		0x070
+#define SOCFPGA_RSTMGR_HPSRSTCMPLT		0x080
+#define SOCFPGA_RSTMGR_CPUINREST		0x090
+#define SOCFPGA_RSTMGR_CPURSTRELEASE		0x094
+#define SOCFPGA_RSTMGR_CPUBASELOW_0		0x098
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_0		0x09C
+#define SOCFPGA_RSTMGR_CPUBASELOW_1		0x0A0
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_1		0x0A4
+#define SOCFPGA_RSTMGR_CPUBASELOW_2		0x0A8
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_2		0x0AC
+#define SOCFPGA_RSTMGR_CPUBASELOW_3		0x0B0
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_3		0x0B4
 
 /* Field Mapping */
-
-#define RSTMGR_PER0MODRST_EMAC0			0x00000001
-#define RSTMGR_PER0MODRST_EMAC1			0x00000002
-#define RSTMGR_PER0MODRST_EMAC2			0x00000004
+/* PER0MODRST */
+#define RSTMGR_PER0MODRST_EMAC0			0x00000001	//TSN0
+#define RSTMGR_PER0MODRST_EMAC1			0x00000002	//TSN1
+#define RSTMGR_PER0MODRST_EMAC2			0x00000004	//TSN2
 #define RSTMGR_PER0MODRST_USB0			0x00000008
 #define RSTMGR_PER0MODRST_USB1			0x00000010
 #define RSTMGR_PER0MODRST_NAND			0x00000020
+#define RSTMGR_PER0MODRST_SOFTPHY		0x00000040
 #define RSTMGR_PER0MODRST_SDMMC			0x00000080
-#define RSTMGR_PER0MODRST_EMAC0OCP		0x00000100
-#define RSTMGR_PER0MODRST_EMAC1OCP		0x00000200
-#define RSTMGR_PER0MODRST_EMAC2OCP		0x00000400
+#define RSTMGR_PER0MODRST_EMAC0OCP		0x00000100	//TSN0ECC
+#define RSTMGR_PER0MODRST_EMAC1OCP		0x00000200	//TSN1ECC
+#define RSTMGR_PER0MODRST_EMAC2OCP		0x00000400	//TSN2ECC
 #define RSTMGR_PER0MODRST_USB0OCP		0x00000800
 #define RSTMGR_PER0MODRST_USB1OCP		0x00001000
 #define RSTMGR_PER0MODRST_NANDOCP		0x00002000
@@ -64,6 +91,7 @@
 #define RSTMGR_PER0MODRST_DMAIF6		0x40000000
 #define RSTMGR_PER0MODRST_DMAIF7		0x80000000
 
+/* PER1MODRST */
 #define RSTMGR_PER1MODRST_WATCHDOG0		0x00000001
 #define RSTMGR_PER1MODRST_WATCHDOG1		0x00000002
 #define RSTMGR_PER1MODRST_WATCHDOG2		0x00000004
@@ -77,31 +105,121 @@
 #define RSTMGR_PER1MODRST_I2C2			0x00000400
 #define RSTMGR_PER1MODRST_I2C3			0x00000800
 #define RSTMGR_PER1MODRST_I2C4			0x00001000
+#define RSTMGR_PER1MODRST_I3C0			0x00002000
+#define RSTMGR_PER1MODRST_I3C1			0x00004000
 #define RSTMGR_PER1MODRST_UART0			0x00010000
 #define RSTMGR_PER1MODRST_UART1			0x00020000
 #define RSTMGR_PER1MODRST_GPIO0			0x01000000
 #define RSTMGR_PER1MODRST_GPIO1			0x02000000
+#define RSTMGR_PER1MODRST_WATCHDOG4		0x04000000
 
+/* HDSKEN */
+#define RSTMGR_HDSKEN_EMIF_FLUSH		0x00000001
 #define RSTMGR_HDSKEN_FPGAHSEN			0x00000004
 #define RSTMGR_HDSKEN_ETRSTALLEN		0x00000008
-#define RSTMGR_HDSKEN_L2FLUSHEN			0x00000100
+#define RSTMGR_HDSKEN_LWS2F_FLUSH		0x00000200
+#define RSTMGR_HDSKEN_S2F_FLUSH			0x00000400
+#define RSTMGR_HDSKEN_F2SDRAM_FLUSH		0x00000800
+#define RSTMGR_HDSKEN_F2S_FLUSH			0x00001000
 #define RSTMGR_HDSKEN_L3NOC_DBG			0x00010000
 #define RSTMGR_HDSKEN_DEBUG_L3NOC		0x00020000
-#define RSTMGR_HDSKEN_SDRSELFREFEN		0x00000001
 
-#define RSTMGR_HDSKEQ_FPGAHSREQ			0x4
+/* HDSKREQ */
+#define RSTMGR_HDSKREQ_EMIFFLUSHREQ		0x00000001
+#define RSTMGR_HDSKREQ_ETRSTALLREQ		0x00000008
+#define RSTMGR_HDSKREQ_LWS2F_FLUSH		0x00000200
+#define RSTMGR_HDSKREQ_S2F_FLUSH		0x00000400
+#define RSTMGR_HDSKREQ_F2SDRAM_FLUSH		0x00000800
+#define RSTMGR_HDSKREQ_F2S_FLUSH		0x00001000
+#define RSTMGR_HDSKREQ_L3NOC_DBG		0x00010000
+#define RSTMGR_HDSKREQ_DEBUG_L3NOC		0x00020000
+#define RSTMGR_HDSKREQ_FPGAHSREQ		0x00000004
+#define RSTMGR_HDSKREQ_LWSOC2FPGAREQ		0x00000200
+#define RSTMGR_HDSKREQ_SOC2FPGAREQ		0x00000400
+#define RSTMGR_HDSKREQ_F2SDRAM0REQ		0x00000800
+#define RSTMGR_HDSKREQ_FPGA2SOCREQ		0x00001000
 
-#define RSTMGR_BRGMODRST_SOC2FPGA		0x1
-#define RSTMGR_BRGMODRST_LWHPS2FPGA		0x2
-#define RSTMGR_BRGMODRST_FPGA2SOC		0x4
-#define RSTMGR_BRGMODRST_F2SSDRAM0		0x8
+/* HDSKACK */
+#define RSTMGR_HDSKACK_EMIFFLUSHREQ		0x00000001
+#define RSTMGR_HDSKACK_FPGAHSREQ		0x00000004
+#define RSTMGR_HDSKACK_ETRSTALLREQ		0x00000008
+#define RSTMGR_HDSKACK_LWS2F_FLUSH		0x00000200
+#define RSTMGR_HDSKACK_S2F_FLUSH		0x00000400
+#define RSTMGR_HDSKACK_F2SDRAM_FLUSH		0x00000800
+#define RSTMGR_HDSKACK_F2S_FLUSH		0x00001000
+#define RSTMGR_HDSKACK_L3NOC_DBG		0x00010000
+#define RSTMGR_HDSKACK_DEBUG_L3NOC		0x00020000
+#define RSTMGR_HDSKACK_FPGAHSACK		0x00000004
+#define RSTMGR_HDSKACK_LWSOC2FPGAACK		0x00000200
+#define RSTMGR_HDSKACK_SOC2FPGAACK		0x00000400
+#define RSTMGR_HDSKACK_F2SDRAM0ACK		0x00000800
+#define RSTMGR_HDSKACK_FPGA2SOCACK		0x00001000
+#define RSTMGR_HDSKACK_FPGAHSACK_DASRT		0x00000000
+#define RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT	0x00000000
+#define RSTMGR_HDSKACK_FPGA2SOCACK_DASRT	0x00000000
+
+/* HDSKSTALL */
+#define RSTMGR_HDSKACK_ETRSTALLWARMRST		0x00000001
+
+/* BRGMODRST */
+#define RSTMGR_BRGMODRST_SOC2FPGA		0x00000001
+#define RSTMGR_BRGMODRST_LWHPS2FPGA		0x00000002
+#define RSTMGR_BRGMODRST_FPGA2SOC		0x00000004
+#define RSTMGR_BRGMODRST_F2SSDRAM0		0x00000008
+#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 #define RSTMGR_BRGMODRST_F2SSDRAM1		0x10
 #define RSTMGR_BRGMODRST_F2SSDRAM2		0x20
-#define RSTMGR_BRGMODRST_MPFE			0x40
 #define RSTMGR_BRGMODRST_DDRSCH			0x40
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define RSTMGR_BRGMODRST_F2SSDRAM1		0x10
+#define RSTMGR_BRGMODRST_F2SSDRAM2		0x20
+#endif
+
+#define RSTMGR_BRGMODRST_MPFE			0x40
+
+/* DBGMODRST */
+#define RSTMGR_DBGMODRST_DBG_RST		0x00000001
 
-#define RSTMGR_HDSKREQ_FPGAHSREQ		(BIT(2))
-#define RSTMGR_HDSKACK_FPGAHSACK_MASK		(BIT(2))
+/* BRGMODRSTMASK */
+#define RSTMGR_BRGMODRSTMASK_SOC2FPGA		0x00000001
+#define RSTMGR_BRGMODRSTMASK_LWHPS2FPGA		0x00000002
+#define RSTMGR_BRGMODRSTMASK_FPGA2SOC		0x00000004
+#define RSTMGR_BRGMODRSTMASK_F2SDRAM0		0x00000008
+#define RSTMGR_BRGMODRSTMASK_MPFE		0x00000040
+
+/* TSTSTA */
+#define RSTMGR_TSTSTA_RSTST			0x0000001F
+
+/* HDSKTIMEOUT */
+#define RSTMGR_HDSKTIMEOUT_VAL			0xFFFFFFFF
+
+/* DBGHDSKTIMEOUT */
+#define RSTMGR_DBGHDSKTIMEOUT_VAL		0xFFFFFFFF
+
+/* DBGRSTCMPLT */
+#define RSTMGR_DBGRSTCMPLT_VAL			0xFFFFFFFF
+
+/* HPSRSTCMPLT */
+#define RSTMGR_DBGRSTCMPLT_VAL			0xFFFFFFFF
+
+/* CPUINRESET */
+#define RSTMGR_CPUINRESET_CPU0			0x00000001
+#define RSTMGR_CPUINRESET_CPU1			0x00000002
+#define RSTMGR_CPUINRESET_CPU2			0x00000004
+#define RSTMGR_CPUINRESET_CPU3			0x00000008
+
+/* CPUSTRELEASE */
+#define RSTMGR_CPUSTRELEASE_CPUx		0x10D11094
+
+/* CPUxRESETBASE */
+#define RSTMGR_CPUxRESETBASELOW_CPU0		0x10D11098
+#define RSTMGR_CPUxRESETBASEHIGH_CPU0		0x10D1109C
+#define RSTMGR_CPUxRESETBASELOW_CPU1		0x10D110A0
+#define RSTMGR_CPUxRESETBASEHIGH_CPU1		0x10D110A4
+#define RSTMGR_CPUxRESETBASELOW_CPU2		0x10D110A8
+#define RSTMGR_CPUxRESETBASEHIGH_CPU2		0x10D110AC
+#define RSTMGR_CPUxRESETBASELOW_CPU3		0x10D110B0
+#define RSTMGR_CPUxRESETBASEHIGH_CPU3		0x10D110B4
 
 /* Definitions */
 
@@ -109,17 +227,28 @@
 #define RSTMGR_HDSKEN_SET			0x010D
 
 /* Macros */
+#define SOCFPGA_RSTMGR(_reg)			(SOCFPGA_RSTMGR_REG_BASE + (SOCFPGA_RSTMGR_##_reg))
+#define RSTMGR_FIELD(_reg, _field)		(RSTMGR_##_reg##MODRST_##_field)
 
-#define SOCFPGA_RSTMGR(_reg)		(SOCFPGA_RSTMGR_REG_BASE \
-					+ (SOCFPGA_RSTMGR_##_reg))
-#define RSTMGR_FIELD(_reg, _field)	(RSTMGR_##_reg##MODRST_##_field)
+/* Reset type to SDM from PSCI */
+// Temp add macro here for reset type
+#define SOCFPGA_RESET_TYPE_COLD			0
+#define SOCFPGA_RESET_TYPE_WARM			1
 
 /* Function Declarations */
 
 void deassert_peripheral_reset(void);
 void config_hps_hs_before_warm_reset(void);
 
+int socfpga_bridges_reset(uint32_t mask);
 int socfpga_bridges_enable(uint32_t mask);
 int socfpga_bridges_disable(uint32_t mask);
 
+int socfpga_cpurstrelease(unsigned int cpu_id);
+int socfpga_cpu_reset_base(unsigned int cpu_id);
+
+/* SMP: Func proto */
+void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id);
+void bl31_plat_set_secondary_cpu_off(void);
+
 #endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 21169f7..0668301 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -15,6 +15,7 @@
 #define INTEL_SIP_SMC_STATUS_NO_RESPONSE			0x3
 #define INTEL_SIP_SMC_STATUS_ERROR				0x4
 #define INTEL_SIP_SMC_RSU_ERROR					0x7
+#define INTEL_SIP_SMC_SEU_ERR_READ_ERROR		0x8
 
 /* SiP mailbox error code */
 #define GENERIC_RESPONSE_ERROR					0x3FF
@@ -138,6 +139,9 @@
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT				0xC200008C
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE				0xC200008E
 
+/* SEU ERR */
+#define INTEL_SIP_SMC_SEU_ERR_STATUS				0xC2000099
+
 #define INTEL_SIP_SMC_FCS_SHA_MODE_MASK				0xF
 #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK			0xF
 #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET			4U
@@ -163,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
@@ -181,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 */
@@ -215,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/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 69ee6d3..f860f57 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,26 +13,6 @@
 
 #define SOCFPGA_SYSMGR_SDMMC				0x28
 
-#define SOCFPGA_SYSMGR_FPGAINTF_EN_2			0x6c
-
-#define SOCFPGA_SYSMGR_EMAC_0				0x44
-#define SOCFPGA_SYSMGR_EMAC_1				0x48
-#define SOCFPGA_SYSMGR_EMAC_2				0x4c
-#define SOCFPGA_SYSMGR_FPGAINTF_EN_3			0x70
-
-#define SOCFPGA_SYSMGR_NOC_TIMEOUT			0xc0
-#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET			0xc4
-#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR			0xc8
-#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL			0xcc
-#define SOCFPGA_SYSMGR_NOC_IDLEACK			0xd0
-#define SOCFPGA_SYSMGR_NOC_IDLESTATUS			0xd4
-
-#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0		0x200
-#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1		0x204
-#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2		0x208
-#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
-#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
-
 /* Field Masking */
 
 #define SYSMGR_SDMMC_DRVSEL(x)			(((x) & 0x7) << 0)
diff --git a/plat/intel/soc/common/include/socfpga_vab.h b/plat/intel/soc/common/include/socfpga_vab.h
new file mode 100644
index 0000000..f6081df
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_vab.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_VAB_H
+#define SOCFPGA_VAB_H
+
+
+#include <stdlib.h>
+#include "socfpga_fcs.h"
+
+struct fcs_hps_vab_certificate_data {
+	uint32_t vab_cert_magic_num;			/* offset 0x10 */
+	uint32_t flags;
+	uint8_t rsvd0_1[8];
+	uint8_t fcs_sha384[FCS_SHA384_WORD_SIZE];	/* offset 0x20 */
+};
+
+struct fcs_hps_vab_certificate_header {
+	uint32_t cert_magic_num;			/* offset 0 */
+	uint32_t cert_data_sz;
+	uint32_t cert_ver;
+	uint32_t cert_type;
+	struct fcs_hps_vab_certificate_data d;		/* offset 0x10 */
+	/* keychain starts at offset 0x50 */
+};
+
+/* Macros */
+#define IS_BYTE_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+#define BYTE_ALIGN(x, a)		__ALIGN_MASK((x), (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask)		(((x)+(mask))&~(mask))
+#define VAB_CERT_HEADER_SIZE		sizeof(struct fcs_hps_vab_certificate_header)
+#define VAB_CERT_MAGIC_OFFSET		offsetof(struct fcs_hps_vab_certificate_header, d)
+#define VAB_CERT_FIT_SHA384_OFFSET	offsetof(struct fcs_hps_vab_certificate_data, fcs_sha384[0])
+#define SDM_CERT_MAGIC_NUM		0x25D04E7F
+#define CHUNKSZ_PER_WD_RESET		(256 * 1024)
+
+/* SHA related return Macro */
+#define ENOVABIMG		1 /* VAB certificate not available */
+#define EIMGERR		2 /* Image format/size not valid */
+#define ETIMEOUT		3 /* Execution timeout */
+#define EPROCESS		4 /* Process error */
+#define EKEYREJECTED		5/* Key was rejected by service */
+
+/* Function Definitions */
+static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz);
+int socfpga_vendor_authentication(void **p_image, size_t *p_size);
+static uint32_t get_unaligned_le32(const void *p);
+void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
+unsigned char *output, unsigned int chunk_sz);
+
+#endif
diff --git a/plat/intel/soc/common/sip/socfpga_sip_ecc.c b/plat/intel/soc/common/sip/socfpga_sip_ecc.c
index c4e06a6..c444d48 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_ecc.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_ecc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  */
 
 #include <assert.h>
@@ -11,10 +11,12 @@
 
 #include "socfpga_fcs.h"
 #include "socfpga_mailbox.h"
+#include "socfpga_plat_def.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
 #include "socfpga_system_manager.h"
 
+
 uint32_t intel_ecc_dbe_notification(uint64_t dbe_value)
 {
 	dbe_value &= WARM_RESET_WFI_FLAG;
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index 3b0b370..beaa720 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -283,6 +283,7 @@
 	uint32_t load_size;
 	uintptr_t id_offset;
 
+	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
 	fcs_decrypt_payload payload = {
 		FCS_DECRYPTION_DATA_0,
@@ -392,6 +393,7 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
 	fcs_decrypt_ext_payload payload = {
 		session_id,
@@ -822,6 +824,7 @@
 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
 
 	if (resp_len > 0) {
+		inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
 		op_status = mmio_read_32(dst_addr) &
 			FCS_CS_KEY_RESP_STATUS_MASK;
 	}
@@ -1070,6 +1073,7 @@
 	uint32_t resp_len;
 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
 	uintptr_t mac_offset;
+	uint32_t dst_size_check = 0;
 
 	if (dst_size == NULL || mbox_error == NULL) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -1094,6 +1098,14 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare crypto header */
@@ -1146,6 +1158,12 @@
 		FCS_CS_FIELD_FLAG_FINALIZE) {
 		/* Copy mac data to command */
 		mac_offset = src_addr + data_size;
+
+		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
+			FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
+			return INTEL_SIP_SMC_STATUS_REJECTED;
+		}
+
 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
 		src_size - data_size);
 
@@ -1186,7 +1204,7 @@
 	uint32_t resp_len;
 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
 	uintptr_t mac_offset;
-
+	uint32_t dst_size_check = 0;
 	/*
 	 * Source data must be 4 bytes aligned
 	 * User data must be 8 bytes aligned
@@ -1211,6 +1229,14 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare crypto header */
@@ -1266,10 +1292,16 @@
 		 * mac_offset = MAC data
 		 */
 		mac_offset = dst_addr;
+
+		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
+			FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
+			return INTEL_SIP_SMC_STATUS_REJECTED;
+		}
+
 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
 		src_size - data_size);
 
-		memset((void *)&dst_addr, 0, sizeof(dst_size));
+		memset((void *) dst_addr, 0, *dst_size);
 
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
@@ -1313,6 +1345,7 @@
 	uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
 	uint32_t resp_len;
 	uintptr_t hash_data_addr;
+	uint32_t dst_size_check = 0;
 
 	if ((dst_size == NULL) || (mbox_error == NULL)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -1328,6 +1361,14 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare command payload */
@@ -1354,6 +1395,12 @@
 	/* Hash Data */
 	i++;
 	hash_data_addr = src_addr;
+
+	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
+		FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
 			src_size);
 
@@ -1397,6 +1444,7 @@
 	uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
 	uint32_t resp_len;
 	uintptr_t hash_sig_pubkey_addr;
+	uint32_t dst_size_check = 0;
 
 	if ((dst_size == NULL) || (mbox_error == NULL)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -1412,6 +1460,14 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare command payload */
@@ -1440,6 +1496,12 @@
 	/* Hash Data Word, Signature Data Word and Public Key Data word */
 	i++;
 	hash_sig_pubkey_addr = src_addr;
+
+	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
+		FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	memcpy((uint8_t *) &payload[i],
 			(uint8_t *) hash_sig_pubkey_addr, src_size);
 
@@ -1687,6 +1749,7 @@
 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
 	uint32_t resp_len;
 	uintptr_t sig_pubkey_offset;
+	uint32_t dst_size_check = 0;
 
 	if ((dst_size == NULL) || (mbox_error == NULL)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -1697,6 +1760,10 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	if (data_size > src_size) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	if (!is_size_4_bytes_aligned(src_size)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
@@ -1711,6 +1778,14 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare crypto header */
@@ -1758,6 +1833,12 @@
 		FCS_CS_FIELD_FLAG_FINALIZE) {
 		/* Signature + Public Key Data */
 		sig_pubkey_offset = src_addr + data_size;
+
+		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
+			FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
+			return INTEL_SIP_SMC_STATUS_REJECTED;
+		}
+
 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
 			src_size - data_size);
 
@@ -1798,10 +1879,11 @@
 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
 	uint32_t resp_len;
 	uintptr_t sig_pubkey_offset;
+	uint32_t dst_size_check = 0;
 
 	/*
 	 * Source data must be 4 bytes aligned
-	 * Source addrress must be 8 bytes aligned
+	 * Source address must be 8 bytes aligned
 	 * User data must be 8 bytes aligned
 	 */
 	if ((dst_size == NULL) || (mbox_error == NULL) ||
@@ -1816,11 +1898,23 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	if (data_size > src_size) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	if (!is_address_in_ddr_range(src_addr, src_size) ||
 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare crypto header */
@@ -1871,10 +1965,16 @@
 		 * sig_pubkey_offset is Signature + Public Key Data
 		 */
 		sig_pubkey_offset = dst_addr;
+
+		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
+			FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
+			return INTEL_SIP_SMC_STATUS_REJECTED;
+		}
+
 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
 			src_size - data_size);
 
-		memset((void *)&dst_addr, 0, sizeof(dst_size));
+		memset((void *) dst_addr, 0, *dst_size);
 
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
@@ -1987,11 +2087,13 @@
 	uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
 	uint32_t resp_len;
 	uintptr_t pubkey;
+	uint32_t dst_size_check = 0;
 
 	if ((dst_size == NULL) || (mbox_error == NULL)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+
 	if (fcs_ecdh_request_param.session_id != session_id ||
 		fcs_ecdh_request_param.context_id != context_id) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -2002,6 +2104,14 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	dst_size_check = *dst_size;
+	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
+		dst_size_check < FCS_MIN_DATA_SIZE) ||
+		(src_size > FCS_MAX_DATA_SIZE ||
+		src_size < FCS_MIN_DATA_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	resp_len = *dst_size / MBOX_WORD_BYTE;
 
 	/* Prepare command payload */
@@ -2025,6 +2135,12 @@
 	i++;
 	/* Public key data */
 	pubkey = src_addr;
+
+	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
+		FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
 	i += src_size / MBOX_WORD_BYTE;
 
@@ -2159,6 +2275,11 @@
 		fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
 		i++;
 
+		if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) >
+			FCS_AES_CMD_MAX_WORD_SIZE) {
+			return INTEL_SIP_SMC_STATUS_REJECTED;
+		}
+
 		memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
 			(uint8_t *) fcs_aes_init_payload.crypto_param,
 			fcs_aes_init_payload.param_size);
diff --git a/plat/intel/soc/common/soc/socfpga_emac.c b/plat/intel/soc/common/soc/socfpga_emac.c
index cacfd53..49c92c3 100644
--- a/plat/intel/soc/common/soc/socfpga_emac.c
+++ b/plat/intel/soc/common/soc/socfpga_emac.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #include <platform_def.h>
 
 #include "socfpga_emac.h"
+#include "socfpga_plat_def.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_system_manager.h"
 
diff --git a/plat/intel/soc/common/soc/socfpga_firewall.c b/plat/intel/soc/common/soc/socfpga_firewall.c
index fc3889c..6247df3 100644
--- a/plat/intel/soc/common/soc/socfpga_firewall.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,11 @@
 void enable_ns_peripheral_access(void)
 {
 	mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_REGISTER), DISABLE_L4_FIREWALL);
+#if	((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
 	mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_DATA), DISABLE_L4_FIREWALL);
+#endif
 
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_ECC), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_READ_ECC), DISABLE_L4_FIREWALL);
@@ -87,9 +91,19 @@
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG1), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG2), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG3), DISABLE_L4_FIREWALL);
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG4), DISABLE_L4_FIREWALL);
+#endif
 
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(DAP), DISABLE_L4_FIREWALL);
 
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(PWRMGR), DISABLE_L4_FIREWALL);
+
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_RXECC), DISABLE_L4_FIREWALL);
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_TXECC), DISABLE_L4_FIREWALL);
+#endif
+
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_PROBES), DISABLE_L4_FIREWALL);
 
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL);
diff --git a/plat/intel/soc/common/soc/socfpga_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c
index 4bb3a96..526c6e1 100644
--- a/plat/intel/soc/common/soc/socfpga_handoff.c
+++ b/plat/intel/soc/common/soc/socfpga_handoff.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
 #include <string.h>
 
 #include "socfpga_handoff.h"
@@ -17,6 +18,10 @@
 	uint32_t *buffer;
 	handoff *handoff_ptr = (handoff *) PLAT_HANDOFF_OFFSET;
 
+	if (sizeof(*handoff_ptr) > sizeof(handoff)) {
+		return -EOVERFLOW;
+	}
+
 	memcpy(reverse_hoff_ptr, handoff_ptr, sizeof(handoff));
 	buffer = (uint32_t *)reverse_hoff_ptr;
 
@@ -24,16 +29,34 @@
 	for (i = 0; i < sizeof(handoff) / 4; i++)
 		buffer[i] = SWAP_UINT32(buffer[i]);
 
-	if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER)
+	if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER) {
+		return -1;
+	}
+	if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL) {
+		return -1;
+	}
+	if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL)
+	}
+	if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR)
+	}
+	if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA)
+	}
+	if (reverse_hoff_ptr->clock_magic != HANDOFF_MAGIC_CLOCK) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY)
+	}
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	if (reverse_hoff_ptr->peripheral_pwr_gate_magic != HANDOFF_MAGIC_PERIPHERAL) {
+		return -1;
+	}
+
+	if (reverse_hoff_ptr->ddr_magic != HANDOFF_MAGIC_DDR) {
 		return -1;
+	}
+#endif
 
 	return 0;
 }
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 7010d81..d93fc8a 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -7,8 +7,10 @@
 #include <lib/mmio.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
+#include <platform_def.h>
 
 #include "socfpga_mailbox.h"
+#include "socfpga_plat_def.h"
 #include "socfpga_sip_svc.h"
 #include "socfpga_system_manager.h"
 
@@ -183,6 +185,7 @@
 	uint32_t resp_data;
 	uint32_t ret_resp_len = 0;
 	uint8_t is_done = 0;
+	uint32_t resp_len_check = 0;
 
 	if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
 		ret_resp_len = MBOX_RESP_LEN(
@@ -242,6 +245,12 @@
 				*resp_len = ret_resp_len;
 			}
 
+			resp_len_check = (uint32_t) *resp_len;
+
+			if (resp_len_check > MBOX_DATA_MAX_LEN) {
+				return MBOX_RET_ERROR;
+			}
+
 			memcpy((uint8_t *) response,
 				(uint8_t *) mailbox_resp_ctr.payload->data,
 				*resp_len * MBOX_WORD_BYTE);
@@ -514,8 +523,18 @@
 void mailbox_reset_cold(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U,
-				CMD_CASUAL, NULL, NULL);
+
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0U, 0U,
+				 CMD_CASUAL, NULL, NULL);
+}
+
+void mailbox_reset_warm(uint32_t reset_type)
+{
+	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
+
+	reset_type = 0x01; // Warm reset header data must be 1
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, &reset_type, 1U,
+				 CMD_CASUAL, NULL, NULL);
 }
 
 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
@@ -669,3 +688,11 @@
 				CMD_CASUAL, resp_buf,
 				&resp_len);
 }
+
+int mailbox_seu_err_status(uint32_t *resp_buf, unsigned int resp_buf_len)
+{
+
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SEU_ERR_READ, NULL, 0U,
+				CMD_CASUAL, resp_buf,
+				&resp_buf_len);
+}
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index bb4efab..7db86c7 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -1,20 +1,22 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include <platform_def.h>
 
 #include "socfpga_f2sdram_manager.h"
 #include "socfpga_mailbox.h"
+#include "socfpga_plat_def.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_system_manager.h"
 
-
 void deassert_peripheral_reset(void)
 {
 	mmio_clrbits_32(SOCFPGA_RSTMGR(PER1MODRST),
@@ -22,6 +24,7 @@
 			RSTMGR_FIELD(PER1, WATCHDOG1) |
 			RSTMGR_FIELD(PER1, WATCHDOG2) |
 			RSTMGR_FIELD(PER1, WATCHDOG3) |
+			RSTMGR_FIELD(PER1, WATCHDOG4) |
 			RSTMGR_FIELD(PER1, L4SYSTIMER0) |
 			RSTMGR_FIELD(PER1, L4SYSTIMER1) |
 			RSTMGR_FIELD(PER1, SPTIMER0) |
@@ -31,12 +34,15 @@
 			RSTMGR_FIELD(PER1, I2C2) |
 			RSTMGR_FIELD(PER1, I2C3) |
 			RSTMGR_FIELD(PER1, I2C4) |
+			RSTMGR_FIELD(PER1, I3C0) |
+			RSTMGR_FIELD(PER1, I3C1) |
 			RSTMGR_FIELD(PER1, UART0) |
 			RSTMGR_FIELD(PER1, UART1) |
 			RSTMGR_FIELD(PER1, GPIO0) |
 			RSTMGR_FIELD(PER1, GPIO1));
 
 	mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST),
+			RSTMGR_FIELD(PER0, SOFTPHY) |
 			RSTMGR_FIELD(PER0, EMAC0OCP) |
 			RSTMGR_FIELD(PER0, EMAC1OCP) |
 			RSTMGR_FIELD(PER0, EMAC2OCP) |
@@ -79,21 +85,22 @@
 {
 	uint32_t or_mask = 0;
 
-	or_mask |= RSTMGR_HDSKEN_SDRSELFREFEN;
+	or_mask |= RSTMGR_HDSKEN_EMIF_FLUSH;
 	or_mask |= RSTMGR_HDSKEN_FPGAHSEN;
 	or_mask |= RSTMGR_HDSKEN_ETRSTALLEN;
-	or_mask |= RSTMGR_HDSKEN_L2FLUSHEN;
+	or_mask |= RSTMGR_HDSKEN_LWS2F_FLUSH;
 	or_mask |= RSTMGR_HDSKEN_L3NOC_DBG;
 	or_mask |= RSTMGR_HDSKEN_DEBUG_L3NOC;
 
 	mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), or_mask);
 }
 
-static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
 {
-	int time_out = 300;
+	int time_out = delay_ms;
 
-	while (time_out--) {
+	while (time_out-- > 0) {
+
 		if ((mmio_read_32(addr) & mask) == match) {
 			return 0;
 		}
@@ -102,9 +109,45 @@
 	return -ETIMEDOUT;
 }
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+static int poll_idle_status_by_counter(uint32_t addr, uint32_t mask,
+					uint32_t match, uint32_t delay_ms)
+{
+	int time_out = delay_ms;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+
+		/* ToDo: Shall use udelay for product release */
+		for (int i = 0; i < 2000; i++) {
+			/* dummy delay */
+		}
+	}
+	return -ETIMEDOUT;
+}
+#endif
+
+static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
+					 uint32_t match, uint32_t delay_clk_cycles)
+{
+	int time_out = delay_clk_cycles;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+}
+
 static void socfpga_s2f_bridge_mask(uint32_t mask,
-				uint32_t *brg_mask,
-				uint32_t *noc_mask)
+				    uint32_t *brg_mask,
+				    uint32_t *noc_mask)
 {
 	*brg_mask = 0;
 	*noc_mask = 0;
@@ -121,12 +164,13 @@
 }
 
 static void socfpga_f2s_bridge_mask(uint32_t mask,
-				uint32_t *brg_mask,
-				uint32_t *f2s_idlereq,
-				uint32_t *f2s_force_drain,
-				uint32_t *f2s_en,
-				uint32_t *f2s_idleack,
-				uint32_t *f2s_respempty)
+				    uint32_t *brg_mask,
+				    uint32_t *f2s_idlereq,
+				    uint32_t *f2s_force_drain,
+				    uint32_t *f2s_en,
+				    uint32_t *f2s_idleack,
+				    uint32_t *f2s_respempty,
+				    uint32_t *f2s_cmdidle)
 {
 	*brg_mask = 0;
 	*f2s_idlereq = 0;
@@ -134,6 +178,7 @@
 	*f2s_en = 0;
 	*f2s_idleack = 0;
 	*f2s_respempty = 0;
+	*f2s_cmdidle = 0;
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 	if ((mask & FPGA2SOC_MASK) != 0U) {
@@ -144,24 +189,60 @@
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM0_CMDIDLE;
 	}
 	if ((mask & F2SDRAM1_MASK) != 0U) {
 		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM1);
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM1_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM1_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM1_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM1_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM1_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM1_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM1_CMDIDLE;
 	}
 	if ((mask & F2SDRAM2_MASK) != 0U) {
 		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM2);
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM2_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM2_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM2_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM2_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM2_CMDIDLE;
+	}
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	if (mask & FPGA2SOC_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, FPGA2SOC);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+	}
+	if (mask & F2SDRAM0_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM0);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+	}
+	if (mask & F2SDRAM1_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM1);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM1_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM1_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM1_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM1_RESPEMPTY;
+	}
+	if (mask & F2SDRAM2_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM2);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM2_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM2_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM2_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM2_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM2_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM2_RESPEMPTY;
 	}
 #else
 	if ((mask & FPGA2SOC_MASK) != 0U) {
@@ -169,12 +250,160 @@
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM0_CMDIDLE;
 	}
 #endif
 }
 
+int socfpga_bridges_reset(uint32_t mask)
+{
+	int ret = 0;
+	int timeout = 300;
+	uint32_t brg_mask = 0;
+	uint32_t noc_mask = 0;
+	uint32_t f2s_idlereq = 0;
+	uint32_t f2s_force_drain = 0;
+	uint32_t f2s_en = 0;
+	uint32_t f2s_idleack = 0;
+	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
+
+	/* Reset s2f bridge */
+	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+	if (brg_mask) {
+		if (mask & SOC2FPGA_MASK) {
+			/* Request handshake with SOC2FPGA bridge to clear traffic */
+			mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_S2F_FLUSH);
+
+			/* Wait for bridge to idle status */
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+					RSTMGR_HDSKACK_S2F_FLUSH,
+					RSTMGR_HDSKACK_S2F_FLUSH, 300);
+		}
+
+		if (mask & LWHPS2FPGA_MASK) {
+			/* Request handshake with LWSOC2FPGA bridge to clear traffic */
+			mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_LWS2F_FLUSH);
+
+			/* Wait for bridge to idle status */
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+					RSTMGR_HDSKACK_LWS2F_FLUSH,
+					RSTMGR_HDSKACK_LWS2F_FLUSH, 300);
+		}
+
+		if (ret < 0) {
+			ERROR("S2F Bridge reset: Timeout waiting for idle ack\n");
+			assert(false);
+		}
+
+		/* Assert reset to bridge */
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				brg_mask);
+
+		/* Clear idle requests to bridge */
+		if (mask & SOC2FPGA_MASK) {
+			mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_S2F_FLUSH);
+		}
+
+		if (mask & LWHPS2FPGA_MASK) {
+			mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_LWS2F_FLUSH);
+		}
+
+		/* When FPGA reconfig is complete */
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
+	}
+
+	/* Reset f2s bridge */
+	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+					&f2s_force_drain, &f2s_en,
+					&f2s_idleack, &f2s_respempty,
+					&f2s_cmdidle);
+
+	if (brg_mask) {
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
+				RSTMGR_HDSKEN_FPGAHSEN);
+
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSREQ,
+				RSTMGR_HDSKACK_FPGAHSREQ, 300);
+
+		if (ret < 0) {
+			ERROR("F2S Bridge disable: Timeout waiting for idle req\n");
+			assert(false);
+		}
+
+		/* Disable f2s bridge */
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+				f2s_en);
+		udelay(5);
+
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+				f2s_force_drain);
+		udelay(5);
+
+		do {
+			/* Read response queue status to ensure it is empty */
+			uint32_t idle_status;
+
+			idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
+				SIDEBANDMGR_FLAGINSTATUS0));
+			if (idle_status & f2s_respempty) {
+				idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
+					SIDEBANDMGR_FLAGINSTATUS0));
+				if (idle_status & f2s_respempty) {
+					break;
+				}
+			}
+			udelay(1000);
+		} while (timeout-- > 0);
+
+		/* Assert reset to f2s bridge */
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				brg_mask);
+
+		/* Clear idle request to FPGA */
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Clear idle request to MPFE */
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+				f2s_idlereq);
+
+		/* When FPGA reconfig is complete */
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
+
+		/* Enable f2s bridge */
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_idlereq);
+
+		ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(
+			SIDEBANDMGR_FLAGINSTATUS0), f2s_idleack, 0, 300);
+		if (ret < 0) {
+			ERROR("F2S bridge enable: Timeout waiting for idle ack");
+			assert(false);
+		}
+
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_force_drain);
+		udelay(5);
+
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_en);
+		udelay(5);
+	}
+
+	return ret;
+}
+
 int socfpga_bridges_enable(uint32_t mask)
 {
 	int ret = 0;
@@ -185,9 +414,88 @@
 	uint32_t f2s_en = 0;
 	uint32_t f2s_idleack = 0;
 	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	uint32_t delay = 0;
+#endif
 
 	/* Enable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Enable SOC2FPGA bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA) {
+		/* Write Reset Manager hdskreq[soc2fpga_flush_req] = 1 */
+		NOTICE("Set S2F hdskreq ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+
+		/* Read Reset Manager hdskack[soc2fpga] = 1 */
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_SOC2FPGAACK, RSTMGR_HDSKACK_SOC2FPGAACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("S2F bridge enable: Timeout hdskack\n");
+		}
+
+		/* Write Reset Manager hdskreq[soc2fpga_flush_req] = 0 */
+		NOTICE("Clear S2F hdskreq ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+
+		/* Write Reset Manager brgmodrst[soc2fpga] = 1 */
+		NOTICE("Assert S2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_SOC2FPGA);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[soc2fpga] = 0 */
+		NOTICE("Deassert S2F ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_SOC2FPGA);
+	}
+
+	/* Enable LWSOC2FPGA bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) {
+		/* Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 1 */
+		NOTICE("Set LWS2F hdskreq ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+
+		/* Read Reset Manager hdskack[lwsoc2fpga] = 1 */
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_LWSOC2FPGAACK, RSTMGR_HDSKACK_LWSOC2FPGAACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("LWS2F bridge enable: Timeout hdskack\n");
+		}
+
+		/* Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 0 */
+		NOTICE("Clear LWS2F hdskreq ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+
+		/* Write Reset Manager brgmodrst[lwsoc2fpga] = 1 */
+		NOTICE("Assert LWS2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[lwsoc2fpga] = 0 */
+		NOTICE("Deassert LWS2F ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_LWHPS2FPGA);
+	}
+#else
 	if (brg_mask != 0U) {
 		/* Clear idle request */
 		mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_CLR),
@@ -198,38 +506,256 @@
 
 		/* Wait until idle ack becomes 0 */
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-						noc_mask, 0);
+				       noc_mask, 0, 300);
 		if (ret < 0) {
-			ERROR("S2F bridge enable: "
-					"Timeout waiting for idle ack\n");
+			ERROR("S2F bridge enable: Timeout idle ack\n");
 		}
 	}
+#endif
 
 	/* Enable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
-						&f2s_force_drain, &f2s_en,
-						&f2s_idleack, &f2s_respempty);
+				&f2s_force_drain, &f2s_en,
+				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Enable FPGA2SOC bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC) {
+		/* Write Reset Manager hdsken[fpgahsen] = 1 */
+		NOTICE("Set FPGA hdsken(fpgahsen) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Set FPGA hdskreq(fpgahsreq) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Read Reset Manager hdskack[fpgahsack] = 1 */
+		NOTICE("Get FPGA hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("FPGA bridge fpga handshake fpgahsreq: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[f2s_flush_req] = 1 */
+		NOTICE("Set F2S hdskreq(f2s_flush_req) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_FPGA2SOCREQ);
+
+		/* Read Reset Manager hdskack[f2s_flush_ack] = 1 */
+		NOTICE("Get F2S hdskack(f2s_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2sdram_flush_req: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Clear FPGA hdskreq(fpgahsreq) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Write Reset Manager hdskreq[f2s_flush_req] = 1 */
+		NOTICE("Clear F2S hdskreq(f2s_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_FPGA2SOCREQ);
+
+		/* Read Reset Manager hdskack[f2s_flush_ack] = 0 */
+		NOTICE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
+		}
+
+		/* Read Reset Manager hdskack[fpgahsack] = 0 */
+		NOTICE("Get FPGA hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2soc] = 1 */
+		NOTICE("Assert F2S ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2soc] = 0 */
+		NOTICE("Deassert F2S ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
+
+		/* Write System Manager f2s bridge control register[f2soc_enable] = 1 */
+		NOTICE("Deassert F2S f2soc_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(F2S_BRIDGE_CTRL),
+			SYSMGR_F2S_BRIDGE_CTRL_EN);
+	}
+
+	/* Enable FPGA2SDRAM bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0) {
+		/* Write Reset Manager hdsken[fpgahsen] = 1 */
+		NOTICE("Set F2SDRAM hdsken(fpgahsen) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Set F2SDRAM hdskreq(fpgahsreq) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Read Reset Manager hdskack[fpgahsack] = 1 */
+		NOTICE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake fpgahsreq: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[f2sdram_flush_req] = 1 */
+		NOTICE("Set F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_F2SDRAM0REQ);
+
+		/* Read Reset Manager hdskack[f2sdram_flush_ack] = 1 */
+		NOTICE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_req: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Clear F2SDRAM hdskreq(fpgahsreq) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Write Reset Manager hdskreq[f2sdram_flush_req] = 1 */
+		NOTICE("Clear F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_F2SDRAM0REQ);
+
+		/* Read Reset Manager hdskack[f2sdram_flush_ack] = 0 */
+		NOTICE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_ack: Timeout\n");
+		}
+
+		/* Read Reset Manager hdskack[fpgahsack] = 0 */
+		NOTICE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake fpgahsack: Timeout\n");
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2sdram] = 1 */
+		NOTICE("Assert F2SDRAM ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_F2SSDRAM0);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2sdram] = 0 */
+		NOTICE("Deassert F2SDRAM ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_F2SSDRAM0);
+
+		/*
+		 * Clear fpga2sdram_manager_main_SidebandManager_FlagOutClr0
+		 * f2s_ready_latency_enable
+		 */
+		NOTICE("Clear F2SDRAM f2s_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+			FLAGOUTCLR0_F2SDRAM0_ENABLE);
+	}
+#else
 	if (brg_mask != 0U) {
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
 
-		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-			f2s_idlereq);
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+				f2s_idlereq);
 
-		ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(
-			SIDEBANDMGR_FLAGINSTATUS0), f2s_idleack, 0);
+		ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0),
+				       f2s_idleack, 0, 300);
+
 		if (ret < 0) {
-			ERROR("F2S bridge enable: "
-					"Timeout waiting for idle ack");
+			ERROR("F2S bridge enable: Timeout idle ack");
 		}
 
-		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-			f2s_force_drain);
+		/* Clear the force drain */
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+				f2s_force_drain);
 		udelay(5);
 
 		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-			f2s_en);
+				f2s_en);
 		udelay(5);
 	}
+#endif
+	return ret;
+}
+
+int socfpga_bridge_nongraceful_disable(uint32_t mask)
+{
+	int ret = 0;
+	int timeout = 1000;
+	uint32_t brg_mask = 0;
+	uint32_t f2s_idlereq = 0;
+	uint32_t f2s_force_drain = 0;
+	uint32_t f2s_en = 0;
+	uint32_t f2s_idleack = 0;
+	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
+
+	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+				&f2s_force_drain, &f2s_en,
+				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
+
+	mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_idlereq);
+
+	/* Time out Error - Bus is still active */
+	/* Performing a non-graceful shutdown with Force drain */
+	mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_force_drain);
+
+	ret = -ETIMEDOUT;
+	do {
+		/* Read response queue status to ensure it is empty */
+		uint32_t idle_status;
+
+		idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0));
+		if ((idle_status & f2s_respempty) != 0U) {
+			idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0));
+			if ((idle_status & f2s_respempty) != 0U) {
+				/* No time-out we are good! */
+				ret = 0;
+				break;
+			}
+		}
+
+		asm("nop");
+
+	} while (timeout-- > 0);
 
 	return ret;
 }
@@ -237,7 +763,6 @@
 int socfpga_bridges_disable(uint32_t mask)
 {
 	int ret = 0;
-	int timeout = 300;
 	uint32_t brg_mask = 0;
 	uint32_t noc_mask = 0;
 	uint32_t f2s_idlereq = 0;
@@ -245,6 +770,7 @@
 	uint32_t f2s_en = 0;
 	uint32_t f2s_idleack = 0;
 	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
 
 	/* Disable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
@@ -255,17 +781,15 @@
 		mmio_write_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1);
 
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-						noc_mask, noc_mask);
+				       noc_mask, noc_mask, 300);
 		if (ret < 0) {
-			ERROR("S2F Bridge disable: "
-					"Timeout waiting for idle ack\n");
+			ERROR("S2F Bridge disable: Timeout idle ack\n");
 		}
 
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS),
-						noc_mask, noc_mask);
+				       noc_mask, noc_mask, 300);
 		if (ret < 0) {
-			ERROR("S2F Bridge disable: "
-					"Timeout waiting for idle status\n");
+			ERROR("S2F Bridge disable: Timeout idle status\n");
 		}
 
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
@@ -275,43 +799,35 @@
 
 	/* Disable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
-						&f2s_force_drain, &f2s_en,
-						&f2s_idleack, &f2s_respempty);
+				&f2s_force_drain, &f2s_en,
+				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
 	if (brg_mask != 0U) {
+
+		if (mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST)) & brg_mask) {
+			/* Bridge cannot be reset twice */
+			return 0;
+		}
+
+		/* Starts the fence and drain traffic from F2SDRAM to MPFE */
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
 				RSTMGR_HDSKEN_FPGAHSEN);
-
+		udelay(5);
+		/* Ignoring FPGA ACK as it will time-out */
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
 				RSTMGR_HDSKREQ_FPGAHSREQ);
 
-		poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-				RSTMGR_HDSKACK_FPGAHSACK_MASK,
-				RSTMGR_HDSKACK_FPGAHSACK_MASK);
+		ret = poll_idle_status_by_clkcycles(SOCFPGA_RSTMGR(HDSKACK),
+						    RSTMGR_HDSKACK_FPGAHSREQ,
+						    RSTMGR_HDSKACK_FPGAHSREQ, 1000);
 
-		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+		/* DISABLE F2S Bridge */
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
 				f2s_en);
 		udelay(5);
 
-		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-				f2s_force_drain);
-		udelay(5);
-
-		do {
-			/* Read response queue status to ensure it is empty */
-			uint32_t idle_status;
-
-			idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
-				SIDEBANDMGR_FLAGINSTATUS0));
-			if ((idle_status & f2s_respempty) != 0U) {
-				idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
-					SIDEBANDMGR_FLAGINSTATUS0));
-				if ((idle_status & f2s_respempty) != 0U) {
-					break;
-				}
-			}
-			udelay(1000);
-		} while (timeout-- > 0);
+		ret = socfpga_bridge_nongraceful_disable(mask);
 
+		/* Bridge reset */
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 		/* Software must never write a 0x1 to FPGA2SOC_MASK bit */
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
@@ -320,8 +836,9 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 				brg_mask);
 #endif
+		/* Re-enable traffic to SDRAM*/
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-				RSTMGR_HDSKEQ_FPGAHSREQ);
+				RSTMGR_HDSKREQ_FPGAHSREQ);
 
 		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
 				f2s_idlereq);
@@ -329,3 +846,68 @@
 
 	return ret;
 }
+
+/* CPUxRESETBASELOW */
+int socfpga_cpu_reset_base(unsigned int cpu_id)
+{
+	int ret = 0;
+	uint32_t entrypoint = 0;
+
+	ret = socfpga_cpurstrelease(cpu_id);
+
+	if (ret < 0) {
+		return RSTMGR_RET_ERROR;
+	}
+
+	if (ret == RSTMGR_RET_OK) {
+
+		switch (cpu_id) {
+		case 0:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_0);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_0) << 24;
+		break;
+
+		case 1:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_1);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_1) << 24;
+		break;
+
+		case 2:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_2);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_2) << 24;
+		break;
+
+		case 3:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_3);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_3) << 24;
+		break;
+
+		default:
+		break;
+		}
+
+		mmio_write_64(PLAT_SEC_ENTRY, entrypoint);
+	}
+
+	return RSTMGR_RET_OK;
+}
+
+/* CPURSTRELEASE */
+int socfpga_cpurstrelease(unsigned int cpu_id)
+{
+	unsigned int timeout = 0;
+
+	do {
+		/* Read response queue status to ensure it is empty */
+		uint32_t cpurstrelease_status;
+
+		cpurstrelease_status = mmio_read_32(SOCFPGA_RSTMGR(CPURSTRELEASE));
+
+		if ((cpurstrelease_status & RSTMGR_CPUSTRELEASE_CPUx) == cpu_id) {
+			return RSTMGR_RET_OK;
+		}
+		udelay(1000);
+	} while (timeout-- > 0);
+
+	return RSTMGR_RET_ERROR;
+}
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index dcd51e2..8fce5cf 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -10,6 +10,15 @@
 #include <lib/mmio.h>
 #include "socfpga_plat_def.h"
 
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+#include "agilex_clock_manager.h"
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X
+#include "n5x_clock_manager.h"
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
+#include "s10_clock_manager.h"
+#endif
+
 #define SOCFPGA_GLOBAL_TIMER		0xffd01000
 #define SOCFPGA_GLOBAL_TIMER_EN		0x3
 
@@ -43,6 +52,8 @@
 	socfpga_delay_timer_init_args();
 	mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
 
+	NOTICE("BL31 CLK freq = %d MHz\n", PLAT_SYS_COUNTER_FREQ_IN_MHZ);
+
 	asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
 	asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
 
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 5fd6559..5ffd512 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -1,21 +1,31 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+
+#ifndef GICV3_SUPPORT_GIC600
 #include <drivers/arm/gicv2.h>
+#else
+#include <drivers/arm/gicv3.h>
+#endif
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
-
 #include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
+#include "socfpga_system_manager.h"
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+void socfpga_wakeup_secondary_cpu(unsigned int cpu_id);
+extern void plat_secondary_cold_boot_setup(void);
+#endif
 
 /*******************************************************************************
  * plat handler called when a CPU is about to enter standby.
@@ -38,16 +48,35 @@
 int socfpga_pwr_domain_on(u_register_t mpidr)
 {
 	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* TODO: Add in CPU FUSE from SDM */
+#else
+	uint32_t psci_boot = 0x00;
 
 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
+#endif
 
 	if (cpu_id == -1)
 		return PSCI_E_INTERN_FAIL;
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
+	if (cpu_id == 0x00) {
+		psci_boot = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8));
+		psci_boot |= 0x20000; /* bit 17 */
+		mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8), psci_boot);
+	}
+
 	mmio_write_64(PLAT_CPUID_RELEASE, cpu_id);
+#endif
 
 	/* release core reset */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	bl31_plat_set_secondary_cpu_entrypoint(cpu_id);
+#else
 	mmio_setbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id);
+	mmio_write_64(PLAT_CPUID_RELEASE, cpu_id);
+#endif
+
 	return PSCI_E_SUCCESS;
 }
 
@@ -62,7 +91,12 @@
 			__func__, i, target_state->pwr_domain_state[i]);
 
 	/* Prevent interrupts from spuriously waking up this cpu */
+#ifdef GICV3_SUPPORT_GIC600
+	gicv3_cpuif_disable(plat_my_core_pos());
+#else
 	gicv2_cpuif_disable();
+#endif
+
 }
 
 /*******************************************************************************
@@ -71,15 +105,18 @@
  ******************************************************************************/
 void socfpga_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	unsigned int cpu_id = plat_my_core_pos();
+#endif
 
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	/* assert core reset */
 	mmio_setbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id);
-
+#endif
 }
 
 /*******************************************************************************
@@ -93,12 +130,18 @@
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
+	/* Enable the gic cpu interface */
+#ifdef GICV3_SUPPORT_GIC600
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+#else
 	/* Program the gic per-cpu distributor or re-distributor interface */
 	gicv2_pcpu_distif_init();
 	gicv2_set_pe_target_mask(plat_my_core_pos());
 
 	/* Enable the gic cpu interface */
 	gicv2_cpuif_enable();
+#endif
 }
 
 /*******************************************************************************
@@ -110,14 +153,18 @@
  ******************************************************************************/
 void socfpga_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
 {
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	unsigned int cpu_id = plat_my_core_pos();
+#endif
 
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	/* release core reset */
 	mmio_clrbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id);
+#endif
 }
 
 /*******************************************************************************
@@ -138,11 +185,11 @@
 
 	memcpy(addr_buf, &intel_rsu_update_address,
 			sizeof(intel_rsu_update_address));
-
-	if (intel_rsu_update_address)
+	if (intel_rsu_update_address) {
 		mailbox_rsu_update(addr_buf);
-	else
+	} else {
 		mailbox_reset_cold();
+	}
 
 	while (1)
 		wfi();
@@ -151,11 +198,20 @@
 static int socfpga_system_reset2(int is_vendor, int reset_type,
 					u_register_t cookie)
 {
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mailbox_reset_warm(reset_type);
+#else
 	if (cold_reset_for_ecc_dbe()) {
 		mailbox_reset_cold();
 	}
+#endif
+
 	/* disable cpuif */
+#ifdef GICV3_SUPPORT_GIC600
+	gicv3_cpuif_disable(plat_my_core_pos());
+#else
 	gicv2_cpuif_disable();
+#endif
 
 	/* Store magic number */
 	mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
@@ -166,8 +222,10 @@
 	/* Enable handshakes */
 	mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_SET);
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	/* Reset L2 module */
 	mmio_setbits_32(SOCFPGA_RSTMGR(COLDMODRST), 0x100);
+#endif
 
 	while (1)
 		wfi();
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 79f743f..c6530cf 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,9 +12,10 @@
 
 #include "socfpga_fcs.h"
 #include "socfpga_mailbox.h"
+#include "socfpga_plat_def.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
-
+#include "socfpga_system_manager.h"
 
 /* Total buffer the driver can hold */
 #define FPGA_CONFIG_BUFFER_SIZE 4
@@ -334,6 +335,7 @@
 	return 0;
 #endif
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	switch (reg_addr) {
 	case(0xF8011100):	/* ECCCTRL1 */
 	case(0xF8011104):	/* ECCCTRL2 */
@@ -385,7 +387,41 @@
 	case(0xFFD12220):	/* BOOT_SCRATCH_COLD8 */
 	case(0xFFD12224):	/* BOOT_SCRATCH_COLD9 */
 		return 0;
+#else
+	switch (reg_addr) {
 
+	case(0xF8011104):	/* ECCCTRL2 */
+	case(0xFFD12028):	/* SDMMCGRP_CTRL */
+	case(0xFFD120C4):	/* NOC_IDLEREQ_SET */
+	case(0xFFD120C8):	/* NOC_IDLEREQ_CLR */
+	case(0xFFD120D0):	/* NOC_IDLEACK */
+
+
+	case(SOCFPGA_MEMCTRL(ECCCTRL1)):	/* ECCCTRL1 */
+	case(SOCFPGA_MEMCTRL(ERRINTEN)):	/* ERRINTEN */
+	case(SOCFPGA_MEMCTRL(ERRINTENS)):	/* ERRINTENS */
+	case(SOCFPGA_MEMCTRL(ERRINTENR)):	/* ERRINTENR */
+	case(SOCFPGA_MEMCTRL(INTMODE)):	/* INTMODE */
+	case(SOCFPGA_MEMCTRL(INTSTAT)):	/* INTSTAT */
+	case(SOCFPGA_MEMCTRL(DIAGINTTEST)):	/* DIAGINTTEST */
+	case(SOCFPGA_MEMCTRL(DERRADDRA)):	/* DERRADDRA */
+
+	case(SOCFPGA_SYSMGR(EMAC_0)):	/* EMAC0 */
+	case(SOCFPGA_SYSMGR(EMAC_1)):	/* EMAC1 */
+	case(SOCFPGA_SYSMGR(EMAC_2)):	/* EMAC2 */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_VALUE)):	/* ECC_INT_MASK_VALUE */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_SET)):	/* ECC_INT_MASK_SET */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_CLR)):	/* ECC_INT_MASK_CLEAR */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_SERR)):	/* ECC_INTSTATUS_SERR */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_DERR)):	/* ECC_INTSTATUS_DERR */
+	case(SOCFPGA_SYSMGR(NOC_TIMEOUT)):	/* NOC_TIMEOUT */
+	case(SOCFPGA_SYSMGR(NOC_IDLESTATUS)):	/* NOC_IDLESTATUS */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0)):	/* BOOT_SCRATCH_COLD0 */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)):	/* BOOT_SCRATCH_COLD1 */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8)):	/* BOOT_SCRATCH_COLD8 */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_9)):	/* BOOT_SCRATCH_COLD9 */
+		return 0;
+#endif
 	default:
 		break;
 	}
@@ -441,8 +477,12 @@
 	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;
+	}
+
 	intel_rsu_update_address = update_address;
 	return INTEL_SIP_SMC_STATUS_OK;
 }
@@ -648,6 +688,16 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+/* SDM SEU Error services */
+static uint32_t intel_sdm_seu_err_read(uint64_t *respbuf, unsigned int respbuf_sz)
+{
+	if (mailbox_seu_err_status((uint32_t *)respbuf, respbuf_sz) < 0) {
+		return INTEL_SIP_SMC_SEU_ERR_READ_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -664,7 +714,7 @@
 	uint32_t retval = 0, completed_addr[3];
 	uint32_t retval2 = 0;
 	uint32_t mbox_error = 0;
-	uint64_t retval64, rsu_respbuf[9];
+	uint64_t retval64, rsu_respbuf[9], seu_respbuf[3];
 	int status = INTEL_SIP_SMC_STATUS_OK;
 	int mbox_status;
 	unsigned int len_in_resp;
@@ -1170,6 +1220,15 @@
 					SIP_SVC_VERSION_MAJOR,
 					SIP_SVC_VERSION_MINOR);
 
+	case INTEL_SIP_SMC_SEU_ERR_STATUS:
+		status = intel_sdm_seu_err_read(seu_respbuf,
+					ARRAY_SIZE(seu_respbuf));
+		if (status) {
+			SMC_RET1(handle, status);
+		} else {
+			SMC_RET3(handle, seu_respbuf[0], seu_respbuf[1], seu_respbuf[2]);
+		}
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
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/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index a2f2c18..e80f074 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,29 +9,37 @@
 #include <assert.h>
 #include <common/debug.h>
 #include <common/tbbr/tbbr_img_def.h>
+#include <drivers/cadence/cdns_nand.h>
+#include <drivers/cadence/cdns_sdmmc.h>
 #include <drivers/io/io_block.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_fip.h>
 #include <drivers/io/io_memmap.h>
+#include <drivers/io/io_mtd.h>
 #include <drivers/io/io_storage.h>
 #include <drivers/mmc.h>
 #include <drivers/partition/partition.h>
 #include <lib/mmio.h>
 #include <tools_share/firmware_image_package.h>
 
+#include "drivers/sdmmc/sdmmc.h"
 #include "socfpga_private.h"
 
+
 #define PLAT_FIP_BASE		(0)
 #define PLAT_FIP_MAX_SIZE	(0x1000000)
 #define PLAT_MMC_DATA_BASE	(0xffe3c000)
 #define PLAT_MMC_DATA_SIZE	(0x2000)
 #define PLAT_QSPI_DATA_BASE	(0x3C00000)
 #define PLAT_QSPI_DATA_SIZE	(0x1000000)
-
+#define PLAT_NAND_DATA_BASE	(0x0200000)
+#define PLAT_NAND_DATA_SIZE	(0x1000000)
 
 static const io_dev_connector_t *fip_dev_con;
 static const io_dev_connector_t *boot_dev_con;
 
+static io_mtd_dev_spec_t nand_dev_spec;
+
 static uintptr_t fip_dev_handle;
 static uintptr_t boot_dev_handle;
 
@@ -136,17 +144,27 @@
 	case BOOT_SOURCE_SDMMC:
 		register_io_dev = &register_io_dev_block;
 		boot_dev_spec.buffer.offset	= PLAT_MMC_DATA_BASE;
-		boot_dev_spec.buffer.length	= MMC_BLOCK_SIZE;
-		boot_dev_spec.ops.read		= mmc_read_blocks;
-		boot_dev_spec.ops.write		= mmc_write_blocks;
+		boot_dev_spec.buffer.length	= SOCFPGA_MMC_BLOCK_SIZE;
+		boot_dev_spec.ops.read		= SDMMC_READ_BLOCKS;
+		boot_dev_spec.ops.write		= SDMMC_WRITE_BLOCKS;
 		boot_dev_spec.block_size	= MMC_BLOCK_SIZE;
 		break;
 
 	case BOOT_SOURCE_QSPI:
 		register_io_dev = &register_io_dev_memmap;
-		fip_spec.offset = fip_spec.offset + PLAT_QSPI_DATA_BASE;
+		fip_spec.offset = PLAT_QSPI_DATA_BASE;
 		break;
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	case BOOT_SOURCE_NAND:
+		register_io_dev = &register_io_dev_mtd;
+		nand_dev_spec.ops.init = cdns_nand_init_mtd;
+		nand_dev_spec.ops.read = cdns_nand_read;
+		nand_dev_spec.ops.write = NULL;
+		fip_spec.offset = PLAT_NAND_DATA_BASE;
+		break;
+#endif
+
 	default:
 		ERROR("Unsupported boot source\n");
 		panic();
@@ -159,8 +177,13 @@
 	result = register_io_dev_fip(&fip_dev_con);
 	assert(result == 0);
 
-	result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
-			&boot_dev_handle);
+	if (boot_source == BOOT_SOURCE_NAND) {
+		result = io_dev_open(boot_dev_con, (uintptr_t)&nand_dev_spec,
+								&boot_dev_handle);
+	} else {
+		result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
+								&boot_dev_handle);
+	}
 	assert(result == 0);
 
 	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
diff --git a/plat/intel/soc/common/socfpga_topology.c b/plat/intel/soc/common/socfpga_topology.c
index ca1a91e..28c9557 100644
--- a/plat/intel/soc/common/socfpga_topology.c
+++ b/plat/intel/soc/common/socfpga_topology.c
@@ -33,8 +33,8 @@
 	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
 		return -1;
 
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+	cluster_id = (mpidr >> PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> PLAT_CPU_ID_MPIDR_AFF_SHIFT) & MPIDR_AFFLVL_MASK;
 
 	if (cluster_id >= PLATFORM_CLUSTER_COUNT)
 		return -1;
diff --git a/plat/intel/soc/common/socfpga_vab.c b/plat/intel/soc/common/socfpga_vab.c
new file mode 100644
index 0000000..e16610c
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_vab.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "socfpga_mailbox.h"
+#include "socfpga_vab.h"
+
+static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
+{
+	uint8_t *img_buf_end = img_buf + img_buf_sz;
+	uint32_t cert_sz = get_unaligned_le32(img_buf_end - sizeof(uint32_t));
+	uint8_t *p = img_buf_end - cert_sz - sizeof(uint32_t);
+
+	/* Ensure p is pointing within the img_buf */
+	if (p < img_buf || p > (img_buf_end - VAB_CERT_HEADER_SIZE))
+		return 0;
+
+	if (get_unaligned_le32(p) == SDM_CERT_MAGIC_NUM)
+		return (size_t)(p - img_buf);
+
+	return 0;
+}
+
+
+
+int socfpga_vendor_authentication(void **p_image, size_t *p_size)
+{
+	int retry_count = 20;
+	uint8_t hash384[FCS_SHA384_WORD_SIZE];
+	uint64_t img_addr, mbox_data_addr;
+	uint32_t img_sz, mbox_data_sz;
+	uint8_t *cert_hash_ptr, *mbox_relocate_data_addr;
+	uint32_t resp = 0, resp_len = 1;
+	int ret = 0;
+
+	img_addr = (uintptr_t)*p_image;
+	img_sz = get_img_size((uint8_t *)img_addr, *p_size);
+
+	if (!img_sz) {
+		NOTICE("VAB certificate not found in image!\n");
+		return -ENOVABIMG;
+	}
+
+	if (!IS_BYTE_ALIGNED(img_sz, sizeof(uint32_t))) {
+		NOTICE("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
+		return -EIMGERR;
+	}
+
+	/* Generate HASH384 from the image */
+	/* TODO: This part need to cross check !!!!!! */
+	sha384_csum_wd((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
+	cert_hash_ptr = (uint8_t *)(img_addr + img_sz +
+	VAB_CERT_MAGIC_OFFSET + VAB_CERT_FIT_SHA384_OFFSET);
+
+	/*
+	 * Compare the SHA384 found in certificate against the SHA384
+	 * calculated from image
+	 */
+	if (memcmp(hash384, cert_hash_ptr, FCS_SHA384_WORD_SIZE)) {
+		NOTICE("SHA384 does not match!\n");
+		return -EKEYREJECTED;
+	}
+
+
+	mbox_data_addr = img_addr + img_sz - sizeof(uint32_t);
+	/* Size in word (32bits) */
+	mbox_data_sz = (BYTE_ALIGN(*p_size - img_sz, sizeof(uint32_t))) >> 2;
+
+	NOTICE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
+
+	/* TODO: This part need to cross check !!!!!! */
+	// mbox_relocate_data_addr = (uint8_t *)malloc(mbox_data_sz * sizeof(uint32_t));
+	// if (!mbox_relocate_data_addr) {
+		// NOTICE("Cannot allocate memory for VAB certificate relocation!\n");
+		// return -ENOMEM;
+	// }
+
+	memcpy(mbox_relocate_data_addr, (uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
+	*(uint32_t *)mbox_relocate_data_addr = 0;
+
+	do {
+		/* Invoke SMC call to ATF to send the VAB certificate to SDM */
+		ret  = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_VAB_SRC_CERT,
+(uint32_t *)mbox_relocate_data_addr, mbox_data_sz, 0, &resp, &resp_len);
+
+		/* If SDM is not available, just delay 50ms and retry again */
+		/* 0x1FF = The device is busy */
+		if (ret == MBOX_RESP_ERR(0x1FF)) {
+			mdelay(50);
+		} else {
+			break;
+		}
+	} while (--retry_count);
+
+	/* Free the relocate certificate memory space */
+	zeromem((void *)&mbox_relocate_data_addr, sizeof(uint32_t));
+
+
+	/* Exclude the size of the VAB certificate from image size */
+	*p_size = img_sz;
+
+	if (ret) {
+		/*
+		 * Unsupported mailbox command or device not in the
+		 * owned/secure state
+		 */
+		 /* 0x85 = Not allowed under current security setting */
+		if (ret == MBOX_RESP_ERR(0x85)) {
+			/* SDM bypass authentication */
+			NOTICE("Image Authentication bypassed at address\n");
+			return 0;
+		}
+		NOTICE("VAB certificate authentication failed in SDM\n");
+		/* 0x1FF = The device is busy */
+		if (ret == MBOX_RESP_ERR(0x1FF)) {
+			NOTICE("Operation timed out\n");
+			return -ETIMEOUT;
+		} else if (ret == MBOX_WRONG_ID) {
+			NOTICE("No such process\n");
+			return -EPROCESS;
+		}
+	} else {
+		/* If Certificate Process Status has error */
+		if (resp) {
+			NOTICE("VAB certificate execution format error\n");
+			return -EIMGERR;
+		}
+	}
+
+	NOTICE("Image Authentication bypassed at address\n");
+	return ret;
+
+}
+
+static uint32_t get_unaligned_le32(const void *p)
+{
+	/* TODO: Temp for testing */
+	//return le32_to_cpup((__le32 *)p);
+	return 0;
+}
+
+void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
+		unsigned char *output, unsigned int chunk_sz)
+{
+	/* TODO: Update sha384 start, update and finish */
+}
diff --git a/plat/intel/soc/n5x/bl31_plat_setup.c b/plat/intel/soc/n5x/bl31_plat_setup.c
index 5ca1a71..a5337ce 100644
--- a/plat/intel/soc/n5x/bl31_plat_setup.c
+++ b/plat/intel/soc/n5x/bl31_plat_setup.c
@@ -140,7 +140,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/intel/soc/n5x/include/n5x_clock_manager.h b/plat/intel/soc/n5x/include/n5x_clock_manager.h
new file mode 100644
index 0000000..14a5717
--- /dev/null
+++ b/plat/intel/soc/n5x/include/n5x_clock_manager.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CLOCKMANAGER_H
+#define CLOCKMANAGER_H
+
+#include "socfpga_handoff.h"
+
+/* MACRO DEFINITION */
+#define SOCFPGA_GLOBAL_TIMER				0xffd01000
+#define SOCFPGA_GLOBAL_TIMER_EN				0x3
+
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK			GENMASK(17, 16)
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET			16
+#define CLKMGR_PLLDIV_FDIV_MASK				GENMASK(16, 8)
+#define CLKMGR_PLLDIV_FDIV_OFFSET			8
+#define CLKMGR_PLLDIV_REFCLKDIV_MASK			GENMASK(5, 0)
+#define CLKMGR_PLLDIV_REFCLKDIV_OFFSET			0
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_MASK			GENMASK(26, 24)
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET		24
+
+#define CLKMGR_PLLOUTDIV_C0CNT_MASK			GENMASK(4, 0)
+#define CLKMGR_PLLOUTDIV_C0CNT_OFFSET			0
+#define CLKMGR_PLLOUTDIV_C1CNT_MASK			GENMASK(12, 8)
+#define CLKMGR_PLLOUTDIV_C1CNT_OFFSET			8
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_MASK			GENMASK(26, 24)
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET		24
+#define CLKMGR_CLKSRC_MASK				GENMASK(18, 16)
+#define CLKMGR_CLKSRC_OFFSET				16
+#define CLKMGR_NOCDIV_DIVIDER_MASK			GENMASK(1, 0)
+#define CLKMGR_NOCDIV_L4MAIN_OFFSET			0
+
+#define CLKMGR_INTOSC_HZ				400000000
+#define CLKMGR_VCO_PSRC_EOSC1				0
+#define CLKMGR_VCO_PSRC_INTOSC				1
+#define CLKMGR_VCO_PSRC_F2S				2
+#define CLKMGR_CLKSRC_MAIN				0
+#define CLKMGR_CLKSRC_PER				1
+
+#define CLKMGR_N5X_BASE					0xffd10000
+#define CLKMGR_MAINPLL_NOCCLK				0x40
+#define CLKMGR_MAINPLL_NOCDIV				0x44
+#define CLKMGR_MAINPLL_PLLGLOB				0x48
+#define CLKMGR_MAINPLL_PLLOUTDIV			0x54
+#define CLKMGR_MAINPLL_PLLDIV				0x50
+#define CLKMGR_PERPLL_PLLGLOB				0x9c
+#define CLKMGR_PERPLL_PLLDIV				0xa4
+#define CLKMGR_PERPLL_PLLOUTDIV				0xa8
+
+/* FUNCTION DEFINITION */
+uint64_t clk_get_pll_output_hz(void);
+uint64_t get_l4_clk(void);
+uint32_t get_clk_freq(uint32_t psrc_reg);
+uint32_t get_mpu_clk(void);
+uint32_t get_cpu_clk(void);
+
+#endif
diff --git a/plat/intel/soc/n5x/include/n5x_system_manager.h b/plat/intel/soc/n5x/include/n5x_system_manager.h
new file mode 100644
index 0000000..b628219
--- /dev/null
+++ b/plat/intel/soc/n5x/include/n5x_system_manager.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef N5X_SOCFPGA_SYSTEMMANAGER_H
+#define N5X_SOCFPGA_SYSTEMMANAGER_H
+
+#include "socfpga_plat_def.h"
+
+/* System Manager Register Map */
+#define SOCFPGA_SYSMGR_SILICONID_1			0x00
+#define SOCFPGA_SYSMGR_SILICONID_2			0x04
+#define SOCFPGA_SYSMGR_WDDBG				0x08
+#define SOCFPGA_SYSMGR_MPU_STATUS			0x10
+#define SOCFPGA_SYSMGR_SDMMC_L3_MASTER			0x2C
+#define SOCFPGA_SYSMGR_NAND_L3_MASTER			0x34
+#define SOCFPGA_SYSMGR_USB0_L3_MASTER			0x38
+#define SOCFPGA_SYSMGR_USB1_L3_MASTER			0x3C
+#define SOCFPGA_SYSMGR_TSN_GLOBAL			0x40
+#define SOCFPGA_SYSMGR_EMAC_0				0x44 /* TSN_0 */
+#define SOCFPGA_SYSMGR_EMAC_1				0x48 /* TSN_1 */
+#define SOCFPGA_SYSMGR_EMAC_2				0x4C /* TSN_2 */
+#define SOCFPGA_SYSMGR_TSN_0_ACE			0x50
+#define SOCFPGA_SYSMGR_TSN_1_ACE			0x54
+#define SOCFPGA_SYSMGR_TSN_2_ACE			0x58
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_1			0x68
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2			0x6C
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3			0x70
+#define SOCFPGA_SYSMGR_DMAC0_L3_MASTER			0x74
+#define SOCFPGA_SYSMGR_ETR_L3_MASTER			0x78
+#define SOCFPGA_SYSMGR_DMAC1_L3_MASTER			0x7C
+#define SOCFPGA_SYSMGR_SEC_CTRL_SLT			0x80
+#define SOCFPGA_SYSMGR_OSC_TRIM				0x84
+#define SOCFPGA_SYSMGR_DMAC0_CTRL_STATUS_REG		0x88
+#define SOCFPGA_SYSMGR_DMAC1_CTRL_STATUS_REG		0x8C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_VALUE		0x90
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SET			0x94
+#define SOCFPGA_SYSMGR_ECC_INTMASK_CLR			0x98
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SERR			0x9C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_DERR			0xA0
+/* NOC configuration value for Agilex5 */
+#define SOCFPGA_SYSMGR_NOC_TIMEOUT			0xC0
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET			0xC4
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR			0xC8
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL			0xCC
+#define SOCFPGA_SYSMGR_NOC_IDLEACK			0xD0
+#define SOCFPGA_SYSMGR_NOC_IDLESTATUS			0xD4
+#define SOCFPGA_SYSMGR_FPGA2SOC_CTRL			0xD8
+#define SOCFPGA_SYSMGR_FPGA_CFG				0xDC
+#define SOCFPGA_SYSMGR_GPO				0xE4
+#define SOCFPGA_SYSMGR_GPI				0xE8
+#define SOCFPGA_SYSMGR_MPU				0xF0
+#define SOCFPGA_SYSMGR_SDM_HPS_SPARE			0xF4
+#define SOCFPGA_SYSMGR_HPS_SDM_SPARE			0xF8
+#define SOCFPGA_SYSMGR_DFI_INTF				0xFC
+#define SOCFPGA_SYSMGR_NAND_DD_CTRL			0x100
+#define SOCFPGA_SYSMGR_NAND_PHY_CTRL_REG		0x104
+#define SOCFPGA_SYSMGR_NAND_PHY_TSEL_REG		0x108
+#define SOCFPGA_SYSMGR_NAND_DQ_TIMING_REG		0x10C
+#define SOCFPGA_SYSMGR_PHY_DQS_TIMING_REG		0x110
+#define SOCFPGA_SYSMGR_NAND_PHY_GATE_LPBK_CTRL_REG	0x114
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_MASTER_CTRL_REG	0x118
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_SLAVE_CTRL_REG	0x11C
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG0	0x120
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG1	0x124
+#define SOCFPGA_SYSMGR_NAND_DD_STATUS_REG		0x128
+#define SOCFPGA_SYSMGR_NAND_DD_ID_LOW_REG		0x12C
+#define SOCFPGA_SYSMGR_NAND_DD_ID_HIGH_REG		0x130
+#define SOCFPGA_SYSMGR_NAND_WRITE_PROT_EN_REG		0x134
+#define SOCFPGA_SYSMGR_SDMMC_CMD_QUEUE_SETTING_REG	0x138
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_LOW			0x13C
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_HIGH			0x140
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_0			0x144
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_1			0x148
+#define SOCFPGA_SYSMGR_F2S_BRIDGE_CTRL			0x14C
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA0	0x150
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA1	0x154
+#define SOCFPGA_SYSMGR_SDM_TBU_STASH_CTRL_REG_1_SDM	0x158
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB2	0x15C
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB3	0x160
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_SDMMC	0x164
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_NAND	0x168
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_ETR	0x16C
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN0	0x170
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN1	0x174
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN2	0x178
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA0	0x17C
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA1	0x180
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_CTRL_REG_1_SDM	0x184
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB2	0x188
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB3	0x18C
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_SDMMC	0x190
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_NAND	0x194
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_ETR	0x198
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN0	0x19C
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN1	0x1A0
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN2	0x1A4
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA0	0x1A8
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA1	0x1AC
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_ID_AX_REG_1_SDM	0x1B0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB2	0x1B4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB3	0x1B8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_SDMMC	0x1BC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_NAND	0x1C0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_ETR	0x1C4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN0	0x1C8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN1	0x1CC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN2	0x1D0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG0		0x1F0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG1		0x1F4
+
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0		0x200
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1		0x204
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2		0x208
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_3		0x20C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_4		0x210
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_5		0x214
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_6		0x218
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_7		0x21C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
+#define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
+#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_3		0x23C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_4		0x240
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_5		0x244
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_6		0x248
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_7		0x24C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_8		0x250
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_9		0x254
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0		0x258
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_1		0x25C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_2		0x260
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_3		0x264
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_4		0x268
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_5		0x26C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_6		0x270
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_7		0x274
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8		0x278
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9		0x27C
+
+#define DMA0_STREAM_CTRL_REG				0x10D1217C
+#define DMA1_STREAM_CTRL_REG				0x10D12180
+#define SDM_STREAM_CTRL_REG				0x10D12184
+#define USB2_STREAM_CTRL_REG				0x10D12188
+#define USB3_STREAM_CTRL_REG				0x10D1218C
+#define SDMMC_STREAM_CTRL_REG				0x10D12190
+#define NAND_STREAM_CTRL_REG				0x10D12194
+#define ETR_STREAM_CTRL_REG				0x10D12198
+#define TSN0_STREAM_CTRL_REG				0x10D1219C
+#define TSN1_STREAM_CTRL_REG				0x10D121A0
+#define TSN2_STREAM_CTRL_REG				0x10D121A4
+
+/* Stream ID configuration value for Agilex5 */
+#define TSN0						0x00010001
+#define TSN1						0x00020002
+#define TSN2						0x00030003
+#define NAND						0x00040004
+#define SDMMC						0x00050005
+#define USB0						0x00060006
+#define USB1						0x00070007
+#define DMA0						0x00080008
+#define DMA1						0x00090009
+#define SDM						0x000A000A
+#define CORE_SIGHT_DEBUG				0x000B000B
+
+
+
+
+/* Field Masking */
+#define SYSMGR_SDMMC_DRVSEL(x)				(((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x)				(((x) & 0x7) << 4)
+#define IDLE_DATA_LWSOC2FPGA				BIT(4)
+#define IDLE_DATA_SOC2FPGA				BIT(0)
+#define IDLE_DATA_MASK					(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
+#define SYSMGR_ECC_OCRAM_MASK				BIT(1)
+#define SYSMGR_ECC_DDR0_MASK				BIT(16)
+#define SYSMGR_ECC_DDR1_MASK				BIT(17)
+#define WSTREAMIDEN_REG_CTRL				BIT(0)
+#define RSTREAMIDEN_REG_CTRL				BIT(1)
+#define WMMUSECSID_REG_VAL				BIT(4)
+#define RMMUSECSID_REG_VAL				BIT(5)
+
+/* Macros */
+#define SOCFPGA_SYSMGR(_reg)				(SOCFPGA_SYSMGR_REG_BASE \
+								+ (SOCFPGA_SYSMGR_##_reg))
+#define ENABLE_STREAMID					WSTREAMIDEN_REG_CTRL | \
+							RSTREAMIDEN_REG_CTRL
+#define ENABLE_STREAMID_SECURE_TX			WSTREAMIDEN_REG_CTRL | \
+							RSTREAMIDEN_REG_CTRL | \
+							WMMUSECSID_REG_VAL | RMMUSECSID_REG_VAL
+
+#endif /* N5X_SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 4c36f91..a06bbc4 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,16 +8,24 @@
 #ifndef PLAT_SOCFPGA_DEF_H
 #define PLAT_SOCFPGA_DEF_H
 
+#include "n5x_system_manager.h"
 #include <platform_def.h>
 
 /* Platform Setting */
-#define PLATFORM_MODEL				PLAT_SOCFPGA_N5X
-#define BOOT_SOURCE				BOOT_SOURCE_SDMMC
+#define PLATFORM_MODEL						PLAT_SOCFPGA_N5X
+#define BOOT_SOURCE							BOOT_SOURCE_SDMMC
+#define PLAT_PRIMARY_CPU					0
+#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT			MPIDR_AFF0_SHIFT
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE		0x2000000
 
+/* QSPI Setting */
+#define CAD_QSPIDATA_OFST			0xff900000
+#define CAD_QSPI_OFFSET				0xff8d2000
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		U(0xf7000000)
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
@@ -32,11 +40,67 @@
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE			U(0xffd21200)
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE			U(0xffd21300)
 
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define DRAM_BASE				(0x0)
+#define DRAM_SIZE				(0x80000000)
+
+#define OCRAM_BASE				(0xFFE00000)
+#define OCRAM_SIZE				(0x00040000)
+
+#define MEM64_BASE				(0x0100000000)
+#define MEM64_SIZE				(0x1F00000000)
+
+#define DEVICE1_BASE				(0x80000000)
+#define DEVICE1_SIZE				(0x60000000)
+
+#define DEVICE2_BASE				(0xF7000000)
+#define DEVICE2_SIZE				(0x08E00000)
+
+#define DEVICE3_BASE				(0xFFFC0000)
+#define DEVICE3_SIZE				(0x00008000)
+
+#define DEVICE4_BASE				(0x2000000000)
+#define DEVICE4_SIZE				(0x0100000000)
+
+#define BL2_BASE		(0xffe00000)
+#define BL2_LIMIT		(0xffe1b000)
+
+#define BL31_BASE		(0x1000)
+#define BL31_LIMIT		(0x81000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define PLAT_UART0_BASE		(0xFFC02000)
+#define PLAT_UART1_BASE		(0xFFC02100)
+
+/*******************************************************************************
+ * GIC related constants
+ ******************************************************************************/
+#define PLAT_GIC_BASE			(0xFFFC0000)
+#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
+#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
+#define PLAT_GICR_BASE			0
+
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
+#define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
+
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0xFFD12218
+
 /* Platform specific system counter */
-/*
- * In N5X the clk init is done in Uboot SPL.
- * BL31 shall bypass the clk init and only provides other APIs.
- */
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	(400)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
 
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 4f3da4e..7afeb74 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -36,6 +36,7 @@
 		lib/cpus/aarch64/cortex_a53.S				\
 		plat/common/plat_psci_common.c				\
 		plat/intel/soc/n5x/bl31_plat_setup.c			\
+		plat/intel/soc/n5x/soc/n5x_clock_manager.c		\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
 		plat/intel/soc/common/socfpga_sip_svc_v2.c		\
diff --git a/plat/intel/soc/n5x/soc/n5x_clock_manager.c b/plat/intel/soc/n5x/soc/n5x_clock_manager.c
new file mode 100644
index 0000000..f32e0f8
--- /dev/null
+++ b/plat/intel/soc/n5x/soc/n5x_clock_manager.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "n5x_clock_manager.h"
+#include "n5x_system_manager.h"
+
+
+
+uint64_t clk_get_pll_output_hz(void)
+{
+	uint32_t clksrc;
+	uint32_t scr_reg;
+	uint32_t divf;
+	uint32_t divr;
+	uint32_t divq;
+	uint32_t power = 1;
+	uint64_t clock = 0;
+
+	clksrc = ((get_clk_freq(CLKMGR_PERPLL_PLLGLOB)) &
+			CLKMGR_PLLGLOB_VCO_PSRC_MASK) >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET;
+
+	switch (clksrc) {
+	case CLKMGR_VCO_PSRC_EOSC1:
+		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
+		clock = mmio_read_32(scr_reg);
+		break;
+
+	case CLKMGR_VCO_PSRC_INTOSC:
+		clock = CLKMGR_INTOSC_HZ;
+		break;
+
+	case CLKMGR_VCO_PSRC_F2S:
+		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
+		clock = mmio_read_32(scr_reg);
+		break;
+	}
+
+	divf = ((get_clk_freq(CLKMGR_PERPLL_PLLDIV)) &
+			CLKMGR_PLLDIV_FDIV_MASK) >> CLKMGR_PLLDIV_FDIV_OFFSET;
+	divr = ((get_clk_freq(CLKMGR_PERPLL_PLLDIV)) &
+			CLKMGR_PLLDIV_REFCLKDIV_MASK) >> CLKMGR_PLLDIV_REFCLKDIV_OFFSET;
+	divq = ((get_clk_freq(CLKMGR_PERPLL_PLLDIV)) &
+			CLKMGR_PLLDIV_OUTDIV_QDIV_MASK) >> CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET;
+
+	while (divq) {
+		power *= 2;
+		divq--;
+	}
+
+	return ((clock * 2 * (divf + 1)) / ((divr + 1) * power));
+}
+
+uint64_t get_l4_clk(void)
+{
+	uint32_t clock = 0;
+	uint32_t mainpll_c1cnt;
+	uint32_t perpll_c1cnt;
+	uint32_t clksrc;
+
+	mainpll_c1cnt = ((get_clk_freq(CLKMGR_MAINPLL_PLLOUTDIV)) &
+			CLKMGR_PLLOUTDIV_C1CNT_MASK) >> CLKMGR_PLLOUTDIV_C1CNT_OFFSET;
+
+	perpll_c1cnt = ((get_clk_freq(CLKMGR_PERPLL_PLLOUTDIV)) &
+			CLKMGR_PLLOUTDIV_C1CNT_MASK) >> CLKMGR_PLLOUTDIV_C1CNT_OFFSET;
+
+	clksrc = ((get_clk_freq(CLKMGR_MAINPLL_NOCCLK)) & CLKMGR_CLKSRC_MASK) >>
+			CLKMGR_CLKSRC_OFFSET;
+
+	switch (clksrc) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = clk_get_pll_output_hz();
+		clock /= 1 + mainpll_c1cnt;
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		clock = clk_get_pll_output_hz();
+		clock /= 1 + perpll_c1cnt;
+		break;
+
+	default:
+		return 0;
+		break;
+	}
+
+	clock /= BIT(((get_clk_freq(CLKMGR_MAINPLL_NOCDIV)) >>
+			CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_NOCDIV_DIVIDER_MASK);
+
+	return clock;
+}
+
+/* Return MPU clock */
+uint32_t get_mpu_clk(void)
+{
+	uint32_t clock = 0;
+	uint32_t mainpll_c0cnt;
+	uint32_t perpll_c0cnt;
+	uint32_t clksrc;
+
+	mainpll_c0cnt = ((get_clk_freq(CLKMGR_MAINPLL_PLLOUTDIV)) &
+			CLKMGR_PLLOUTDIV_C0CNT_MASK) >> CLKMGR_PLLOUTDIV_C0CNT_OFFSET;
+
+	perpll_c0cnt = ((get_clk_freq(CLKMGR_PERPLL_PLLOUTDIV)) &
+			CLKMGR_PLLOUTDIV_C0CNT_MASK) >> CLKMGR_PLLOUTDIV_C0CNT_OFFSET;
+
+	clksrc = ((get_clk_freq(CLKMGR_MAINPLL_NOCCLK)) & CLKMGR_CLKSRC_MASK) >>
+			CLKMGR_CLKSRC_OFFSET;
+
+	switch (clksrc) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = clk_get_pll_output_hz();
+		clock /= 1 + mainpll_c0cnt;
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		clock = clk_get_pll_output_hz();
+		clock /= 1 + perpll_c0cnt;
+		break;
+
+	default:
+		return 0;
+		break;
+	}
+
+	clock /= BIT(((get_clk_freq(CLKMGR_MAINPLL_NOCDIV)) >>
+			CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_NOCDIV_DIVIDER_MASK);
+
+	return clock;
+}
+
+/* Calculate clock frequency based on parameter */
+uint32_t get_clk_freq(uint32_t psrc_reg)
+{
+	uint32_t clk_psrc;
+
+	clk_psrc = mmio_read_32(CLKMGR_N5X_BASE + psrc_reg);
+
+	return clk_psrc;
+}
+
+/* Get cpu freq clock */
+uint32_t get_cpu_clk(void)
+{
+	uint32_t cpu_clk = 0;
+
+	cpu_clk = get_mpu_clk()/PLAT_HZ_CONVERT_TO_MHZ;
+
+	return cpu_clk;
+}
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index be0fae5..ba00e82 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -147,7 +147,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h
index cf57df3..5f76375 100644
--- a/plat/intel/soc/stratix10/include/s10_clock_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef __CLOCKMANAGER_H__
 #define __CLOCKMANAGER_H__
 
+#include "s10_system_manager.h"
 #include "socfpga_handoff.h"
 
 #define ALT_CLKMGR				0xffd10000
@@ -95,5 +96,6 @@
 uint32_t get_mmc_clk(void);
 uint32_t get_l3_clk(uint32_t ref_clk);
 uint32_t get_ref_clk(uint32_t pllglob);
+uint32_t get_cpu_clk(void);
 
 #endif
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
new file mode 100644
index 0000000..88c0b46
--- /dev/null
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef S10_SOCFPGA_SYSTEMMANAGER_H
+#define S10_SOCFPGA_SYSTEMMANAGER_H
+
+#include "socfpga_plat_def.h"
+
+/* System Manager Register Map */
+#define SOCFPGA_SYSMGR_SILICONID_1			0x00
+#define SOCFPGA_SYSMGR_SILICONID_2			0x04
+#define SOCFPGA_SYSMGR_WDDBG				0x08
+#define SOCFPGA_SYSMGR_MPU_STATUS			0x10
+#define SOCFPGA_SYSMGR_SDMMC_L3_MASTER			0x2C
+#define SOCFPGA_SYSMGR_NAND_L3_MASTER			0x34
+#define SOCFPGA_SYSMGR_USB0_L3_MASTER			0x38
+#define SOCFPGA_SYSMGR_USB1_L3_MASTER			0x3C
+#define SOCFPGA_SYSMGR_TSN_GLOBAL			0x40
+#define SOCFPGA_SYSMGR_EMAC_0				0x44 /* TSN_0 */
+#define SOCFPGA_SYSMGR_EMAC_1				0x48 /* TSN_1 */
+#define SOCFPGA_SYSMGR_EMAC_2				0x4C /* TSN_2 */
+#define SOCFPGA_SYSMGR_TSN_0_ACE			0x50
+#define SOCFPGA_SYSMGR_TSN_1_ACE			0x54
+#define SOCFPGA_SYSMGR_TSN_2_ACE			0x58
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_1			0x68
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2			0x6C
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3			0x70
+#define SOCFPGA_SYSMGR_DMAC0_L3_MASTER			0x74
+#define SOCFPGA_SYSMGR_ETR_L3_MASTER			0x78
+#define SOCFPGA_SYSMGR_DMAC1_L3_MASTER			0x7C
+#define SOCFPGA_SYSMGR_SEC_CTRL_SLT			0x80
+#define SOCFPGA_SYSMGR_OSC_TRIM				0x84
+#define SOCFPGA_SYSMGR_DMAC0_CTRL_STATUS_REG		0x88
+#define SOCFPGA_SYSMGR_DMAC1_CTRL_STATUS_REG		0x8C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_VALUE		0x90
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SET			0x94
+#define SOCFPGA_SYSMGR_ECC_INTMASK_CLR			0x98
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SERR			0x9C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_DERR			0xA0
+/* NOC configuration value for Agilex5 */
+#define SOCFPGA_SYSMGR_NOC_TIMEOUT			0xC0
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET			0xC4
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR			0xC8
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL			0xCC
+#define SOCFPGA_SYSMGR_NOC_IDLEACK			0xD0
+#define SOCFPGA_SYSMGR_NOC_IDLESTATUS			0xD4
+#define SOCFPGA_SYSMGR_FPGA2SOC_CTRL			0xD8
+#define SOCFPGA_SYSMGR_FPGA_CFG				0xDC
+#define SOCFPGA_SYSMGR_GPO				0xE4
+#define SOCFPGA_SYSMGR_GPI				0xE8
+#define SOCFPGA_SYSMGR_MPU				0xF0
+#define SOCFPGA_SYSMGR_SDM_HPS_SPARE			0xF4
+#define SOCFPGA_SYSMGR_HPS_SDM_SPARE			0xF8
+#define SOCFPGA_SYSMGR_DFI_INTF				0xFC
+#define SOCFPGA_SYSMGR_NAND_DD_CTRL			0x100
+#define SOCFPGA_SYSMGR_NAND_PHY_CTRL_REG		0x104
+#define SOCFPGA_SYSMGR_NAND_PHY_TSEL_REG		0x108
+#define SOCFPGA_SYSMGR_NAND_DQ_TIMING_REG		0x10C
+#define SOCFPGA_SYSMGR_PHY_DQS_TIMING_REG		0x110
+#define SOCFPGA_SYSMGR_NAND_PHY_GATE_LPBK_CTRL_REG	0x114
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_MASTER_CTRL_REG	0x118
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_SLAVE_CTRL_REG	0x11C
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG0	0x120
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG1	0x124
+#define SOCFPGA_SYSMGR_NAND_DD_STATUS_REG		0x128
+#define SOCFPGA_SYSMGR_NAND_DD_ID_LOW_REG		0x12C
+#define SOCFPGA_SYSMGR_NAND_DD_ID_HIGH_REG		0x130
+#define SOCFPGA_SYSMGR_NAND_WRITE_PROT_EN_REG		0x134
+#define SOCFPGA_SYSMGR_SDMMC_CMD_QUEUE_SETTING_REG	0x138
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_LOW			0x13C
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_HIGH			0x140
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_0			0x144
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_1			0x148
+#define SOCFPGA_SYSMGR_F2S_BRIDGE_CTRL			0x14C
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA0	0x150
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA1	0x154
+#define SOCFPGA_SYSMGR_SDM_TBU_STASH_CTRL_REG_1_SDM	0x158
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB2	0x15C
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB3	0x160
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_SDMMC	0x164
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_NAND	0x168
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_ETR	0x16C
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN0	0x170
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN1	0x174
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN2	0x178
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA0	0x17C
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA1	0x180
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_CTRL_REG_1_SDM	0x184
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB2	0x188
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB3	0x18C
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_SDMMC	0x190
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_NAND	0x194
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_ETR	0x198
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN0	0x19C
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN1	0x1A0
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN2	0x1A4
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA0	0x1A8
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA1	0x1AC
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_ID_AX_REG_1_SDM	0x1B0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB2	0x1B4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB3	0x1B8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_SDMMC	0x1BC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_NAND	0x1C0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_ETR	0x1C4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN0	0x1C8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN1	0x1CC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN2	0x1D0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG0		0x1F0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG1		0x1F4
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0		0x200
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1		0x204
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2		0x208
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_3		0x20C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_4		0x210
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_5		0x214
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_6		0x218
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_7		0x21C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
+#define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
+#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_3		0x23C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_4		0x240
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_5		0x244
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_6		0x248
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_7		0x24C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_8		0x250
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_9		0x254
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0		0x258
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_1		0x25C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_2		0x260
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_3		0x264
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_4		0x268
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_5		0x26C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_6		0x270
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_7		0x274
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8		0x278
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9		0x27C
+
+#define DMA0_STREAM_CTRL_REG				0x10D1217C
+#define DMA1_STREAM_CTRL_REG				0x10D12180
+#define SDM_STREAM_CTRL_REG				0x10D12184
+#define USB2_STREAM_CTRL_REG				0x10D12188
+#define USB3_STREAM_CTRL_REG				0x10D1218C
+#define SDMMC_STREAM_CTRL_REG				0x10D12190
+#define NAND_STREAM_CTRL_REG				0x10D12194
+#define ETR_STREAM_CTRL_REG				0x10D12198
+#define TSN0_STREAM_CTRL_REG				0x10D1219C
+#define TSN1_STREAM_CTRL_REG				0x10D121A0
+#define TSN2_STREAM_CTRL_REG				0x10D121A4
+
+/* Stream ID configuration value for Agilex5 */
+#define TSN0						0x00010001
+#define TSN1						0x00020002
+#define TSN2						0x00030003
+#define NAND						0x00040004
+#define SDMMC						0x00050005
+#define USB0						0x00060006
+#define USB1						0x00070007
+#define DMA0						0x00080008
+#define DMA1						0x00090009
+#define SDM						0x000A000A
+#define CORE_SIGHT_DEBUG				0x000B000B
+
+/* Field Masking */
+#define SYSMGR_SDMMC_DRVSEL(x)				(((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x)				(((x) & 0x7) << 4)
+#define IDLE_DATA_LWSOC2FPGA				BIT(4)
+#define IDLE_DATA_SOC2FPGA				BIT(0)
+#define IDLE_DATA_MASK					(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
+#define SYSMGR_ECC_OCRAM_MASK				BIT(1)
+#define SYSMGR_ECC_DDR0_MASK				BIT(16)
+#define SYSMGR_ECC_DDR1_MASK				BIT(17)
+#define WSTREAMIDEN_REG_CTRL				BIT(0)
+#define RSTREAMIDEN_REG_CTRL				BIT(1)
+#define WMMUSECSID_REG_VAL				BIT(4)
+#define RMMUSECSID_REG_VAL				BIT(5)
+
+/* Macros */
+
+#define SOCFPGA_SYSMGR(_reg)				(SOCFPGA_SYSMGR_REG_BASE \
+								+ (SOCFPGA_SYSMGR_##_reg))
+#define ENABLE_STREAMID					WSTREAMIDEN_REG_CTRL | \
+							RSTREAMIDEN_REG_CTRL
+#define ENABLE_STREAMID_SECURE_TX			WSTREAMIDEN_REG_CTRL | \
+							RSTREAMIDEN_REG_CTRL | \
+							WMMUSECSID_REG_VAL | RMMUSECSID_REG_VAL
+
+#endif /* S10_SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 516cc75..7c9f15a 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,15 +8,23 @@
 #define PLAT_SOCFPGA_DEF_H
 
 #include <platform_def.h>
+#include "s10_system_manager.h"
 
 /* Platform Setting */
-#define PLATFORM_MODEL				PLAT_SOCFPGA_STRATIX10
-#define BOOT_SOURCE				BOOT_SOURCE_SDMMC
+#define PLATFORM_MODEL						PLAT_SOCFPGA_STRATIX10
+#define BOOT_SOURCE							BOOT_SOURCE_SDMMC
+#define PLAT_PRIMARY_CPU					0
+#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT			MPIDR_AFF0_SHIFT
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE		0x1000000
 
+/* QSPI Setting */
+#define CAD_QSPIDATA_OFST			0xff900000
+#define CAD_QSPI_OFFSET				0xff8d2000
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
@@ -31,10 +39,67 @@
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE		0xffd21200
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE		0xffd21300
 
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define DRAM_BASE				(0x0)
+#define DRAM_SIZE				(0x80000000)
+
+#define OCRAM_BASE				(0xFFE00000)
+#define OCRAM_SIZE				(0x00040000)
+
+#define MEM64_BASE				(0x0100000000)
+#define MEM64_SIZE				(0x1F00000000)
+
+#define DEVICE1_BASE				(0x80000000)
+#define DEVICE1_SIZE				(0x60000000)
+
+#define DEVICE2_BASE				(0xF7000000)
+#define DEVICE2_SIZE				(0x08E00000)
+
+#define DEVICE3_BASE				(0xFFFC0000)
+#define DEVICE3_SIZE				(0x00008000)
+
+#define DEVICE4_BASE				(0x2000000000)
+#define DEVICE4_SIZE				(0x0100000000)
+
+#define BL2_BASE		(0xffe00000)
+#define BL2_LIMIT		(0xffe1b000)
+
+#define BL31_BASE		(0x1000)
+#define BL31_LIMIT		(0x81000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define PLAT_UART0_BASE		(0xFFC02000)
+#define PLAT_UART1_BASE		(0xFFC02100)
+
+/*******************************************************************************
+ * GIC related constants
+ ******************************************************************************/
+#define PLAT_GIC_BASE			(0xFFFC0000)
+#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
+#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
+#define PLAT_GICR_BASE			0
+
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
+#define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
+
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0xFFD12218
+
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
 
-uint32_t get_cpu_clk(void);
-
 #endif /* PLATSOCFPGA_DEF_H */
 
diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
index 30009f7..416d359 100644
--- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
@@ -316,7 +316,7 @@
 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
 	ref_clk = get_ref_clk(data32);
 
-	cpu_clk = get_l3_clk(ref_clk)/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+	cpu_clk = get_l3_clk(ref_clk)/PLAT_HZ_CONVERT_TO_MHZ;
 
 	return cpu_clk;
 }
diff --git a/plat/marvell/armada/a8k/common/plat_pm.c b/plat/marvell/armada/a8k/common/plat_pm.c
index 9ea9276..f08f08a 100644
--- a/plat/marvell/armada/a8k/common/plat_pm.c
+++ b/plat/marvell/armada/a8k/common/plat_pm.c
@@ -423,7 +423,7 @@
 	} else
 #endif
 	{
-		/* proprietary CPU ON exection flow */
+		/* proprietary CPU ON execution flow */
 		plat_marvell_cpu_on(mpidr);
 	}
 	return 0;
diff --git a/plat/marvell/armada/common/marvell_ddr_info.c b/plat/marvell/armada/common/marvell_ddr_info.c
index 7340996..1ae0254 100644
--- a/plat/marvell/armada/common/marvell_ddr_info.c
+++ b/plat/marvell/armada/common/marvell_ddr_info.c
@@ -34,7 +34,7 @@
 	DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS
 
 /* Mapping between DDR area length and real DDR size is specific and looks like
- * bellow:
+ * below:
  * 0 => 384 MB
  * 1 => 768 MB
  * 2 => 1536 MB
diff --git a/plat/mediatek/common/common_config.mk b/plat/mediatek/common/common_config.mk
index 851eb2c..31a61e0 100644
--- a/plat/mediatek/common/common_config.mk
+++ b/plat/mediatek/common/common_config.mk
@@ -19,7 +19,7 @@
 ENABLE_STACK_PROTECTOR := strong
 # AMU, Kernel will access amuserenr_el0 if PE supported
 # Firmware _must_ implement AMU support
-ENABLE_AMU := 1
+ENABLE_FEAT_AMU := 2
 VENDOR_EXTEND_PUBEVENT_ENABLE := 1
 
 # MTK define options
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index a8a5a48..5a3ad1f 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,6 +76,7 @@
 
 MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
 MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
+MTK_SIP_SMC_FROM_S_EL1_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
 
 IMPORT_SYM(uintptr_t, __MTK_SMC_POOL_START__, MTK_SMC_POOL_START);
 IMPORT_SYM(uintptr_t, __MTK_SMC_POOL_END_UNALIGNED__, MTK_SMC_POOL_END_UNALIGNED);
@@ -134,6 +135,28 @@
 }
 MTK_EARLY_PLAT_INIT(mtk_smc_handler_init);
 
+/* This function handles Mediatek defined SiP Calls from Secure world */
+static u_register_t mtk_smc_handler_sel1(uint32_t smc_id,
+					 u_register_t x1,
+					 u_register_t x2,
+					 u_register_t x3,
+					 u_register_t x4,
+					 void *cookie,
+					 void *handle,
+					 u_register_t flags)
+{
+	u_register_t ret = MTK_SIP_E_SUCCESS;
+	struct smccc_res smc_ret = {0};
+
+	switch (smc_id) {
+		MTK_SIP_SMC_FROM_S_EL1_TABLE(SMC_ID_EXPAND_AS_SMC_OPERATION);
+	default:
+		INFO("SEL1 SMC ID:0x%x not support\n", smc_id);
+		ret = SMC_UNK;
+	}
+	SMC_RET4(handle, ret, smc_ret.a1, smc_ret.a2, smc_ret.a3);
+}
+
 /* This function handles Mediatek defined SiP Calls from Bootloader */
 static uintptr_t mtk_smc_handler_bl33(uint32_t smc_id,
 				      u_register_t x1,
@@ -209,8 +232,8 @@
 
 	if (!ns) {
 		/* SiP SMC service secure world's call */
-		INFO("Secure SMC ID:0x%x not supported\n", smc_id);
-		SMC_RET1(handle, ret);
+		return mtk_smc_handler_sel1(smc_num, x1, x2, x3, x4,
+					    cookie, handle, flags);
 	}
 	if (is_from_bl33(smc_ori)) {
 		/* SiP SMC service secure bootloader's call */
diff --git a/plat/mediatek/drivers/apusys/apusys.c b/plat/mediatek/drivers/apusys/apusys.c
new file mode 100644
index 0000000..dfe1dcf
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TF-A system header */
+#include <common/debug.h>
+
+/* 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>
+
+static u_register_t apusys_kernel_handler(u_register_t x1,
+					  u_register_t x2,
+					  u_register_t x3,
+					  u_register_t x4,
+					  void *handle,
+					  struct smccc_res *smccc_ret)
+{
+	uint32_t request_ops;
+	int32_t ret = -1;
+
+	request_ops = (uint32_t)x1;
+
+	switch (request_ops) {
+	case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON:
+		ret = apusys_kernel_apusys_pwr_top_on();
+		break;
+	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;
+	}
+
+	return ret;
+}
+DECLARE_SMC_HANDLER(MTK_SIP_APUSYS_CONTROL, apusys_kernel_handler);
+
+int apusys_init(void)
+{
+	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
new file mode 100644
index 0000000..ed4e195
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_H
+#define APUSYS_H
+
+#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_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,
+};
+
+#endif
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
new file mode 100644
index 0000000..cdfc133
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+
+/* TF-A system header */
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/* Vendor header */
+#include "apusys.h"
+#include "apusys_power.h"
+#include "apusys_rv.h"
+#include <mtk_mmap_pool.h>
+
+static spinlock_t apu_lock;
+static bool apusys_top_on;
+
+static int apu_poll(uintptr_t reg, uint32_t mask, uint32_t value, uint32_t timeout_us)
+{
+	uint32_t reg_val, count;
+
+	count = timeout_us / APU_POLL_STEP_US;
+	if (count == 0) {
+		count = 1;
+	}
+
+	do {
+		reg_val = mmio_read_32(reg);
+		if ((reg_val & mask) == value) {
+			return 0;
+		}
+
+		udelay(APU_POLL_STEP_US);
+	} while (--count);
+
+	ERROR(MODULE_TAG "Timeout polling APU register %#" PRIxPTR "\n", reg);
+	ERROR(MODULE_TAG "Read value 0x%x, expected 0x%x\n", reg_val,
+	      (value == 0U) ? (reg_val & ~mask) : (reg_val | mask));
+
+	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) {
+	case D4_SLV_OFF:
+		mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI21_CTRL_0,
+				INFRA_FMEM_BUS_u_SI21_CTRL_EN);
+		mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI22_CTRL_0,
+				INFRA_FMEM_BUS_u_SI22_CTRL_EN);
+		mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI11_CTRL_0,
+				INFRA_FMEM_BUS_u_SI11_CTRL_EN);
+		mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0,
+				INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN);
+		break;
+	case D4_SLV_ON:
+		mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI21_CTRL_0,
+				INFRA_FMEM_BUS_u_SI21_CTRL_EN);
+		mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI22_CTRL_0,
+				INFRA_FMEM_BUS_u_SI22_CTRL_EN);
+		mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI11_CTRL_0,
+				INFRA_FMEM_BUS_u_SI11_CTRL_EN);
+		mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0,
+				INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN);
+		break;
+	default:
+		ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, en);
+		break;
+	}
+}
+
+static void apu_pwr_flow_remote_sync(uint32_t cfg)
+{
+	mmio_write_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG, (cfg & 0x1));
+}
+
+int apusys_kernel_apusys_pwr_top_on(void)
+{
+	int ret;
+
+	spin_lock(&apu_lock);
+
+	if (apusys_top_on == true) {
+		INFO(MODULE_TAG "%s: APUSYS already powered on!\n", __func__);
+		spin_unlock(&apu_lock);
+		return 0;
+	}
+
+	apu_pwr_flow_remote_sync(1);
+
+	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL_1, AFC_ENA);
+
+	mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_SET);
+
+	ret = apu_poll(APU_RPC_BASE + APU_RPC_INTF_PWR_RDY,
+		       PWR_RDY, PWR_RDY, APU_TOP_ON_POLLING_TIMEOUT_US);
+	if (ret != 0) {
+		ERROR(MODULE_TAG "%s polling RPC RDY timeout, ret %d\n", __func__, ret);
+		spin_unlock(&apu_lock);
+		return ret;
+	}
+
+	ret = apu_poll(APU_RPC_BASE + APU_RPC_STATUS,
+		       RPC_STATUS_RDY, RPC_STATUS_RDY, APU_TOP_ON_POLLING_TIMEOUT_US);
+	if (ret != 0) {
+		ERROR(MODULE_TAG "%s polling ARE FSM timeout, ret %d\n", __func__, ret);
+		spin_unlock(&apu_lock);
+		return ret;
+	}
+
+	mmio_write_32(APU_VCORE_BASE + APUSYS_VCORE_CG_CLR, CG_CLR);
+	mmio_write_32(APU_RCX_BASE + APU_RCX_CG_CLR, CG_CLR);
+
+	apu_xpu2apusys_d4_slv_en(D4_SLV_OFF);
+
+	apu_backup_restore(APU_CTRL_RESTORE);
+
+	apusys_top_on = true;
+
+	spin_unlock(&apu_lock);
+	return ret;
+}
+
+static void apu_sleep_rpc_rcx(void)
+{
+	mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_CLR);
+	udelay(10);
+
+	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, (RPC_CTRL | RSV10));
+	udelay(10);
+
+	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, CLR_IRQ);
+	udelay(10);
+
+	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, SLEEP_REQ);
+	udelay(100);
+}
+
+int apusys_kernel_apusys_pwr_top_off(void)
+{
+	int ret;
+
+	spin_lock(&apu_lock);
+
+	if (apusys_top_on == false) {
+		INFO(MODULE_TAG "%s: APUSYS already powered off!\n", __func__);
+		spin_unlock(&apu_lock);
+		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) {
+		apu_pwr_flow_remote_sync(1);
+	} else {
+		apu_sleep_rpc_rcx();
+	}
+
+	ret = apu_poll(APU_RPC_BASE + APU_RPC_INTF_PWR_RDY,
+		       PWR_RDY, PWR_OFF, APU_TOP_OFF_POLLING_TIMEOUT_US);
+	if (ret != 0) {
+		ERROR(MODULE_TAG "%s timeout to wait RPC sleep (val:%d), ret %d\n",
+		      __func__, APU_TOP_OFF_POLLING_TIMEOUT_US, ret);
+		spin_unlock(&apu_lock);
+		return ret;
+	}
+
+	apusys_top_on = false;
+
+	spin_unlock(&apu_lock);
+	return ret;
+}
+
+static void get_pll_pcw(const uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
+{
+	unsigned int fvco = clk_rate;
+	unsigned int pcw_val;
+	unsigned int postdiv_val = 1;
+	unsigned int postdiv_reg = 0;
+
+	while (fvco <= OUT_CLK_FREQ_MIN) {
+		postdiv_val = postdiv_val << 1;
+		postdiv_reg = postdiv_reg + 1;
+		fvco = fvco << 1;
+	}
+
+	pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ;
+
+	if (postdiv_reg == 0) {
+		pcw_val = pcw_val * 2;
+		postdiv_val = postdiv_val << 1;
+		postdiv_reg = postdiv_reg + 1;
+	}
+
+	*r1 = postdiv_reg;
+	*r2 = pcw_val;
+}
+
+static void apu_pll_init(void)
+{
+	const uint32_t pll_hfctl_cfg[PLL_NUM] = {
+		PLL4HPLL_FHCTL0_CFG,
+		PLL4HPLL_FHCTL1_CFG,
+		PLL4HPLL_FHCTL2_CFG,
+		PLL4HPLL_FHCTL3_CFG
+	};
+	const uint32_t pll_con1[PLL_NUM] = {
+		PLL4H_PLL1_CON1,
+		PLL4H_PLL2_CON1,
+		PLL4H_PLL3_CON1,
+		PLL4H_PLL4_CON1
+	};
+	const uint32_t pll_fhctl_dds[PLL_NUM] = {
+		PLL4HPLL_FHCTL0_DDS,
+		PLL4HPLL_FHCTL1_DDS,
+		PLL4HPLL_FHCTL2_DDS,
+		PLL4HPLL_FHCTL3_DDS
+	};
+	const uint32_t pll_freq_out[PLL_NUM] = {
+		APUPLL0_DEFAULT_FREQ,
+		APUPLL1_DEFAULT_FREQ,
+		APUPLL2_DEFAULT_FREQ,
+		APUPLL3_DEFAULT_FREQ
+	};
+	uint32_t pcw_val, posdiv_val;
+	int pll_idx;
+
+	mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_RST_CON, PLL4H_PLL_HP_SWRSTB);
+	mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_HP_EN, PLL4H_PLL_HP_EN);
+	mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_CLK_CON, PLL4H_PLL_HP_CLKEN);
+
+	for (pll_idx = 0; pll_idx < PLL_NUM; pll_idx++) {
+		mmio_setbits_32(APU_PLL_BASE + pll_hfctl_cfg[pll_idx], (FHCTL0_EN | SFSTR0_EN));
+
+		posdiv_val = 0;
+		pcw_val = 0;
+		get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val);
+
+		mmio_clrsetbits_32(APU_PLL_BASE + pll_con1[pll_idx],
+				   (RG_PLL_POSDIV_MASK << RG_PLL_POSDIV_SFT),
+				   (posdiv_val << RG_PLL_POSDIV_SFT));
+		mmio_write_32(APU_PLL_BASE + pll_fhctl_dds[pll_idx],
+			      (FHCTL_PLL_TGL_ORG | pcw_val));
+	}
+}
+
+static void apu_acc_init(void)
+{
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR0, CGEN_SOC);
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET0, HW_CTRL_EN);
+
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR1, CGEN_SOC);
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET1, HW_CTRL_EN);
+
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR2, CGEN_SOC);
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET2, HW_CTRL_EN);
+	mmio_write_32(APU_ACC_BASE + APU_ACC_AUTO_CTRL_SET2, CLK_REQ_SW_EN);
+
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR3, CGEN_SOC);
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET3, HW_CTRL_EN);
+	mmio_write_32(APU_ACC_BASE + APU_ACC_AUTO_CTRL_SET3, CLK_REQ_SW_EN);
+
+	mmio_write_32(APU_ACC_BASE + APU_ACC_CLK_INV_EN_SET, CLK_INV_EN);
+}
+
+static void apu_buck_off_cfg(void)
+{
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_SET);
+	udelay(10);
+
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_SET);
+	udelay(10);
+
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR);
+	udelay(10);
+}
+
+static void apu_pcu_init(void)
+{
+	uint32_t vapu_en_offset = BUCK_VAPU_PMIC_REG_EN_ADDR;
+	uint32_t vapu_sram_en_offset = BUCK_VAPU_SRAM_PMIC_REG_EN_ADDR;
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_CTRL_SET, AUTO_BUCK_EN);
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_STEP_SEL, BUCK_ON_OFF_CMD_EN);
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT0_L,
+		      ((vapu_sram_en_offset << BUCK_OFFSET_SFT) + BUCK_ON_CMD));
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT0_H, CMD_OP);
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT1_L,
+		      ((vapu_en_offset << BUCK_OFFSET_SFT) + BUCK_ON_CMD));
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT1_H, CMD_OP);
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT0_L,
+		      ((vapu_en_offset << BUCK_OFFSET_SFT) + BUCK_OFF_CMD));
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT0_H, CMD_OP);
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT1_L,
+		      ((vapu_sram_en_offset << BUCK_OFFSET_SFT) + BUCK_OFF_CMD));
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT1_H, CMD_OP);
+
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_SLE0, APU_PCU_BUCK_ON_SETTLE_TIME);
+	mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_SLE1, APU_PCU_BUCK_ON_SETTLE_TIME);
+}
+
+static void apu_rpclite_init(void)
+{
+	const uint32_t sleep_type_offset[] = {
+		APU_RPC_SW_TYPE2,
+		APU_RPC_SW_TYPE3,
+		APU_RPC_SW_TYPE4,
+		APU_RPC_SW_TYPE5,
+		APU_RPC_SW_TYPE6,
+		APU_RPC_SW_TYPE7,
+		APU_RPC_SW_TYPE8,
+		APU_RPC_SW_TYPE9
+	};
+	int ofs_arr_size = ARRAY_SIZE(sleep_type_offset);
+	int ofs_idx;
+
+	for (ofs_idx = 0 ; ofs_idx < ofs_arr_size ; ofs_idx++) {
+		mmio_clrbits_32(APU_ACX0_RPC_LITE_BASE + sleep_type_offset[ofs_idx],
+				SW_TYPE);
+	}
+
+	mmio_setbits_32(APU_ACX0_RPC_LITE_BASE + APU_RPC_TOP_SEL, RPC_CTRL);
+}
+
+static void apu_rpc_init(void)
+{
+	mmio_clrbits_32(APU_RPC_BASE + APU_RPC_SW_TYPE0, SW_TYPE);
+	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, RPC_TOP_CTRL);
+	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL_1, RPC_TOP_CTRL1);
+}
+
+static int apu_are_init(void)
+{
+	int ret;
+	int are_id = 0;
+	const uint32_t are_base[APU_ARE_NUM] = { APU_ARE0_BASE, APU_ARE1_BASE, APU_ARE2_BASE };
+	const uint32_t are_entry2_cfg_l[APU_ARE_NUM] = {
+		ARE0_ENTRY2_CFG_L,
+		ARE1_ENTRY2_CFG_L,
+		ARE2_ENTRY2_CFG_L
+	};
+
+	mmio_setbits_32(APU_AO_CTL_BASE + CSR_DUMMY_0_ADDR, VCORE_ARE_REQ);
+
+	ret = apu_poll(APU_ARE2_BASE + APU_ARE_GLO_FSM, ARE_GLO_FSM_IDLE, ARE_GLO_FSM_IDLE,
+		       APU_ARE_POLLING_TIMEOUT_US);
+	if (ret != 0) {
+		ERROR(MODULE_TAG "[%s][%d] ARE init timeout\n",
+		      __func__, __LINE__);
+		return ret;
+	}
+
+	for (are_id = APU_ARE0; are_id < APU_ARE_NUM; are_id++) {
+		mmio_write_32(are_base[are_id] + APU_ARE_ENTRY0_SRAM_H, ARE_ENTRY0_SRAM_H_INIT);
+		mmio_write_32(are_base[are_id] + APU_ARE_ENTRY0_SRAM_L, ARE_ENTRY0_SRAM_L_INIT);
+
+		mmio_write_32(are_base[are_id] + APU_ARE_ENTRY1_SRAM_H, ARE_ENTRY1_SRAM_H_INIT);
+		mmio_write_32(are_base[are_id] + APU_ARE_ENTRY1_SRAM_L, ARE_ENTRY1_SRAM_L_INIT);
+
+		mmio_write_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_H, ARE_ENTRY_CFG_H);
+		mmio_write_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_L, are_entry2_cfg_l[are_id]);
+
+		mmio_read_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_H);
+		mmio_read_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_L);
+
+		mmio_write_32(are_base[are_id] + APU_ARE_INI_CTRL, ARE_CONFG_INI);
+	}
+
+	return ret;
+}
+
+static void apu_aoc_init(void)
+{
+	mmio_clrbits_32(SPM_BASE + APUSYS_BUCK_ISOLATION, IPU_EXT_BUCK_ISO);
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_CLR);
+	udelay(10);
+
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_SET);
+	udelay(10);
+
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_CLR);
+	udelay(10);
+
+	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, SRAM_AOC_ISO_CLR);
+	udelay(10);
+}
+
+static int init_hw_setting(void)
+{
+	int ret;
+
+	apu_aoc_init();
+	apu_pcu_init();
+	apu_rpc_init();
+	apu_rpclite_init();
+
+	ret = apu_are_init();
+	if (ret != 0) {
+		return ret;
+	}
+
+	apu_pll_init();
+	apu_acc_init();
+	apu_buck_off_cfg();
+
+	return ret;
+}
+
+int apusys_power_init(void)
+{
+	int ret;
+
+	ret = init_hw_setting();
+	if (ret != 0) {
+		ERROR(MODULE_TAG "%s initial fail\n", __func__);
+	} else {
+		INFO(MODULE_TAG "%s initial done\n", __func__);
+	}
+
+	return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
new file mode 100644
index 0000000..460cc50
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_POWER_H
+#define APUSYS_POWER_H
+
+#include <platform_def.h>
+
+enum APU_CLKSRC_ID {
+	PLL_CONN = 0, /* MNOC */
+	PLL_UP,
+	PLL_VPU,
+	PLL_DLA,
+	PLL_NUM,
+};
+
+enum APU_ARE_ID {
+	APU_ARE0 = 0,
+	APU_ARE1,
+	APU_ARE2,
+	APU_ARE_NUM,
+};
+
+enum APU_D4_SLV_CTRL {
+	D4_SLV_OFF = 0,
+	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)
+#define BASIC_CLK_FREQ				(26)
+#define DDS_SHIFT				(14)
+
+#define APUPLL0_DEFAULT_FREQ			(900)
+#define APUPLL1_DEFAULT_FREQ			(832)
+#define APUPLL2_DEFAULT_FREQ			(700)
+#define APUPLL3_DEFAULT_FREQ			(700)
+
+#define APU_TOP_ON_POLLING_TIMEOUT_US		(10000)
+#define APU_TOP_OFF_POLLING_TIMEOUT_US		(5 * APU_TOP_ON_POLLING_TIMEOUT_US)
+#define APU_ARE_POLLING_TIMEOUT_US		(10000)
+
+/* APU related reg */
+#define APU_VCORE_BASE				(APU_RCX_VCORE_CONFIG)
+#define APU_RCX_BASE				(APU_RCX_CONFIG)
+#define APU_RPC_BASE				(APU_RPCTOP)
+#define APU_PCU_BASE				(APU_PCUTOP)
+#define APU_ARE0_BASE				(APU_ARETOP_ARE0)
+#define APU_ARE1_BASE				(APU_ARETOP_ARE1)
+#define APU_ARE2_BASE				(APU_ARETOP_ARE2)
+#define APU_MBOX0_BASE				(APU_MBOX0)
+#define APU_AO_CTL_BASE				(APU_AO_CTRL)
+#define APU_PLL_BASE				(APU_PLL)
+#define APU_ACC_BASE				(APU_ACC)
+#define APU_ACX0_RPC_LITE_BASE			(APU_ACX0_RPC_LITE)
+
+/* RPC offset define */
+#define APU_RPC_TOP_CON				(0x0000)
+#define APU_RPC_TOP_SEL				(0x0004)
+#define APU_RPC_STATUS				(0x0014)
+#define APU_RPC_TOP_SEL_1			(0x0018)
+#define APU_RPC_HW_CON				(0x001c)
+#define APU_RPC_INTF_PWR_RDY			(0x0044)
+#define APU_RPC_SW_TYPE0			(0x0200)
+
+/* RPC control */
+#define SRAM_AOC_ISO_CLR			BIT(7)
+#define BUCK_ELS_EN_SET				BIT(10)
+#define BUCK_ELS_EN_CLR				BIT(11)
+#define BUCK_AO_RST_B_SET			BIT(12)
+#define BUCK_AO_RST_B_CLR			BIT(13)
+#define BUCK_PROT_REQ_SET			BIT(14)
+#define BUCK_PROT_REQ_CLR			BIT(15)
+#define SW_TYPE					BIT(1)
+#define RPC_CTRL				(0x0000009e)
+#define RPC_TOP_CTRL				(0x0800501e)
+#define RPC_TOP_CTRL1				BIT(20)
+#define AFC_ENA					BIT(16)
+#define REG_WAKEUP_SET				BIT(8)
+#define REG_WAKEUP_CLR				BIT(12)
+#define PWR_RDY					BIT(0)
+#define PWR_OFF					(0)
+#define RPC_STATUS_RDY				BIT(29)
+#define RSV10					BIT(10)
+#define CLR_IRQ					(0x6)
+#define SLEEP_REQ				BIT(0)
+
+/* PLL offset define */
+#define PLL4H_PLL1_CON1				(0x000c)
+#define PLL4H_PLL2_CON1				(0x001c)
+#define PLL4H_PLL3_CON1				(0x002c)
+#define PLL4H_PLL4_CON1				(0x003c)
+#define PLL4HPLL_FHCTL_HP_EN			(0x0e00)
+#define PLL4HPLL_FHCTL_CLK_CON			(0x0e08)
+#define PLL4HPLL_FHCTL_RST_CON			(0x0e0c)
+#define PLL4HPLL_FHCTL0_CFG			(0x0e3c)
+#define PLL4HPLL_FHCTL0_DDS			(0x0e44)
+#define PLL4HPLL_FHCTL1_CFG			(0x0e50)
+#define PLL4HPLL_FHCTL1_DDS			(0x0e58)
+#define PLL4HPLL_FHCTL2_CFG			(0x0e64)
+#define PLL4HPLL_FHCTL2_DDS			(0x0e6c)
+#define PLL4HPLL_FHCTL3_CFG			(0x0e78)
+#define PLL4HPLL_FHCTL3_DDS			(0x0e80)
+
+/* PLL control */
+#define PLL4H_PLL_HP_EN				(0xf)
+#define PLL4H_PLL_HP_CLKEN			(0xf)
+#define PLL4H_PLL_HP_SWRSTB			(0xf)
+#define FHCTL0_EN				BIT(0)
+#define	SFSTR0_EN				BIT(2)
+#define RG_PLL_POSDIV_MASK			(0x7)
+#define RG_PLL_POSDIV_SFT			(24)
+#define FHCTL_PLL_TGL_ORG			BIT(31)
+
+/* ACC offset define */
+#define APU_ACC_CONFG_SET0			(0x0000)
+#define APU_ACC_CONFG_SET1			(0x0004)
+#define APU_ACC_CONFG_SET2			(0x0008)
+#define APU_ACC_CONFG_SET3			(0x000c)
+#define APU_ACC_CONFG_CLR0			(0x0040)
+#define APU_ACC_CONFG_CLR1			(0x0044)
+#define APU_ACC_CONFG_CLR2			(0x0048)
+#define APU_ACC_CONFG_CLR3			(0x004c)
+#define APU_ACC_CLK_INV_EN_SET			(0x00e8)
+#define APU_ACC_AUTO_CTRL_SET2			(0x0128)
+#define APU_ACC_AUTO_CTRL_SET3			(0x012c)
+
+/* ACC control */
+#define CGEN_SOC				BIT(2)
+#define HW_CTRL_EN				BIT(15)
+#define CLK_REQ_SW_EN				BIT(8)
+#define CLK_INV_EN				(0xaaa8)
+
+/* ARE offset define */
+#define APU_ARE_INI_CTRL			(0x0000)
+#define APU_ARE_GLO_FSM				(0x0048)
+#define APU_ARE_ENTRY0_SRAM_H			(0x0c00)
+#define APU_ARE_ENTRY0_SRAM_L			(0x0800)
+#define APU_ARE_ENTRY1_SRAM_H			(0x0c04)
+#define APU_ARE_ENTRY1_SRAM_L			(0x0804)
+#define APU_ARE_ENTRY2_SRAM_H			(0x0c08)
+#define APU_ARE_ENTRY2_SRAM_L			(0x0808)
+
+/* ARE control */
+#define ARE_ENTRY_CFG_H				(0x00140000)
+#define ARE0_ENTRY2_CFG_L			(0x004e0804)
+#define ARE1_ENTRY2_CFG_L			(0x004e0806)
+#define ARE2_ENTRY2_CFG_L			(0x004e0807)
+#define ARE_GLO_FSM_IDLE			BIT(0)
+#define ARE_ENTRY0_SRAM_H_INIT			(0x12345678)
+#define ARE_ENTRY0_SRAM_L_INIT			(0x89abcdef)
+#define ARE_ENTRY1_SRAM_H_INIT			(0xfedcba98)
+#define ARE_ENTRY1_SRAM_L_INIT			(0x76543210)
+#define ARE_CONFG_INI				BIT(2)
+
+/* VCORE offset define */
+#define APUSYS_VCORE_CG_CLR			(0x0008)
+
+/* RCX offset define */
+#define APU_RCX_CG_CLR				(0x0008)
+
+/* SPM offset define */
+#define APUSYS_BUCK_ISOLATION			(0x03ec)
+
+/* SPM control*/
+#define IPU_EXT_BUCK_ISO			(0x21)
+
+/* apu_rcx_ao_ctrl  */
+#define CSR_DUMMY_0_ADDR			(0x0024)
+
+/* apu_rcx_ao_ctrl control */
+#define VCORE_ARE_REQ				BIT(2)
+
+/* xpu2apusys */
+#define INFRA_FMEM_BUS_u_SI21_CTRL_0		(0x002c)
+#define INFRA_FMEM_BUS_u_SI22_CTRL_0		(0x0044)
+#define INFRA_FMEM_BUS_u_SI11_CTRL_0		(0x0048)
+#define INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0	(0x01d0)
+
+/* xpu2apusys */
+#define INFRA_FMEM_BUS_u_SI21_CTRL_EN		BIT(12)
+#define INFRA_FMEM_BUS_u_SI22_CTRL_EN		BIT(13)
+#define INFRA_FMEM_BUS_u_SI11_CTRL_EN		BIT(11)
+#define INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN	BIT(15)
+
+/* PCU offset define */
+#define APU_PCU_CTRL_SET			(0x0000)
+#define APU_PCU_BUCK_STEP_SEL			(0x0030)
+#define APU_PCU_BUCK_ON_DAT0_L			(0x0080)
+#define APU_PCU_BUCK_ON_DAT0_H			(0x0084)
+#define APU_PCU_BUCK_ON_DAT1_L			(0x0088)
+#define APU_PCU_BUCK_ON_DAT1_H			(0x008c)
+#define APU_PCU_BUCK_OFF_DAT0_L			(0x00a0)
+#define APU_PCU_BUCK_OFF_DAT0_H			(0x00a4)
+#define APU_PCU_BUCK_OFF_DAT1_L			(0x00a8)
+#define APU_PCU_BUCK_OFF_DAT1_H			(0x00ac)
+#define APU_PCU_BUCK_ON_SLE0			(0x00c0)
+#define APU_PCU_BUCK_ON_SLE1			(0x00c4)
+#define APU_PCU_BUCK_ON_SETTLE_TIME		(0x012c)
+
+/* PCU initial data */
+#define MT6359P_RG_BUCK_VMODEM_EN_ADDR		(0x1688)
+#define MT6359P_RG_LDO_VSRAM_MD_EN_ADDR		(0x1f2e)
+#define BUCK_VAPU_PMIC_REG_EN_ADDR		MT6359P_RG_BUCK_VMODEM_EN_ADDR
+#define BUCK_VAPU_SRAM_PMIC_REG_EN_ADDR		MT6359P_RG_LDO_VSRAM_MD_EN_ADDR
+
+/* PCU control */
+#define AUTO_BUCK_EN				BIT(16)
+#define BUCK_ON_OFF_CMD_EN			(0x33)
+#define BUCK_OFFSET_SFT				(16)
+#define BUCK_ON_CMD				(0x1)
+#define BUCK_OFF_CMD				(0x0)
+#define CMD_OP					(0x4)
+
+/* RPC lite offset define */
+#define APU_RPC_SW_TYPE2			(0x0208)
+#define APU_RPC_SW_TYPE3			(0x020c)
+#define APU_RPC_SW_TYPE4			(0x0210)
+#define APU_RPC_SW_TYPE5			(0x0214)
+#define APU_RPC_SW_TYPE6			(0x0218)
+#define APU_RPC_SW_TYPE7			(0x021c)
+#define APU_RPC_SW_TYPE8			(0x0220)
+#define APU_RPC_SW_TYPE9			(0x0224)
+
+/* power flow sync */
+#define PWR_FLOW_SYNC_REG			(0x0440)
+
+#define CG_CLR					(0xffffffff)
+
+int apusys_power_init(void);
+int apusys_kernel_apusys_pwr_top_on(void);
+int apusys_kernel_apusys_pwr_top_off(void);
+
+#endif /* APUSYS_POWER_H */
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
new file mode 100644
index 0000000..c358067
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/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_${MTK_SOC}
+
+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
new file mode 100644
index 0000000..498925c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := apusys
+
+LOCAL_SRCS-y:= ${LOCAL_DIR}/apusys.c
+
+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/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
index 27b2b07..bf77791 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.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
  */
@@ -9,6 +9,7 @@
 #include <lib/mmio.h>
 #include <emi_mpu.h>
 #include <lib/mtk_init/mtk_init.h>
+#include <mtk_sip_svc.h>
 
 #if ENABLE_EMI_MPU_SW_LOCK
 static unsigned char region_lock_state[EMI_MPU_REGION_NUM];
@@ -111,6 +112,16 @@
 	return 0;
 }
 
+u_register_t mtk_emi_mpu_sip_handler(u_register_t x1, u_register_t x2,
+				     u_register_t x3, u_register_t x4,
+				     void *handle, struct smccc_res *smccc_ret)
+{
+	/* TODO: implement emi mpu handler */
+
+	return 0;
+}
+DECLARE_SMC_HANDLER(MTK_SIP_TEE_MPU_PERM_SET, mtk_emi_mpu_sip_handler);
+
 int emi_mpu_init(void)
 {
 	INFO("[%s] emi mpu initialization\n", __func__);
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/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c
index cca5d0a..85f9e37 100644
--- a/plat/mediatek/drivers/gic600/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c
@@ -42,13 +42,19 @@
 
 struct gic_chip_data {
 	/* All cores share the same configuration */
+	unsigned int saved_ctlr;
 	unsigned int saved_group;
 	unsigned int saved_enable;
 	unsigned int saved_conf0;
 	unsigned int saved_conf1;
 	unsigned int saved_grpmod;
+	unsigned int saved_ispendr;
+	unsigned int saved_isactiver;
+	unsigned int saved_nsacr;
 	/* Per-core sgi */
 	unsigned int saved_sgi[PLATFORM_CORE_COUNT];
+	/* Per-core priority */
+	unsigned int saved_prio[PLATFORM_CORE_COUNT][GICR_NUM_REGS(IPRIORITYR)];
 };
 
 static struct gic_chip_data gic_data;
@@ -94,53 +100,84 @@
 
 void mt_gic_rdistif_save(void)
 {
-	unsigned int proc_num;
+	unsigned int i, proc_num;
 	uintptr_t gicr_base;
 
 	proc_num = plat_my_core_pos();
 	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 
+	/*
+	 * Wait for any write to GICR_CTLR to complete before trying to save any
+	 * state.
+	 */
+	gicr_wait_for_pending_write(gicr_base);
+
+	gic_data.saved_ctlr = mmio_read_32(gicr_base + GICR_CTLR);
 	gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0);
 	gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0);
 	gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0);
 	gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1);
 	gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0);
+	gic_data.saved_ispendr = mmio_read_32(gicr_base + GICR_ISPENDR0);
+	gic_data.saved_isactiver = mmio_read_32(gicr_base + GICR_ISACTIVER0);
+	gic_data.saved_nsacr = mmio_read_32(gicr_base + GICR_NSACR);
+
+	for (i = 0U; i < 8U; ++i)
+		gic_data.saved_prio[proc_num][i] = gicr_ipriorityr_read(gicr_base, i);
 
 	rdist_has_saved[proc_num] = 1;
 }
 
 void mt_gic_rdistif_restore(void)
 {
-	unsigned int proc_num;
+	unsigned int i, proc_num;
 	uintptr_t gicr_base;
 
 	proc_num = plat_my_core_pos();
 	if (rdist_has_saved[proc_num] == 1) {
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
 		mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
-		mmio_write_32(gicr_base + GICR_ISENABLER0,
-			gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod);
+		mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr);
 		mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
 		mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
-		mmio_write_32(gicr_base + GICR_IGRPMODR0,
-			gic_data.saved_grpmod);
+
+		for (i = 0U; i < 8U; ++i)
+			gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]);
+
+		mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr);
+		mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver);
+		mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr);
+
+		gicr_wait_for_pending_write(gicr_base);
 	}
 }
 
 void mt_gic_rdistif_restore_all(void)
 {
-	unsigned int proc_num;
+	unsigned int i, proc_num;
 	uintptr_t gicr_base;
 
 	for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) {
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
 		mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
-		mmio_write_32(gicr_base + GICR_ISENABLER0,
-			gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod);
+		mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr);
 		mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
 		mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
-		mmio_write_32(gicr_base + GICR_IGRPMODR0,
-			gic_data.saved_grpmod);
+
+		for (i = 0U; i < 8U; ++i)
+			gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]);
+
+		mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr);
+		mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver);
+		mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr);
+
+		gicr_wait_for_pending_write(gicr_base);
 	}
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
index 0b792ab..c8a2d4c 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
@@ -53,6 +53,7 @@
 static struct mt_irqremain *refer2remain_irq;
 
 static struct mt_spm_cond_tables cond_bus26m = {
+	.name = "bus26m",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -175,7 +176,7 @@
 		(IS_PLAT_SUSPEND_ID(state_id) || (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
 	const struct mt_spm_cond_tables *tlb_check =
@@ -185,7 +186,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						 &cond_bus26m_res : NULL);
 	status.all_pll_dump = mt_spm_dump_all_pll(tlb, tlb_check,
@@ -279,7 +280,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_UPDATE_REMAIN_IRQS:
 		update_rc_remain_irqs(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
index d1a2435..82b38ad 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
@@ -37,6 +37,7 @@
 #define CONSTRAINT_DRAM_RESOURCE_REQ (MT_SPM_SYSPLL | MT_SPM_INFRA | MT_SPM_26M)
 
 static struct mt_spm_cond_tables cond_dram = {
+	.name = "dram",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -104,7 +105,7 @@
 		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
 	const struct mt_spm_cond_tables *tlb_check = (const struct mt_spm_cond_tables *)&cond_dram;
@@ -113,7 +114,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						  &cond_dram_res : NULL);
 	return MT_RM_STATUS_OK;
@@ -185,7 +186,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_CLKBUF_STATUS:
 		update_rc_clkbuf_status(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
index 700f500..5359c7c 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
@@ -49,6 +49,7 @@
 static unsigned short ext_status_syspll;
 
 static struct mt_spm_cond_tables cond_syspll = {
+	.name = "syspll",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -113,7 +114,7 @@
 		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	int res = MT_RM_STATUS_OK;
 
@@ -126,7 +127,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						 &cond_syspll_res : NULL);
 	return res;
@@ -228,7 +229,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_CLKBUF_STATUS:
 		update_rc_clkbuf_status(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
index fe6e598..bed55c9 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
@@ -126,12 +126,14 @@
 #define PLL_APLL4	MT_LP_TZ_APMIXEDSYS(0x404)
 #define PLL_APLL5	MT_LP_TZ_APMIXEDSYS(0x418)
 
-unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+unsigned int mt_spm_cond_check(int state_id,
+			       const struct mt_spm_cond_tables *src,
 			       const struct mt_spm_cond_tables *dest,
 			       struct mt_spm_cond_tables *res)
 {
 	unsigned int b_res = 0U;
 	unsigned int i;
+	bool is_system_suspend = IS_PLAT_SUSPEND_ID(state_id);
 
 	if ((src == NULL) || (dest == NULL)) {
 		return SPM_COND_CHECK_FAIL;
@@ -140,6 +142,11 @@
 	for (i = 0; i < PLAT_SPM_COND_MAX; i++) {
 		if (res != NULL) {
 			res->table_cg[i] = (src->table_cg[i] & dest->table_cg[i]);
+			if (is_system_suspend && ((res->table_cg[i]) != 0U)) {
+				INFO("suspend: %s block[%u](0x%lx) = 0x%08x\n",
+				     dest->name, i, idle_cg_info[i].addr,
+				     res->table_cg[i]);
+			}
 
 			if ((res->table_cg[i]) != 0U) {
 				b_res |= BIT(i);
@@ -161,6 +168,10 @@
 		b_res |= SPM_COND_CHECK_BLOCKED_PLL;
 	}
 
+	if (is_system_suspend && ((b_res) != 0U)) {
+		INFO("suspend: %s total blocked = 0x%08x\n", dest->name, b_res);
+	}
+
 	return b_res;
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
index 793d5e8..d93df57 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
@@ -75,13 +75,15 @@
 #define SPM_COND_CHECK_FAIL		BIT(31)
 
 struct mt_spm_cond_tables {
+	char *name;
 	unsigned int table_cg[PLAT_SPM_COND_MAX];
 	unsigned int table_pll;
 	unsigned int table_all_pll;
 	void *priv;
 };
 
-unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+unsigned int mt_spm_cond_check(int state_id,
+			       const struct mt_spm_cond_tables *src,
 			       const struct mt_spm_cond_tables *dest,
 			       struct mt_spm_cond_tables *res);
 unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src,
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
index bcb2df6..395448a 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
@@ -61,6 +61,14 @@
 
 	__spm_send_cpu_wakeup_event();
 
+	INFO("cpu%d: wakesrc = 0x%x, settle = 0x%x, sec = %u\n",
+	     cpu, pwrctrl->wake_src, mmio_read_32(SPM_CLK_SETTLE),
+	     (mmio_read_32(PCM_TIMER_VAL) / 32768));
+	INFO("sw_flag = 0x%x 0x%x, req = 0x%x, pwr = 0x%x 0x%x\n",
+	     pwrctrl->pcm_flags, pwrctrl->pcm_flags1,
+	     mmio_read_32(SPM_SRC_REQ), mmio_read_32(PWR_STATUS),
+	     mmio_read_32(PWR_STATUS_2ND));
+
 	return ret;
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
index b38a6d0..5eb16b3 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
@@ -24,6 +24,7 @@
 
 wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta)
 {
+	uint32_t bk_vtcxo_dur, spm_26m_off_pct;
 	wake_reason_t wr = WR_UNKNOWN;
 
 	if (wakesta == NULL) {
@@ -46,6 +47,33 @@
 		}
 	}
 
+	INFO("r12 = 0x%x, r12_ext = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n",
+	     wakesta->tr.comm.r12, wakesta->r12_ext, wakesta->tr.comm.r13, wakesta->tr.comm.debug_flag,
+	     wakesta->tr.comm.debug_flag1);
+	INFO("raw_sta = 0x%x 0x%x 0x%x, idle_sta = 0x%x, cg_check_sta = 0x%x\n",
+	     wakesta->tr.comm.raw_sta, wakesta->md32pcm_wakeup_sta,
+	     wakesta->md32pcm_event_sta, wakesta->idle_sta,
+	     wakesta->cg_check_sta);
+	INFO("req_sta = 0x%x 0x%x 0x%x 0x%x 0x%x, isr = 0x%x\n",
+	     wakesta->tr.comm.req_sta0, wakesta->tr.comm.req_sta1, wakesta->tr.comm.req_sta2,
+	     wakesta->tr.comm.req_sta3, wakesta->tr.comm.req_sta4, wakesta->isr);
+	INFO("rt_req_sta0 = 0x%x, rt_req_sta1 = 0x%x, rt_req_sta2 = 0x%x\n",
+	     wakesta->rt_req_sta0, wakesta->rt_req_sta1, wakesta->rt_req_sta2);
+	INFO("rt_req_sta3 = 0x%x, dram_sw_con_3 = 0x%x, raw_ext_sta = 0x%x\n",
+	     wakesta->rt_req_sta3, wakesta->rt_req_sta4, wakesta->raw_ext_sta);
+	INFO("wake_misc = 0x%x, pcm_flag = 0x%x 0x%x 0x%x 0x%x, req = 0x%x\n",
+	     wakesta->wake_misc, wakesta->sw_flag0, wakesta->sw_flag1,
+	     wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1, wakesta->src_req);
+	INFO("clk_settle = 0x%x, wlk_cntcv_l = 0x%x, wlk_cntcv_h = 0x%x\n",
+	     wakesta->clk_settle, mmio_read_32(SYS_TIMER_VALUE_L),
+	     mmio_read_32(SYS_TIMER_VALUE_H));
+
+	if (wakesta->tr.comm.timer_out != 0U) {
+		bk_vtcxo_dur = mmio_read_32(SPM_BK_VTCXO_DUR);
+		spm_26m_off_pct = (100 * bk_vtcxo_dur) / wakesta->tr.comm.timer_out;
+		INFO("spm_26m_off_pct = %u\n", spm_26m_off_pct);
+	}
+
 	return wr;
 }
 
@@ -331,6 +359,18 @@
 	wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);	/* SPM_SW_RSV_7 */
 	wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);	/* SPM_SW_RSV_8 */
 
+	/* record below spm info for debug */
+	wakesta->src_req = mmio_read_32(SPM_SRC_REQ);
+
+	/* get HW CG check status */
+	wakesta->cg_check_sta = mmio_read_32(SPM_CG_CHECK_STA);
+
+	wakesta->rt_req_sta0 = mmio_read_32(SPM_SW_RSV_2);
+	wakesta->rt_req_sta1 = mmio_read_32(SPM_SW_RSV_3);
+	wakesta->rt_req_sta2 = mmio_read_32(SPM_SW_RSV_4);
+	wakesta->rt_req_sta3 = mmio_read_32(SPM_SW_RSV_5);
+	wakesta->rt_req_sta4 = mmio_read_32(SPM_SW_RSV_6);
+
 	/* get ISR status */
 	wakesta->isr = mmio_read_32(SPM_IRQ_STA);
 
@@ -338,6 +378,9 @@
 	wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0);
 	wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1);
 
+	/* get CLK SETTLE */
+	wakesta->clk_settle = mmio_read_32(SPM_CLK_SETTLE);
+
 	/* check abort */
 	wakesta->is_abort = wakesta->tr.comm.debug_flag & DEBUG_ABORT_MASK;
 	wakesta->is_abort |= wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1;
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
index c719caf..5e3390f 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
@@ -628,11 +628,19 @@
 	uint32_t md32pcm_event_sta;	/* MD32PCM_EVENT_STA */
 	uint32_t wake_misc;		/* SPM_SW_RSV_5 */
 	uint32_t idle_sta;		/* SUBSYS_IDLE_STA */
+	uint32_t cg_check_sta;		/* SPM_CG_CHECK_STA */
 	uint32_t sw_flag0;		/* SPM_SW_FLAG_0 */
 	uint32_t sw_flag1;		/* SPM_SW_FLAG_1 */
 	uint32_t isr;			/* SPM_IRQ_STA */
+	uint32_t clk_settle;		/* SPM_CLK_SETTLE */
+	uint32_t src_req;		/* SPM_SRC_REQ */
 	uint32_t log_index;
 	uint32_t is_abort;
+	uint32_t rt_req_sta0;		/* SPM_SW_RSV_2 */
+	uint32_t rt_req_sta1;		/* SPM_SW_RSV_3 */
+	uint32_t rt_req_sta2;		/* SPM_SW_RSV_4 */
+	uint32_t rt_req_sta3;		/* SPM_SW_RSV_5 */
+	uint32_t rt_req_sta4;		/* SPM_SW_RSV_6 */
 };
 
 struct spm_lp_scen {
diff --git a/plat/mediatek/include/mtk_sip_def.h b/plat/mediatek/include/mtk_sip_def.h
index 2039017..a86a46c 100644
--- a/plat/mediatek/include/mtk_sip_def.h
+++ b/plat/mediatek/include/mtk_sip_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +19,9 @@
 	_func(MTK_SIP_DP_CONTROL, 0x523) \
 	_func(MTK_SIP_KERNEL_GIC_OP, 0x526)
 
+#define MTK_SIP_SMC_FROM_S_EL1_TABLE(_func) \
+	_func(MTK_SIP_TEE_MPU_PERM_SET, 0x031)
+
 #define MTK_SIP_SMC_FROM_BL33_TABLE(_func) \
 	_func(MTK_SIP_KERNEL_BOOT, 0x115)
 
diff --git a/plat/mediatek/include/mtk_sip_svc.h b/plat/mediatek/include/mtk_sip_svc.h
index ce51048..684f951 100644
--- a/plat/mediatek/include/mtk_sip_svc.h
+++ b/plat/mediatek/include/mtk_sip_svc.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
  */
@@ -55,11 +55,13 @@
 
 MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX);
 MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX);
+MTK_SIP_SMC_FROM_S_EL1_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX);
 
 /* Expand SiP SMC ID table as enum */
 enum {
 	MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_ENUM)
 	MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_ENUM)
+	MTK_SIP_SMC_FROM_S_EL1_TABLE(SMC_ID_EXPAND_AS_ENUM)
 	MTK_SIP_SMC_MAX_NUMBER
 };
 
@@ -95,7 +97,7 @@
 };
 
 /*
- * This function should be implemented in MediaTek SOC directory. It fullfills
+ * This function should be implemented in MediaTek SOC directory. It fulfills
  * MTK_SIP_SET_AUTHORIZED_SECURE_REG SiP call by checking the sreg with the
  * predefined secure register list, if a match was found, set val to sreg.
  *
diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c
index bd7d0b0..fd7874f 100644
--- a/plat/mediatek/mt8173/bl31_plat_setup.c
+++ b/plat/mediatek/mt8173/bl31_plat_setup.c
@@ -129,7 +129,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/mediatek/mt8173/drivers/spm/spm.c b/plat/mediatek/mt8173/drivers/spm/spm.c
index 8980e07..0d3acb2 100644
--- a/plat/mediatek/mt8173/drivers/spm/spm.c
+++ b/plat/mediatek/mt8173/drivers/spm/spm.c
@@ -20,7 +20,7 @@
  * - spm_suspend.c for system power control in system suspend scenario.
  *
  * This file provide utility functions common to hotplug, mcdi(idle), suspend
- * power scenarios. A bakery lock (software lock) is incoporated to protect
+ * power scenarios. A bakery lock (software lock) is incorporated to protect
  * certain critical sections to avoid kicking different SPM firmware
  * concurrently.
  */
diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c
index 7dac8a4..f608da3 100644
--- a/plat/mediatek/mt8183/bl31_plat_setup.c
+++ b/plat/mediatek/mt8183/bl31_plat_setup.c
@@ -163,7 +163,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/mediatek/mt8186/bl31_plat_setup.c b/plat/mediatek/mt8186/bl31_plat_setup.c
index 5fc6b6e..fb826be 100644
--- a/plat/mediatek/mt8186/bl31_plat_setup.c
+++ b/plat/mediatek/mt8186/bl31_plat_setup.c
@@ -102,7 +102,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index 34d4637..0a7ae6d 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -25,6 +25,32 @@
 #define TOPCKGEN_BASE		(IO_PHYS)
 
 /*******************************************************************************
+ * 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)
+
+/*******************************************************************************
  * AUDIO related constants
  ******************************************************************************/
 #define AUDIO_BASE		(IO_PHYS + 0x00b10000)
@@ -175,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/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index 85ceeb9..5096e15 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -24,6 +24,7 @@
 MODULES-y += $(MTK_PLAT)/lib/mtk_init
 MODULES-y += $(MTK_PLAT)/lib/pm
 MODULES-y += $(MTK_PLAT)/lib/system_reset
+MODULES-y += $(MTK_PLAT)/drivers/apusys
 MODULES-y += $(MTK_PLAT)/drivers/audio
 MODULES-y += $(MTK_PLAT)/drivers/cirq
 MODULES-y += $(MTK_PLAT)/drivers/cpu_pm
diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c
index c3cb9a5..3b23027 100644
--- a/plat/mediatek/mt8192/bl31_plat_setup.c
+++ b/plat/mediatek/mt8192/bl31_plat_setup.c
@@ -110,7 +110,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/mediatek/mt8195/bl31_plat_setup.c b/plat/mediatek/mt8195/bl31_plat_setup.c
index dff6670..0f5674f 100644
--- a/plat/mediatek/mt8195/bl31_plat_setup.c
+++ b/plat/mediatek/mt8195/bl31_plat_setup.c
@@ -106,7 +106,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/mediatek/mt8195/drivers/apusys/apupll.c b/plat/mediatek/mt8195/drivers/apusys/apupll.c
index 0eb8d4a..3c18798 100644
--- a/plat/mediatek/mt8195/drivers/apusys/apupll.c
+++ b/plat/mediatek/mt8195/drivers/apusys/apupll.c
@@ -268,7 +268,7 @@
  * @pll_idx: Which PLL to enable/disable
  * @on: 1 -> enable, 0 -> disable.
  *
- * This funciton will only change RG_PLL_EN of CON1 for pll[pll_idx].
+ * This function will only change RG_PLL_EN of CON1 for pll[pll_idx].
  *
  * Context: Any context.
  */
@@ -286,7 +286,7 @@
  * @pll_idx: Which PLL to enable/disable
  * @on: 1 -> enable, 0 -> disable.
  *
- * This funciton will only change PLL_SDM_PWR_ON of CON3 for pll[pll_idx].
+ * This function will only change PLL_SDM_PWR_ON of CON3 for pll[pll_idx].
  *
  * Context: Any context.
  */
@@ -304,7 +304,7 @@
  * @pll_idx: Which PLL to enable/disable
  * @enable: 1 -> turn on isolation, 0 -> turn off isolation.
  *
- * This funciton will turn on/off pll isolation by
+ * This function will turn on/off pll isolation by
  * changing PLL_SDM_PWR_ON of CON3 for pll[pll_idx].
  *
  * Context: Any context.
@@ -324,7 +324,7 @@
  * @on: 1 -> enable, 0 -> disable.
  * @fhctl_en: enable or disable fhctl function
  *
- * This is the entry poing for controlling pll and fhctl funciton on/off.
+ * This is the entry poing for controlling pll and fhctl function on/off.
  * Caller can chose only enable pll instead of fhctl function.
  *
  * Context: Any context.
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
index 794e21e..b6e5a2d 100644
--- a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <emi_mpu.h>
+#include <mtk_sip_svc.h>
 
 #if ENABLE_EMI_MPU_SW_LOCK
 static unsigned char region_lock_state[EMI_MPU_REGION_NUM];
@@ -17,6 +18,7 @@
 #define EMI_MPU_END_MASK		(0x00FFFFFF)
 #define EMI_MPU_APC_SW_LOCK_MASK	(0x00FFFFFF)
 #define EMI_MPU_APC_HW_LOCK_MASK	(0x80FFFFFF)
+#define MPU_PHYSICAL_ADDR_SHIFT_BITS	(16)
 
 static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
 					unsigned int apc)
@@ -139,7 +141,7 @@
 	/* Forbidden All */
 	region_info.start = 0x40000000ULL;	/* dram base addr */
 	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 4;
+	region_info.region = 5;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -149,3 +151,42 @@
 
 	dump_emi_mpu_regions();
 }
+
+static inline uint64_t get_decoded_phys_addr(uint64_t addr)
+{
+	return (addr << MPU_PHYSICAL_ADDR_SHIFT_BITS);
+}
+
+static inline uint32_t get_decoded_zone_id(uint32_t info)
+{
+	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
+}
+
+int32_t emi_mpu_sip_handler(uint64_t encoded_addr, uint64_t zone_size, uint64_t zone_info)
+{
+	uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
+	struct emi_region_info_t region_info;
+	enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
+
+	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
+	     encoded_addr, zone_size, zone_info);
+
+	if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) {
+		ERROR("Invalid param %s, %d\n", __func__, __LINE__);
+		return MTK_SIP_E_INVALID_PARAM;
+	}
+
+	/* SVP DRAM */
+	region_info.start = phys_addr;
+	region_info.end = phys_addr + zone_size;
+	region_info.region = 4;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+
+	emi_mpu_set_protection(&region_info);
+
+	return 0;
+}
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h
index 415146e..83bd6de 100644
--- a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -93,6 +93,15 @@
 	unsigned int apc[EMI_MPU_DGROUP_NUM];
 };
 
+enum MPU_REQ_ORIGIN_ZONE_ID {
+	MPU_REQ_ORIGIN_TEE_ZONE_SVP = 0,
+	MPU_REQ_ORIGIN_TEE_ZONE_TUI = 1,
+	MPU_REQ_ORIGIN_TEE_ZONE_WFD = 2,
+	MPU_REQ_ORIGIN_TEE_ZONE_MAX = 3,
+	MPU_REQ_ORIGIN_ZONE_INVALID = 0x7FFFFFFF,
+};
+
 void emi_mpu_init(void);
+int32_t emi_mpu_sip_handler(uint64_t encoded_addr, uint64_t zone_size, uint64_t zone_info);
 
 #endif
diff --git a/plat/mediatek/mt8195/plat_sip_calls.c b/plat/mediatek/mt8195/plat_sip_calls.c
index 1cdd622..2debeff 100644
--- a/plat/mediatek/mt8195/plat_sip_calls.c
+++ b/plat/mediatek/mt8195/plat_sip_calls.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <emi_mpu.h>
 #include <mt_dp.h>
 #include <mt_spm.h>
 #include <mt_spm_vcorefs.h>
@@ -27,6 +28,11 @@
 	uint32_t ret_val;
 
 	switch (smc_fid) {
+	case MTK_SIP_TEE_MPU_PERM_SET_AARCH64:
+	case MTK_SIP_TEE_MPU_PERM_SET_AARCH32:
+		ret = emi_mpu_sip_handler(x1, x2, x3);
+		SMC_RET2(handle, ret, ret_val);
+		break;
 	case MTK_SIP_DP_CONTROL_AARCH32:
 	case MTK_SIP_DP_CONTROL_AARCH64:
 		ret = dp_secure_handler(x1, x2, &ret_val);
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 6c8c4f0..72ecd54 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -125,15 +125,18 @@
 .endm
 
 	/* -----------------------------------------------------
-	 * unsigned int plat_is_my_cpu_primary(void);
+	 * bool plat_is_my_cpu_primary(void);
 	 *
 	 * This function checks if this is the Primary CPU
+	 *
+	 * Registers clobbered: x0, x1
 	 * -----------------------------------------------------
 	 */
 func plat_is_my_cpu_primary
 	mrs	x0, mpidr_el1
-	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
-	cmp	x0, #TEGRA_PRIMARY_CPU
+	adr	x1, tegra_primary_cpu_mpid
+	ldr	x1, [x1]
+	cmp	x0, x1
 	cset	x0, eq
 	ret
 endfunc plat_is_my_cpu_primary
@@ -251,6 +254,14 @@
 	adr	x18, bl31_entrypoint
 	str	x18, [x17]
 
+	/* -----------------------------------
+	 * save the boot CPU MPID value
+	 * -----------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	adr	x1, tegra_primary_cpu_mpid
+	str	x0, [x1]
+
 1:	cpu_init_common
 
 	ret
@@ -426,3 +437,10 @@
 	 */
 tegra_console_base:
 	.quad	0
+
+	/* --------------------------------------------------
+	 * MPID value for the boot CPU
+	 * --------------------------------------------------
+	 */
+tegra_primary_cpu_mpid:
+	.quad	0
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 6a3eae0..e3068b6 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,21 +92,16 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0;
-	plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
+	struct tegra_bl31_params *arg_from_bl2 = plat_get_bl31_params();
+	plat_params_from_bl2_t *plat_params = plat_get_bl31_plat_params();
 	int32_t ret;
 
 	/*
-	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
-	 * there's no argument to relay from a previous bootloader. Platforms
-	 * might use custom ways to get arguments.
+	 * Tegra platforms will receive boot parameters through custom
+	 * mechanisms. So, we ignore the input parameters.
 	 */
-	if (arg_from_bl2 == NULL) {
-		arg_from_bl2 = plat_get_bl31_params();
-	}
-	if (plat_params == NULL) {
-		plat_params = plat_get_bl31_plat_params();
-	}
+	(void)arg0;
+	(void)arg1;
 
 	/*
 	 * Copy BL3-3, BL3-2 entry point information.
@@ -267,7 +262,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this only intializes the mmu in a quick and dirty way.
+ * moment this only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index ec34a85..8edb024 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,6 +92,16 @@
 /*******************************************************************************
  * Handler called when a power domain is about to be turned off. The
  * target_state encodes the power state that each level should transition to.
+ * Return error if CPU off sequence is not allowed for the current core.
+ ******************************************************************************/
+static int tegra_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	return tegra_soc_pwr_domain_off_early(target_state);
+}
+
+/*******************************************************************************
+ * Handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
 static void tegra_pwr_domain_off(const psci_power_state_t *target_state)
 {
@@ -268,6 +278,7 @@
 static plat_psci_ops_t tegra_plat_psci_ops = {
 	.cpu_standby			= tegra_cpu_standby,
 	.pwr_domain_on			= tegra_pwr_domain_on,
+	.pwr_domain_off_early		= tegra_pwr_domain_off_early,
 	.pwr_domain_off			= tegra_pwr_domain_off,
 	.pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
 	.pwr_domain_suspend		= tegra_pwr_domain_suspend,
diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
index 92120b5..0644fd2 100644
--- a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
@@ -301,7 +301,7 @@
 	if (video_mem_base != 0U) {
 		/*
 		 * Lock the non overlapping memory being cleared so that
-		 * other masters do not accidently write to it. The memory
+		 * other masters do not accidentally write to it. The memory
 		 * would be unlocked once the non overlapping region is
 		 * cleared and the new memory settings take effect.
 		 */
diff --git a/plat/nvidia/tegra/include/drivers/tegra_gic.h b/plat/nvidia/tegra/include/drivers/tegra_gic.h
index 6661dff..9f9477c 100644
--- a/plat/nvidia/tegra/include/drivers/tegra_gic.h
+++ b/plat/nvidia/tegra/include/drivers/tegra_gic.h
@@ -19,7 +19,7 @@
 } pcpu_fiq_state_t;
 
 /*******************************************************************************
- * Fucntion declarations
+ * Function declarations
  ******************************************************************************/
 void tegra_gic_cpuif_deactivate(void);
 void tegra_gic_init(void);
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index 84b3297..958a3f9 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -41,8 +41,6 @@
 #define PLATFORM_STACK_SIZE 		U(0x400)
 #endif
 
-#define TEGRA_PRIMARY_CPU		U(0x0)
-
 #define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
 					 PLATFORM_MAX_CPUS_PER_CLUSTER)
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index a971cec..cf8778b 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -84,7 +84,7 @@
 #define TEGRA_CLK_SE			TEGRA186_CLK_SE
 
 /*******************************************************************************
- * Tegra Miscellanous register constants
+ * Tegra Miscellaneous register constants
  ******************************************************************************/
 #define TEGRA_MISC_BASE			U(0x00100000)
 #define  HARDWARE_REVISION_OFFSET	U(0x4)
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index abe193f..2158913 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -60,7 +60,7 @@
 #define TEGRA_CLK_SE			TEGRA194_CLK_SE
 
 /*******************************************************************************
- * Tegra Miscellanous register constants
+ * Tegra Miscellaneous register constants
  ******************************************************************************/
 #define TEGRA_MISC_BASE			U(0x00100000)
 
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index cc2ad86..f93585d 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -98,6 +98,9 @@
 int32_t tegra_fiq_get_intr_context(void);
 void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
 
+/* Declarations for tegra_helpers.S */
+bool plat_is_my_cpu_primary(void);
+
 /* Declarations for tegra_security.c */
 void tegra_security_setup(void);
 void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
@@ -109,6 +112,7 @@
 int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state);
 int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
@@ -150,7 +154,7 @@
 		     void *handle,
 		     uint64_t flags);
 
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 void tegra194_ras_enable(void);
 void tegra194_ras_corrected_err_clear(uint64_t *cookie);
 #endif
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
index ecfb3f4..45302da 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
@@ -40,7 +40,7 @@
 	/* index 83 is deprecated */
 	TEGRA_ARI_PERFMON = 84U,
 	TEGRA_ARI_UPDATE_CCPLEX_GSC = 85U,
-	/* index 86 is depracated */
+	/* index 86 is deprecated */
 	/* index 87 is deprecated */
 	TEGRA_ARI_ROC_FLUSH_CACHE_ONLY = 88U,
 	TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS = 89U,
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index af4182e..8f88e28 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -433,6 +433,16 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	/* Do not power off the boot CPU */
+	if (plat_is_my_cpu_primary()) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
index 7a68a43..ca74d2c 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
@@ -17,7 +17,7 @@
 
 /**
  * Current version - Major version increments may break backwards
- * compatiblity and binary compatibility. Minor version increments
+ * compatibility and binary compatibility. Minor version increments
  * occur when there is only new functionality.
  */
 enum {
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 41a85ee..83d815a 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -463,6 +463,16 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	/* Do not power off the boot CPU */
+	if (plat_is_my_cpu_primary()) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index a9fed0a..2f438c3 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -284,7 +284,7 @@
 	ERROR("RAS Error in %s, ERRSELR_EL1=0x%x:\n", name, errselr);
 	ERROR("\tStatus = 0x%" PRIx64 "\n", status);
 
-	/* Print uncorrectable errror information. */
+	/* Print uncorrectable error information. */
 	if (ERR_STATUS_GET_FIELD(status, UE) != 0U) {
 
 		ERR_STATUS_SET_FIELD(val, UE, 1);
@@ -484,7 +484,7 @@
 void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
 {
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags);
 #else
 	plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index 8f7d1e9..d3d09d3 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -254,7 +254,7 @@
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	/* Enable Uncorrectable RAS error */
 	tegra194_ras_enable();
 #endif
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index 1eef559..f0704ed 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -71,7 +71,7 @@
 
 		break;
 
-#if RAS_EXTENSION
+#if RAS_FFH_SUPPORT
 	case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
 	{
 		/*
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index 631c926..a183d0e 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -34,7 +34,8 @@
 
 # enable RAS handling
 HANDLE_EA_EL3_FIRST_NS			:= 1
-RAS_EXTENSION				:= 1
+ENABLE_FEAT_RAS				:= 1
+RAS_FFH_SUPPORT				:= 1
 
 # platform files
 PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t194 \
@@ -68,7 +69,7 @@
 endif
 
 # RAS sources
-ifeq (${RAS_EXTENSION},1)
+ifeq (${RAS_FFH_SUPPORT},1)
 BL31_SOURCES		+=	lib/extensions/ras/std_err_record.c		\
 				lib/extensions/ras/ras_common.c			\
 				${SOC_DIR}/plat_ras.c
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 7f73ea5..2ec044c 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -575,6 +575,16 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	/* Do not power off the boot CPU */
+	if (plat_is_my_cpu_primary()) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index 93d1283..f3ebd4b 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -33,8 +33,7 @@
 /*******************************************************************************
  * Tegra210 SiP SMCs
  ******************************************************************************/
-#define TEGRA_SIP_PMC_COMMANDS_LEGACY	U(0xC2FEFE00)
-#define TEGRA_SIP_PMC_COMMANDS		U(0xC2FFFE00)
+#define TEGRA_SIP_PMC_COMMANDS		U(0xC200FE00)
 
 /*******************************************************************************
  * This function is responsible for handling all T210 SiP calls
@@ -55,10 +54,12 @@
 	if (!ns)
 		SMC_RET1(handle, SMC_UNK);
 
-	if ((smc_fid == TEGRA_SIP_PMC_COMMANDS) || (smc_fid == TEGRA_SIP_PMC_COMMANDS_LEGACY)) {
+	if (smc_fid == TEGRA_SIP_PMC_COMMANDS) {
+
 		/* check the address is within PMC range and is 4byte aligned */
-		if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
+		if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3)) {
 			return -EINVAL;
+		}
 
 		switch (x2) {
 		/* Black listed PMC registers */
diff --git a/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk b/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
index 7d673ba..36c07b7 100644
--- a/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
+++ b/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
@@ -1,5 +1,6 @@
 #
 # Copyright 2020 NXP
+# Copyright (c) 2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,8 +23,6 @@
 
 DDR_FIP_IO_SOURCES	+= $(DDR_FIP_IO_STORAGE_PATH)/ddr_io_storage.c
 
-$(shell cp tools/nxp/plat_fiptool/plat_fiptool.mk ${PLAT_DIR})
-
 ifeq (${BL_COMM_DDR_FIP_IO_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${DDR_FIP_IO_SOURCES}
 else
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
index d8f5ae6..4e84d02 100644
--- a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
@@ -1,5 +1,6 @@
 #
 # Copyright 2018-2020 NXP
+# Copyright (c) 2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,8 +30,6 @@
 
 ifeq (${FUSE_PROV_FILE},)
 
-$(shell cp tools/nxp/plat_fiptool/plat_fiptool.mk ${PLAT_DIR})
-
 else
 ifeq (${TRUSTED_BOARD_BOOT},1)
 FUSE_PROV_FILE_SB = $(notdir ${FUSE_PROV_FILE})_prov.sb
diff --git a/plat/nxp/common/setup/ls_bl31_setup.c b/plat/nxp/common/setup/ls_bl31_setup.c
index bd0ab4f..3d0d804 100644
--- a/plat/nxp/common/setup/ls_bl31_setup.c
+++ b/plat/nxp/common/setup/ls_bl31_setup.c
@@ -174,7 +174,7 @@
 	soc_platform_setup();
 
 	/* Console logs gone missing as part going to
-	 * EL1 for initilizing Bl32 if present.
+	 * EL1 for initializing Bl32 if present.
 	 * console flush is necessary to avoid it.
 	 */
 	(void)console_flush();
diff --git a/plat/nxp/soc-ls1088a/include/soc.h b/plat/nxp/soc-ls1088a/include/soc.h
index eb36c2e..793feee 100644
--- a/plat/nxp/soc-ls1088a/include/soc.h
+++ b/plat/nxp/soc-ls1088a/include/soc.h
@@ -112,7 +112,7 @@
 #define IPSTPCR1_VALUE			0x000003FF
 #define IPSTPCR2_VALUE			0x00013006
 
-/* Dont' stop UART */
+/* Don't stop UART */
 #define IPSTPCR3_VALUE			0x0000033A
 
 #define IPSTPCR4_VALUE			0x00103300
diff --git a/plat/qemu/common/qemu_bl1_setup.c b/plat/qemu/common/qemu_bl1_setup.c
index 67f3327..529510c 100644
--- a/plat/qemu/common/qemu_bl1_setup.c
+++ b/plat/qemu/common/qemu_bl1_setup.c
@@ -14,6 +14,29 @@
 
 #include "qemu_private.h"
 
+#define MAP_BL1_TOTAL		MAP_REGION_FLAT(			\
+					bl1_tzram_layout.total_base,	\
+					bl1_tzram_layout.total_size,	\
+					MT_MEMORY | MT_RW | EL3_PAS)
+
+#define MAP_BL1_RO		MAP_REGION_FLAT(			\
+					BL_CODE_BASE,			\
+					BL1_CODE_END - BL_CODE_BASE,	\
+					MT_CODE | EL3_PAS),		\
+				MAP_REGION_FLAT(			\
+					BL1_RO_DATA_BASE,		\
+					BL1_RO_DATA_END			\
+						- BL_RO_DATA_BASE,	\
+					MT_RO_DATA | EL3_PAS)
+
+#if USE_COHERENT_MEM
+#define MAP_BL_COHERENT_RAM	MAP_REGION_FLAT(			\
+					BL_COHERENT_RAM_BASE,		\
+					BL_COHERENT_RAM_END		\
+						- BL_COHERENT_RAM_BASE,	\
+					MT_DEVICE | MT_RW | EL3_PAS)
+#endif
+
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
 static meminfo_t bl1_tzram_layout;
 
@@ -49,11 +72,21 @@
 
 void bl1_plat_arch_setup(void)
 {
-	QEMU_CONFIGURE_BL1_MMU(bl1_tzram_layout.total_base,
-				bl1_tzram_layout.total_size,
-				BL_CODE_BASE, BL1_CODE_END,
-				BL1_RO_DATA_BASE, BL1_RO_DATA_END,
-				BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
+	const mmap_region_t bl_regions[] = {
+		MAP_BL1_TOTAL,
+		MAP_BL1_RO,
+#if USE_COHERENT_MEM
+		MAP_BL_COHERENT_RAM,
+#endif
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_qemu_get_mmap());
+#ifdef __aarch64__
+	enable_mmu_el3(0);
+#else
+	enable_mmu_svc_mon(0);
+#endif
 }
 
 void bl1_platform_setup(void)
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index be55877..c4d235e 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -23,6 +23,28 @@
 
 #include "qemu_private.h"
 
+#define MAP_BL2_TOTAL		MAP_REGION_FLAT(			\
+					bl2_tzram_layout.total_base,	\
+					bl2_tzram_layout.total_size,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_BL2_RO		MAP_REGION_FLAT(			\
+					BL_CODE_BASE,			\
+					BL_CODE_END - BL_CODE_BASE,	\
+					MT_CODE | MT_SECURE),		\
+				MAP_REGION_FLAT(			\
+					BL_RO_DATA_BASE,		\
+					BL_RO_DATA_END			\
+						- BL_RO_DATA_BASE,	\
+					MT_RO_DATA | MT_SECURE)
+
+#if USE_COHERENT_MEM
+#define MAP_BL_COHERENT_RAM	MAP_REGION_FLAT(			\
+					BL_COHERENT_RAM_BASE,		\
+					BL_COHERENT_RAM_END		\
+						- BL_COHERENT_RAM_BASE,	\
+					MT_DEVICE | MT_RW | MT_SECURE)
+#endif
 
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
@@ -83,19 +105,24 @@
 	/* TODO Initialize timer */
 }
 
+void bl2_plat_arch_setup(void)
+{
+	const mmap_region_t bl_regions[] = {
+		MAP_BL2_TOTAL,
+		MAP_BL2_RO,
+#if USE_COHERENT_MEM
+		MAP_BL_COHERENT_RAM,
+#endif
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_qemu_get_mmap());
+
 #ifdef __aarch64__
-#define QEMU_CONFIGURE_BL2_MMU(...)	qemu_configure_mmu_el1(__VA_ARGS__)
+	enable_mmu_el1(0);
 #else
-#define QEMU_CONFIGURE_BL2_MMU(...)	qemu_configure_mmu_svc_mon(__VA_ARGS__)
+	enable_mmu_svc_mon(0);
 #endif
-
-void bl2_plat_arch_setup(void)
-{
-	QEMU_CONFIGURE_BL2_MMU(bl2_tzram_layout.total_base,
-			      bl2_tzram_layout.total_size,
-			      BL_CODE_BASE, BL_CODE_END,
-			      BL_RO_DATA_BASE, BL_RO_DATA_END,
-			      BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
 }
 
 /*******************************************************************************
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 4f60eb1..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
  */
@@ -12,6 +12,28 @@
 
 #include "qemu_private.h"
 
+#define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
+					BL31_BASE,			\
+					BL31_END - BL31_BASE,		\
+					MT_MEMORY | MT_RW | EL3_PAS)
+#define MAP_BL31_RO		MAP_REGION_FLAT(			\
+					BL_CODE_BASE,			\
+					BL_CODE_END - BL_CODE_BASE,	\
+					MT_CODE | EL3_PAS),		\
+				MAP_REGION_FLAT(			\
+					BL_RO_DATA_BASE,		\
+					BL_RO_DATA_END			\
+						- BL_RO_DATA_BASE,	\
+					MT_RO_DATA | EL3_PAS)
+
+#if USE_COHERENT_MEM
+#define MAP_BL_COHERENT_RAM	MAP_REGION_FLAT(			\
+					BL_COHERENT_RAM_BASE,		\
+					BL_COHERENT_RAM_END		\
+						- BL_COHERENT_RAM_BASE,	\
+					MT_DEVICE | MT_RW | EL3_PAS)
+#endif
+
 /*
  * Placeholder variables for copying the arguments that have been passed to
  * BL3-1 from BL2.
@@ -33,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
 	 */
@@ -64,10 +91,18 @@
 
 void bl31_plat_arch_setup(void)
 {
-	qemu_configure_mmu_el3(BL31_BASE, (BL31_END - BL31_BASE),
-			      BL_CODE_BASE, BL_CODE_END,
-			      BL_RO_DATA_BASE, BL_RO_DATA_END,
-			      BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
+#if USE_COHERENT_MEM
+		MAP_BL_COHERENT_RAM,
+#endif
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_qemu_get_mmap());
+
+	enable_mmu_el3(0);
 }
 
 static void qemu_gpio_init(void)
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 23ac581..98be491 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,6 +1,6 @@
 
 /*
- * 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
  */
@@ -122,45 +122,12 @@
 #endif
 
 /*******************************************************************************
- * Macro generating the code for the function setting up the pagetables as per
- * the platform memory map & initialize the mmu, for the given exception level
+ * Returns QEMU platform specific memory map regions.
  ******************************************************************************/
-
-#define DEFINE_CONFIGURE_MMU_EL(_el)					\
-	void qemu_configure_mmu_##_el(unsigned long total_base,	\
-				   unsigned long total_size,		\
-				   unsigned long code_start,		\
-				   unsigned long code_limit,		\
-				   unsigned long ro_start,		\
-				   unsigned long ro_limit,		\
-				   unsigned long coh_start,		\
-				   unsigned long coh_limit)		\
-	{								\
-		mmap_add_region(total_base, total_base,			\
-				total_size,				\
-				MT_MEMORY | MT_RW | MT_SECURE);		\
-		mmap_add_region(code_start, code_start,			\
-				code_limit - code_start,		\
-				MT_CODE | MT_SECURE);			\
-		mmap_add_region(ro_start, ro_start,			\
-				ro_limit - ro_start,			\
-				MT_RO_DATA | MT_SECURE);		\
-		mmap_add_region(coh_start, coh_start,			\
-				coh_limit - coh_start,			\
-				MT_DEVICE | MT_RW | MT_SECURE);		\
-		mmap_add(plat_qemu_mmap);				\
-		init_xlat_tables();					\
-									\
-		enable_mmu_##_el(0);					\
-	}
-
-/* Define EL1 and EL3 variants of the function initialising the MMU */
-#ifdef __aarch64__
-DEFINE_CONFIGURE_MMU_EL(el1)
-DEFINE_CONFIGURE_MMU_EL(el3)
-#else
-DEFINE_CONFIGURE_MMU_EL(svc_mon)
-#endif
+const mmap_region_t *plat_qemu_get_mmap(void)
+{
+	return plat_qemu_mmap;
+}
 
 #if MEASURED_BOOT || TRUSTED_BOARD_BOOT
 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
@@ -195,3 +162,14 @@
 	return 0;
 }
 #endif
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 159c44f..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
  */
@@ -9,28 +9,18 @@
 
 #include <stdint.h>
 
-void qemu_configure_mmu_svc_mon(unsigned long total_base,
-			unsigned long total_size,
-			unsigned long code_start, unsigned long code_limit,
-			unsigned long ro_start, unsigned long ro_limit,
-			unsigned long coh_start, unsigned long coh_limit);
-
-void qemu_configure_mmu_el1(unsigned long total_base, unsigned long total_size,
-			unsigned long code_start, unsigned long code_limit,
-			unsigned long ro_start, unsigned long ro_limit,
-			unsigned long coh_start, unsigned long coh_limit);
-
-void qemu_configure_mmu_el3(unsigned long total_base, unsigned long total_size,
-			unsigned long code_start, unsigned long code_limit,
-			unsigned long ro_start, unsigned long ro_limit,
-			unsigned long coh_start, unsigned long coh_limit);
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 void plat_qemu_io_setup(void);
 int qemu_io_register_sp_pkg(const char *name, const char *uuid,
 			    uintptr_t load_addr);
 unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
+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/common/qemu_sdei.c b/plat/qemu/common/qemu_sdei.c
new file mode 100644
index 0000000..820567e
--- /dev/null
+++ b/plat/qemu/common/qemu_sdei.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for ARM platforms */
+
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+#include <platform_def.h>
+
+/* Private event mappings */
+static sdei_ev_map_t qemu_sdei_private[] = {
+	SDEI_DEFINE_EVENT_0(PLAT_SDEI_SGI_PRIVATE),
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t qemu_sdei_shared[] = {
+};
+
+void plat_sdei_setup(void)
+{
+	INFO("SDEI platform setup\n");
+}
+
+/* Export Arm SDEI events */
+REGISTER_SDEI_MAP(qemu_sdei_private, qemu_sdei_shared);
diff --git a/plat/qemu/common/qemu_stack_protector.c b/plat/qemu/common/qemu_stack_protector.c
index 15ce3d6..d0b4a0f 100644
--- a/plat/qemu/common/qemu_stack_protector.c
+++ b/plat/qemu/common/qemu_stack_protector.c
@@ -14,12 +14,10 @@
 
 u_register_t plat_get_stack_protector_canary(void)
 {
-#if ENABLE_FEAT_RNG
 	/* Use the RNDR instruction if the CPU supports it */
-	if (is_armv8_5_rng_present()) {
+	if (is_feat_rng_supported()) {
 		return read_rndr();
 	}
-#endif
 
 	/*
 	 * Ideally, a random number should be returned above. If a random
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 803f8e2..93a3ce8 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -23,15 +23,14 @@
 #define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
 #define PLATFORM_CLUSTER1_CORE_COUNT	U(0)
 #else
-#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
 /*
  * Define the number of cores per cluster used in calculating core position.
  * The cluster number is shifted by this value and added to the core ID,
  * so its value represents log2(cores/cluster).
- * Default is 2**(2) = 4 cores per cluster.
+ * Default is 2**(4) = 16 cores per cluster.
  */
-#define PLATFORM_CPU_PER_CLUSTER_SHIFT	U(2)
-
+#define PLATFORM_CPU_PER_CLUSTER_SHIFT	U(4)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	(U(1) << PLATFORM_CPU_PER_CLUSTER_SHIFT)
 #define PLATFORM_CLUSTER_COUNT		U(2)
 #define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
 #define PLATFORM_CLUSTER1_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
@@ -245,8 +244,7 @@
  * interrupts.
  *****************************************************************************/
 #define PLATFORM_G1S_PROPS(grp)						\
-	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,	\
-					   grp, GIC_INTR_CFG_EDGE),	\
+	DESC_G1S_IRQ_SEC_SGI_0(grp)					\
 	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,	\
 					   grp, GIC_INTR_CFG_EDGE),	\
 	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,	\
@@ -262,7 +260,19 @@
 	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,	\
 					   grp, GIC_INTR_CFG_EDGE)
 
+#if SDEI_SUPPORT
+#define DESC_G0_IRQ_SEC_SGI(grp)					\
+	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \
+					   GIC_INTR_CFG_EDGE)
+#define DESC_G1S_IRQ_SEC_SGI_0(grp)
+#else
+#define DESC_G0_IRQ_SEC_SGI(grp)
+#define DESC_G1S_IRQ_SEC_SGI_0(grp)					\
+	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp),	\
+					   GIC_INTR_CFG_EDGE),
+#endif
+
-#define PLATFORM_G0_PROPS(grp)
+#define PLATFORM_G0_PROPS(grp)		DESC_G0_IRQ_SEC_SGI(grp)
 
 /*
  * DT related constants
@@ -271,6 +281,14 @@
 #define PLAT_QEMU_DT_MAX_SIZE		0x100000
 
 /*
+ * Platforms macros to support SDEI
+ */
+#define PLAT_PRI_BITS			U(3)
+#define PLAT_SDEI_CRITICAL_PRI		0x60
+#define PLAT_SDEI_NORMAL_PRI		0x70
+#define PLAT_SDEI_SGI_PRIVATE		QEMU_IRQ_SEC_SGI_0
+
+/*
  * System counter
  */
 #define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 4cbce9d..a10ab65 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,12 +12,23 @@
 # Qemu Cortex-A15 model does not implement the virtualization extension.
 # For this reason, we cannot set ARM_CORTEX_A15=yes and must define all
 # the ARMv7 build directives.
-MARCH32_DIRECTIVE 	:= 	-mcpu=cortex-a15
+MARCH_DIRECTIVE 	:= 	-mcpu=cortex-a15
 $(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
 $(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
 $(eval $(call add_define,ARMV7_SUPPORTS_VFP))
 # Qemu expects a BL32 boot stage.
 NEED_BL32		:=	yes
+else
+CTX_INCLUDE_AARCH32_REGS := 0
+ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1)
+$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled")
+endif
+
+# Treating this as a memory-constrained port for now
+USE_COHERENT_MEM	:=	0
+
+# This can be overridden depending on CPU(s) used in the QEMU image
+HW_ASSISTED_COHERENCY	:=	1
 endif # ARMv7
 
 ifeq (${SPD},opteed)
@@ -46,6 +57,18 @@
 
 ifeq (${ARM_ARCH_MAJOR},8)
 PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
+
+QEMU_CPU_LIBS		:=	lib/cpus/aarch64/aem_generic.S		\
+				lib/cpus/aarch64/cortex_a53.S		\
+				lib/cpus/aarch64/cortex_a57.S		\
+				lib/cpus/aarch64/cortex_a72.S		\
+				lib/cpus/aarch64/cortex_a76.S		\
+				lib/cpus/aarch64/neoverse_n_common.S	\
+				lib/cpus/aarch64/neoverse_n1.S		\
+				lib/cpus/aarch64/neoverse_v1.S		\
+				lib/cpus/aarch64/qemu_max.S
+else
+QEMU_CPU_LIBS		:=	lib/cpus/${ARCH}/cortex_a15.S
 endif
 
 PLAT_BL_COMMON_SOURCES	:=	${PLAT_QEMU_COMMON_PATH}/qemu_common.c			\
@@ -135,14 +158,15 @@
 				lib/semihosting/${ARCH}/semihosting_call.S \
 				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c		\
 				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c
+				${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c	\
+				${QEMU_CPU_LIBS}
 
 ifeq (${ARM_ARCH_MAJOR},8)
-BL1_SOURCES		+=	lib/cpus/aarch64/aem_generic.S		\
-				lib/cpus/aarch64/cortex_a53.S		\
-				lib/cpus/aarch64/cortex_a57.S		\
-				lib/cpus/aarch64/cortex_a72.S		\
-				lib/cpus/aarch64/qemu_max.S		\
+BL1_SOURCES		+=	lib/cpus/${ARCH}/aem_generic.S		\
+				lib/cpus/${ARCH}/cortex_a53.S		\
+				lib/cpus/${ARCH}/cortex_a57.S		\
+				lib/cpus/${ARCH}/cortex_a72.S		\
+				lib/cpus/${ARCH}/qemu_max.S		\
 
 else
 BL1_SOURCES		+=	lib/cpus/${ARCH}/cortex_a15.S
@@ -195,11 +219,7 @@
 endif
 
 ifeq (${ARM_ARCH_MAJOR},8)
-BL31_SOURCES		+=	lib/cpus/aarch64/aem_generic.S		\
-				lib/cpus/aarch64/cortex_a53.S		\
-				lib/cpus/aarch64/cortex_a57.S		\
-				lib/cpus/aarch64/cortex_a72.S		\
-				lib/cpus/aarch64/qemu_max.S		\
+BL31_SOURCES		+=	${QEMU_CPU_LIBS}			\
 				lib/semihosting/semihosting.c		\
 				lib/semihosting/${ARCH}/semihosting_call.S \
 				plat/common/plat_psci_common.c		\
@@ -211,6 +231,10 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c		\
 				${QEMU_GIC_SOURCES}
 
+ifeq (${SDEI_SUPPORT}, 1)
+BL31_SOURCES		+=	plat/qemu/common/qemu_sdei.c
+endif
+
 # Pointer Authentication sources
 ifeq (${ENABLE_PAUTH}, 1)
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c	\
@@ -282,8 +306,29 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# QEMU will use the RNDR instruction for the stack protector canary.
+ENABLE_FEAT_RNG			:= 2
+
 # Later QEMU versions support SME and SVE.
 ifneq (${ARCH},aarch32)
-	ENABLE_SVE_FOR_NS	:= 1
-	ENABLE_SME_FOR_NS	:= 1
+	ENABLE_SVE_FOR_NS	:= 2
+	ENABLE_SME_FOR_NS	:= 2
+endif
+
+qemu_fw.bios: bl1 fip
+	$(ECHO) "  DD      $@"
+	$(Q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
+	$(Q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
+
+qemu_fw.rom: qemu_fw.bios
+	$(ECHO) "  DD      $@"
+	$(Q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
+	$(Q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
+
+ifneq (${BL33},)
+all: qemu_fw.bios qemu_fw.rom
+endif
+
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES		+=	plat/common/aarch64/plat_ehf.c
 endif
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 2393b39..3dfefd0 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
 #
@@ -19,6 +19,11 @@
 # Enable new version of image loading on QEMU platforms
 LOAD_IMAGE_V2		:=	1
 
+CTX_INCLUDE_AARCH32_REGS := 0
+ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1)
+$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled")
+endif
+
 ifeq ($(NEED_BL32),yes)
 $(eval $(call add_define,QEMU_LOAD_BL32))
 endif
@@ -36,6 +41,19 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_console.c		\
 				drivers/arm/pl011/${ARCH}/pl011_console.S
 
+# Treating this as a memory-constrained port for now
+USE_COHERENT_MEM	:=	0
+
+# This can be overridden depending on CPU(s) used in the QEMU image
+HW_ASSISTED_COHERENCY	:=	1
+
+QEMU_CPU_LIBS		:=	lib/cpus/aarch64/cortex_a57.S			\
+				lib/cpus/aarch64/cortex_a72.S			\
+				lib/cpus/aarch64/neoverse_n_common.S		\
+				lib/cpus/aarch64/neoverse_n1.S			\
+				lib/cpus/aarch64/neoverse_v1.S			\
+				lib/cpus/aarch64/qemu_max.S
+
 include lib/xlat_tables_v2/xlat_tables.mk
 PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
 
@@ -49,9 +67,7 @@
 				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S	\
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c
 
-BL1_SOURCES		+=	lib/cpus/aarch64/cortex_a57.S			\
-				lib/cpus/aarch64/cortex_a72.S			\
-				lib/cpus/aarch64/qemu_max.S			\
+BL1_SOURCES		+=	${QEMU_CPU_LIBS}
 
 BL2_SOURCES		+=	drivers/io/io_semihosting.c			\
 				drivers/io/io_storage.c				\
@@ -74,16 +90,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		+=	lib/cpus/aarch64/cortex_a57.S			\
-				lib/cpus/aarch64/cortex_a72.S			\
-				lib/cpus/aarch64/qemu_max.S			\
+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	\
@@ -124,5 +139,8 @@
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
 # Later QEMU versions support SME and SVE.
-ENABLE_SVE_FOR_NS	:= 1
-ENABLE_SME_FOR_NS	:= 1
+ENABLE_SVE_FOR_NS	:= 2
+ENABLE_SME_FOR_NS	:= 2
+
+# QEMU 7.2+ has support for FGT and Linux needs it enabled to boot on max
+ENABLE_FEAT_FGT 	:= 2
diff --git a/plat/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..05ebec4
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -0,0 +1,186 @@
+/*
+ * 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)
+#define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
+
+static uint64_t gic_its_addr;
+
+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>;
+	 *       its {
+	 *               reg = <0x00 0x44081000 0x00 0x20000>;
+	 *       };
+	 * };
+	 */
+	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);
+
+	node = fdt_path_offset(dtb, "/intc/its");
+	if (node < 0) {
+		return;
+	}
+
+	err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICI reg property of GIC node\n");
+		return;
+	}
+	INFO("GICI base = 0x%lx\n", gic_its_addr);
+}
+
+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());
+
+	case SIP_SVC_GET_GIC_ITS:
+		SMC_RET2(handle, NULL, gic_its_addr);
+
+	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_bl31_setup.c b/plat/qti/common/src/qti_bl31_setup.c
index dac0253..a5f5858 100644
--- a/plat/qti/common/src/qti_bl31_setup.c
+++ b/plat/qti/common/src/qti_bl31_setup.c
@@ -81,7 +81,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this only intializes the mmu in a quick and dirty way.
+ * moment this only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index ae361e9..487a56e 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -24,6 +24,12 @@
 #define QTI_LOCAL_PSTATE_WIDTH		4
 #define QTI_LOCAL_PSTATE_MASK		((1 << QTI_LOCAL_PSTATE_WIDTH) - 1)
 
+#if PSCI_OS_INIT_MODE
+#define QTI_LAST_AT_PLVL_MASK		(QTI_LOCAL_PSTATE_MASK <<	\
+					 (QTI_LOCAL_PSTATE_WIDTH *	\
+					  (PLAT_MAX_PWR_LVL + 1)))
+#endif
+
 /* Make composite power state parameter till level 0 */
 #define qti_make_pwrstate_lvl0(lvl0_state, type) \
 		(((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT))
@@ -88,7 +94,12 @@
 	 *  search if the number of entries justify the additional complexity.
 	 */
 	for (i = 0; !!qti_pm_idle_states[i]; i++) {
+#if PSCI_OS_INIT_MODE
+		if ((power_state & ~QTI_LAST_AT_PLVL_MASK) ==
+		    qti_pm_idle_states[i])
+#else
 		if (power_state == qti_pm_idle_states[i])
+#endif
 			break;
 	}
 
@@ -100,11 +111,14 @@
 	state_id = psci_get_pstate_id(power_state);
 
 	/* Parse the State ID and populate the state info parameter */
-	while (state_id) {
-		req_state->pwr_domain_state[i++] = state_id &
+	for (i = QTI_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = state_id &
 		    QTI_LOCAL_PSTATE_MASK;
 		state_id >>= QTI_LOCAL_PSTATE_WIDTH;
 	}
+#if PSCI_OS_INIT_MODE
+	req_state->last_at_pwrlvl = state_id & QTI_LOCAL_PSTATE_MASK;
+#endif
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/qti/msm8916/aarch32/msm8916_helpers.S b/plat/qti/msm8916/aarch32/msm8916_helpers.S
new file mode 100644
index 0000000..ea39663
--- /dev/null
+++ b/plat/qti/msm8916/aarch32/msm8916_helpers.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <msm8916_mmap.h>
+
+#define APCS_TCM_START_ADDR	0x10
+#define APCS_TCM_REDIRECT_EN_0	BIT_32(0)
+
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+	.globl	plat_panic_handler
+	.globl	plat_my_core_pos
+	.globl	plat_get_my_entrypoint
+	.globl	plat_reset_handler
+	.globl	platform_mem_init
+	.globl	msm8916_entry_point
+
+	/* -------------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Initialize the crash console.
+	 * Out: r0 - 1 on success, 0 on error
+	 * Clobber list : r0 - r4
+	 * -------------------------------------------------
+	 */
+func plat_crash_console_init
+	ldr	r1, =BLSP_UART_BASE
+	mov	r0, #1
+	b	console_uartdm_core_init
+endfunc plat_crash_console_init
+
+	/* -------------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Print a character on the crash console.
+	 * In : r0 - character to be printed
+	 * Out: r0 - printed character on success
+	 * Clobber list : r1, r2
+	 * -------------------------------------------------
+	 */
+func plat_crash_console_putc
+	ldr	r1, =BLSP_UART_BASE
+	b	console_uartdm_core_putc
+endfunc plat_crash_console_putc
+
+	/* -------------------------------------------------
+	 * void plat_crash_console_flush(void)
+	 * Force a write of all buffered data that has not
+	 * been output.
+	 * Clobber list : r1, r2
+	 * -------------------------------------------------
+	 */
+func plat_crash_console_flush
+	ldr	r1, =BLSP_UART_BASE
+	b	console_uartdm_core_flush
+endfunc plat_crash_console_flush
+
+	/* -------------------------------------------------
+	 * void plat_panic_handler(void) __dead
+	 * Called when an unrecoverable error occurs.
+	 * -------------------------------------------------
+	 */
+func plat_panic_handler
+	/* Try to shutdown/reset */
+	ldr	r0, =MPM_PS_HOLD
+	mov	r1, #0
+	str	r1, [r0]
+1:	b	1b
+endfunc plat_panic_handler
+
+	/* -------------------------------------------------
+	 * unsigned int plat_my_core_pos(void)
+	 * Out: r0 - index of the calling CPU
+	 * -------------------------------------------------
+	 */
+func plat_my_core_pos
+	/* There is just a single cluster so this is very simple */
+	ldcopr	r0, MPIDR
+	and	r0, r0, #MPIDR_CPU_MASK
+	bx	lr
+endfunc plat_my_core_pos
+
+	/* -------------------------------------------------
+	 * uintptr_t plat_get_my_entrypoint(void)
+	 * Distinguish cold and warm boot and return warm boot
+	 * entry address if available.
+	 * Out: r0 - warm boot entry point or 0 on cold boot
+	 * -------------------------------------------------
+	 */
+func plat_get_my_entrypoint
+	ldr	r0, =msm8916_entry_point
+	ldr	r0, [r0]
+	cmp	r0, #0
+	bxne	lr
+
+	/*
+	 * Cold boot: Disable TCM redirect to L2 cache as early as
+	 * possible to avoid crashes when making use of the cache.
+	 */
+	ldr	r1, =APCS_CFG
+	ldr	r2, [r1, #APCS_TCM_START_ADDR]
+	and	r2, r2, #~APCS_TCM_REDIRECT_EN_0
+	str	r2, [r1, #APCS_TCM_START_ADDR]
+	bx	lr
+endfunc plat_get_my_entrypoint
+
+	/* -------------------------------------------------
+	 * void platform_mem_init(void)
+	 * Performs additional memory initialization early
+	 * in the boot process.
+	 * -------------------------------------------------
+	 */
+func platform_mem_init
+	/* Nothing to do here, all memory is already initialized */
+	bx	lr
+endfunc platform_mem_init
+
+	.data
+	.align	3
+
+	/* -------------------------------------------------
+	 * Warm boot entry point for CPU. Set by PSCI code.
+	 * -------------------------------------------------
+	 */
+msm8916_entry_point:
+	.word	0
diff --git a/plat/qti/msm8916/aarch32/uartdm_console.S b/plat/qti/msm8916/aarch32/uartdm_console.S
new file mode 100644
index 0000000..a19776a
--- /dev/null
+++ b/plat/qti/msm8916/aarch32/uartdm_console.S
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * Based on aarch32/skeleton_console.S:
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <console_macros.S>
+
+/* UART DM registers */
+#define UART_DM_DMEN		0x03c		/* DMA / data packing */
+#define UART_DM_SR		0x0a4		/* status register */
+#define UART_DM_CR		0x0a8		/* command register */
+#define UART_DM_TF		0x100		/* transmit FIFO */
+
+#define UART_DM_DMEN_TX_SC	BIT_32(4)	/* TX single character mode */
+
+#define UART_DM_SR_TXRDY	BIT_32(2)	/* TX FIFO has space */
+#define UART_DM_SR_TXEMT	BIT_32(3)	/* TX FIFO is empty */
+
+#define UART_DM_CR_RESET_RX	(U(0x01) << 4)	/* reset receiver */
+#define UART_DM_CR_RESET_TX	(U(0x02) << 4)	/* reset transmitter */
+#define UART_DM_CR_TX_ENABLE	BIT_32(2)	/* enable transmitter */
+
+	.globl	console_uartdm_register
+	.globl	console_uartdm_core_init
+	.globl	console_uartdm_putc
+	.globl	console_uartdm_core_putc
+	.globl	console_uartdm_flush
+	.globl	console_uartdm_core_flush
+
+	/* -----------------------------------------------------------
+	 * int console_uartdm_register(console_t *console,
+	 * 	uintptr_t base_addr)
+	 * Function to initialize and register the console. The caller
+	 * needs to pass an empty console_t structure in which *MUST*
+	 * be allocated in persistent memory (e.g. a global or static
+	 * local variable, *NOT* on the stack).
+	 * In : r0 - pointer to empty console_t structure
+	 *      r1 - base address
+	 * Out: r0 - 1 on success, 0 on error
+	 * Clobber list : r0 - r7
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_register
+	str	r1, [r0, #CONSOLE_T_BASE]
+	mov	r7, lr
+	bl	console_uartdm_core_init
+	mov	lr, r7
+
+	/* Register the new console */
+	finish_console_register uartdm putc=1, flush=1
+endfunc console_uartdm_register
+
+	/* -----------------------------------------------------------
+	 * void console_uartdm_core_init(unused, uintptr_t base_addr)
+	 * Function to initialize the console.
+	 * In : r0 - unused
+	 *      r1 - base address
+	 * Out: void
+	 * Clobber list : r1, r2, r3
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_core_init
+	/*
+	 * Try to flush remaining characters from the TX FIFO before resetting
+	 * the transmitter. Unfortunately there is no good way to check if
+	 * the transmitter is actually enabled (and will finish eventually),
+	 * so use a timeout to avoid looping forever.
+	 */
+	mov	r2, #65536
+1:
+	ldr	r3, [r1, #UART_DM_SR]
+	tst	r3, #UART_DM_SR_TXEMT
+	bne	2f
+	subs	r2, r2, #1
+	bne	1b
+	/* Timeout */
+
+2:	/* Reset receiver */
+	mov	r3, #UART_DM_CR_RESET_RX
+	str	r3, [r1, #UART_DM_CR]
+
+	/* Reset transmitter */
+	mov	r3, #UART_DM_CR_RESET_TX
+	str	r3, [r1, #UART_DM_CR]
+
+	/*
+	 * Disable BAM/DMA modes but enable single-character mode for TX.
+	 * The single character mode allows simplifying the putc implementation
+	 * since characters can be written directly to the FIFO instead of
+	 * having to initiate a new transfer and waiting for its completion.
+	 */
+	mov	r3, #UART_DM_DMEN_TX_SC
+	str	r3, [r1, #UART_DM_DMEN]
+
+	/* Enable transmitter */
+	mov	r3, #UART_DM_CR_TX_ENABLE
+	str	r3, [r1, #UART_DM_CR]
+
+	bx	lr
+endfunc console_uartdm_core_init
+
+	/* -----------------------------------------------------------
+	 * int console_uartdm_putc(int c, console_t *console)
+	 * Function to output a character over the console.
+	 * In : r0 - character to be printed
+	 *      r1 - pointer to console_t struct
+	 * Out: r0 - printed character on success, < 0 on error.
+	 * Clobber list : r0, r1, r2
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_putc
+	ldr	r1, [r1, #CONSOLE_T_BASE]
+	b	console_uartdm_core_putc
+endfunc console_uartdm_putc
+
+	/* -----------------------------------------------------------
+	 * int console_uartdm_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console.
+	 * In : r0 - character to be printed
+	 *      r1 - base address
+	 * Out: r0 - printed character on success, < 0 on error.
+	 * Clobber list : r2
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_core_putc
+	cmp	r0, #'\n'
+	bne	2f
+
+1:	/* Loop until TX FIFO has space */
+	ldr	r2, [r1, #UART_DM_SR]
+	tst	r2, #UART_DM_SR_TXRDY
+	beq	1b
+
+	/* Prepend '\r' to '\n' */
+	mov	r2, #'\r'
+	str	r2, [r1, #UART_DM_TF]
+
+2:	/* Loop until TX FIFO has space */
+	ldr	r2, [r1, #UART_DM_SR]
+	tst	r2, #UART_DM_SR_TXRDY
+	beq	2b
+
+	/* Write character to FIFO */
+	str	r0, [r1, #UART_DM_TF]
+	bx	lr
+endfunc console_uartdm_core_putc
+
+	/* -----------------------------------------------------------
+	 * void console_uartdm_flush(console_t *console)
+	 * Function to force a write of all buffered data
+	 * that has not been output.
+	 * In : r0 - pointer to console_t struct
+	 * Out: void
+	 * Clobber list : r0, r1, r2, r3, r4, r5
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_flush
+	ldr	r1, [r0, #CONSOLE_T_BASE]
+	b	console_uartdm_core_flush
+endfunc console_uartdm_flush
+
+	/* -----------------------------------------------------------
+	 * void console_uartdm_core_flush(unused, uintptr_t base_addr)
+	 * Function to force a write of all buffered data
+	 * that has not been output.
+	 * In : r0 - unused
+	 *      r1 - base address
+	 * Out: void
+	 * Clobber list : r2
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_core_flush
+1:	/* Loop until TX FIFO is empty */
+	ldr	r2, [r1, #UART_DM_SR]
+	tst	r2, #UART_DM_SR_TXEMT
+	beq	1b
+	bx	lr
+endfunc console_uartdm_core_flush
diff --git a/plat/qti/msm8916/aarch64/msm8916_helpers.S b/plat/qti/msm8916/aarch64/msm8916_helpers.S
index dad9968..bccc5e5 100644
--- a/plat/qti/msm8916/aarch64/msm8916_helpers.S
+++ b/plat/qti/msm8916/aarch64/msm8916_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,18 +30,7 @@
 	 * -------------------------------------------------
 	 */
 func plat_crash_console_init
-	mov	x1, #BLSP_UART2_BASE
-
-	/*
-	 * If the non-secure world has been actively using the UART there might
-	 * be still some characters left to be sent in the FIFO. In that case,
-	 * resetting the transmitter too early might cause all output to become
-	 * corrupted. To avoid that, try to flush (wait until FIFO empty) first.
-	 */
-	mov	x4, lr
-	bl	console_uartdm_core_flush
-	mov	lr, x4
-
+	mov_imm	x1, BLSP_UART_BASE
 	mov	x0, #1
 	b	console_uartdm_core_init
 endfunc plat_crash_console_init
@@ -55,7 +44,7 @@
 	 * -------------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov	x1, #BLSP_UART2_BASE
+	mov_imm	x1, BLSP_UART_BASE
 	b	console_uartdm_core_putc
 endfunc plat_crash_console_putc
 
@@ -67,7 +56,7 @@
 	 * -------------------------------------------------
 	 */
 func plat_crash_console_flush
-	mov	x1, #BLSP_UART2_BASE
+	mov_imm	x1, BLSP_UART_BASE
 	b	console_uartdm_core_flush
 endfunc plat_crash_console_flush
 
@@ -104,43 +93,42 @@
 	 */
 func plat_get_my_entrypoint
 	ldr	x0, msm8916_entry_point
+	cbz	x0, 1f
 	ret
-endfunc plat_get_my_entrypoint
-
-	/* -------------------------------------------------
-	 * void plat_reset_handler(void)
-	 * Perform additional initialization after reset.
-	 * Clobber list : x0 - x18, x30
-	 * -------------------------------------------------
+1:
+	/*
+	 * Cold boot: Disable TCM redirect to L2 cache as early as
+	 * possible to avoid crashes when making use of the cache.
 	 */
-func plat_reset_handler
+	mov_imm	x1, APCS_CFG
+	ldr	w2, [x1, #APCS_TCM_START_ADDR]
+	and	w2, w2, #~APCS_TCM_REDIRECT_EN_0
+	str	w2, [x1, #APCS_TCM_START_ADDR]
+
 	/*
-	 * Check if the CPU is running at the correct address.
-	 * During cold boot the CPU enters here at the wrong address
-	 * using the "boot remapper". (It remaps the BL31_BASE to
-	 * the CPU reset address 0x0).
+	 * After reset the CPU always starts executing at the fixed reset
+	 * address (0x0), which does not match the link address of BL31.
+	 * The "boot remapper" redirects all memory accesses to the real
+	 * physical address in DRAM.
+	 *
+	 * For warm boots, this is already handled by loading the real
+	 * entry point address above.
+	 *
+	 * For cold boots, check if the CPU is using the boot remapper,
+	 * i.e. if bl31_entrypoint appears to be at the reset address (0x0).
 	 */
-	mov	x0, #BL31_BASE
 	adr	x1, bl31_entrypoint
-	cmp	x0, x1
-	b.ne	_remapped_cold_boot
-	/* Already running at correct address, just return directly */
-	ret
+	cbnz	x1, 2f
 
-_remapped_cold_boot:
 	/*
-	 * The previous boot stage seems to use the L2 cache as TCM.
-	 * Disable the TCM redirect before enabling caches to avoid
-	 * strange crashes.
+	 * Add the real BL31_BASE offset to the return address in the link
+	 * register so the CPU will continue at the real address after return.
 	 */
-	mov	x2, #APCS_CFG
-	ldr	w3, [x2, #APCS_TCM_START_ADDR]
-	and	w3, w3, #~APCS_TCM_REDIRECT_EN_0
-	str	w3, [x2, #APCS_TCM_START_ADDR]
-
-	/* Enter BL31 again at the real address */
-	br	x0
-endfunc plat_reset_handler
+	mov_imm	x1, BL31_BASE
+	add	lr, lr, x1
+2:
+	ret
+endfunc plat_get_my_entrypoint
 
 	/* -------------------------------------------------
 	 * void platform_mem_init(void)
diff --git a/plat/qti/msm8916/aarch64/uartdm_console.S b/plat/qti/msm8916/aarch64/uartdm_console.S
index c69c193..6c65daf 100644
--- a/plat/qti/msm8916/aarch64/uartdm_console.S
+++ b/plat/qti/msm8916/aarch64/uartdm_console.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * Based on aarch64/skeleton_console.S:
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
@@ -65,7 +65,21 @@
 	 * -----------------------------------------------------------
 	 */
 func console_uartdm_core_init
-	/* Reset receiver */
+	/*
+	 * Try to flush remaining characters from the TX FIFO before resetting
+	 * the transmitter. Unfortunately there is no good way to check if
+	 * the transmitter is actually enabled (and will finish eventually),
+	 * so use a timeout to avoid looping forever.
+	 */
+	mov	w2, #65536
+1:
+	ldr	w3, [x1, #UART_DM_SR]
+	tbnz	w3, #UART_DM_SR_TXEMT_BIT, 2f
+	subs	w2, w2, #1
+	b.ne	1b
+	/* Timeout */
+
+2:	/* Reset receiver */
 	mov	w3, #UART_DM_CR_RESET_RX
 	str	w3, [x1, #UART_DM_CR]
 
@@ -113,10 +127,21 @@
 	 * -----------------------------------------------------------
 	 */
 func console_uartdm_core_putc
+	cmp	w0, #'\n'
+	b.ne	2f
+
 1:	/* Loop until TX FIFO has space */
 	ldr	w2, [x1, #UART_DM_SR]
 	tbz	w2, #UART_DM_SR_TXRDY_BIT, 1b
 
+	/* Prepend '\r' to '\n' */
+	mov	w2, #'\r'
+	str	w2, [x1, #UART_DM_TF]
+
+2:	/* Loop until TX FIFO has space */
+	ldr	w2, [x1, #UART_DM_SR]
+	tbz	w2, #UART_DM_SR_TXRDY_BIT, 2b
+
 	/* Write character to FIFO */
 	str	w0, [x1, #UART_DM_TF]
 	ret
diff --git a/plat/qti/msm8916/include/msm8916_mmap.h b/plat/qti/msm8916/include/msm8916_mmap.h
index 406ae6b..35e3b86 100644
--- a/plat/qti/msm8916/include/msm8916_mmap.h
+++ b/plat/qti/msm8916/include/msm8916_mmap.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,9 +8,9 @@
 #define MSM8916_MMAP_H
 
 #define PCNOC_BASE		0x00000000
-#define PCNOC_SIZE		0x8000000	/* 128 MiB */
+#define PCNOC_SIZE		SZ_128M
 #define APCS_BASE		0x0b000000
-#define APCS_SIZE		0x800000	/* 8 MiB */
+#define APCS_SIZE		SZ_8M
 
 #define MPM_BASE		(PCNOC_BASE + 0x04a0000)
 #define MPM_PS_HOLD		(MPM_BASE + 0xb000)
@@ -23,8 +23,9 @@
 #define APPS_SMMU_BASE		(PCNOC_BASE + 0x1e00000)
 #define APPS_SMMU_QCOM		(APPS_SMMU_BASE + 0xf0000)
 
-#define BLSP_UART1_BASE		(PCNOC_BASE + 0x78af000)
-#define BLSP_UART2_BASE		(PCNOC_BASE + 0x78b0000)
+#define BLSP1_BASE		(PCNOC_BASE + 0x7880000)
+#define BLSP1_UART_BASE(n)	(BLSP1_BASE + 0x2f000 + (((n) - 1) * 0x1000))
+#define BLSP_UART_BASE		BLSP1_UART_BASE(QTI_UART_NUM)
 
 #define APCS_QGIC2_BASE		(APCS_BASE + 0x00000)
 #define APCS_QGIC2_GICD		(APCS_QGIC2_BASE + 0x0000)
diff --git a/plat/qti/msm8916/include/platform_def.h b/plat/qti/msm8916/include/platform_def.h
index bfade70..f6ba1cc 100644
--- a/plat/qti/msm8916/include/platform_def.h
+++ b/plat/qti/msm8916/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <plat/common/common_def.h>
 
+#ifdef __aarch64__
 /*
  * There is at least 1 MiB available for BL31. However, at the moment the
  * "msm8916_entry_point" variable in the data section is read through the
@@ -16,11 +17,13 @@
  * the overall limit to 128 KiB. This could be increased if needed by placing
  * the "msm8916_entry_point" variable explicitly in the first 64 KiB of BL31.
  */
-#define BL31_LIMIT			(BL31_BASE + 0x20000)	/* 128 KiB */
-#define BL31_PROGBITS_LIMIT		(BL31_BASE + 0x10000)	/* 64 KiB */
+#define BL31_LIMIT			(BL31_BASE + SZ_128K)
+#define BL31_PROGBITS_LIMIT		(BL31_BASE + SZ_64K)
+#endif
+#define BL32_LIMIT			(BL32_BASE + SZ_128K)
 
 #define CACHE_WRITEBACK_GRANULE		U(64)
-#define PLATFORM_STACK_SIZE		U(0x1000)
+#define PLATFORM_STACK_SIZE		SZ_4K
 
 /* CPU topology: single cluster with 4 cores */
 #define PLATFORM_CLUSTER_COUNT		U(1)
@@ -44,8 +47,9 @@
 #define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
 
-/* Timer frequency */
+/* Timer */
 #define PLAT_SYSCNT_FREQ		19200000
+#define IRQ_SEC_PHY_TIMER		(16 + 2)	/* PPI #2 */
 
 /*
  * The Qualcomm QGIC2 implementation seems to have PIDR0-4 and PIDR4-7
@@ -54,4 +58,9 @@
  */
 #define GICD_PIDR2_GICV2		U(0xFD8)
 
+/* TSP */
+#define TSP_IRQ_SEC_PHY_TIMER		IRQ_SEC_PHY_TIMER
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/msm8916/msm8916_bl31_setup.c b/plat/qti/msm8916/msm8916_bl31_setup.c
index 638cd09..449be7f 100644
--- a/plat/qti/msm8916/msm8916_bl31_setup.c
+++ b/plat/qti/msm8916/msm8916_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,25 +8,10 @@
 
 #include <arch.h>
 #include <common/debug.h>
-#include <drivers/console.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_mmu_helpers.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
-#include "msm8916_gicv2.h"
-#include <msm8916_mmap.h>
-#include <platform_def.h>
-#include <uartdm_console.h>
-
-static const mmap_region_t msm8916_mmap[] = {
-	MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
-	MAP_REGION_FLAT(APCS_BASE, APCS_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
-	{},
-};
+#include "msm8916_config.h"
+#include "msm8916_setup.h"
 
 static struct {
 	entry_point_info_t bl32;
@@ -44,164 +29,23 @@
 	.bl33.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
 };
 
-static console_t console;
-
-unsigned int plat_get_syscnt_freq2(void)
-{
-	return PLAT_SYSCNT_FREQ;
-}
-
-#define CLK_ENABLE			BIT_32(0)
-#define CLK_OFF				BIT_32(31)
-
-#define GPIO_BLSP_UART2_TX		4
-#define GPIO_BLSP_UART2_RX		5
-#define GPIO_CFG_FUNC_BLSP_UART2	(U(0x2) << 2)
-#define GPIO_CFG_DRV_STRENGTH_16MA	(U(0x7) << 6)
-
-#define GCC_BLSP1_AHB_CBCR		(GCC_BASE + 0x01008)
-#define GCC_BLSP1_UART2_APPS_CBCR	(GCC_BASE + 0x0302c)
-#define GCC_APCS_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x45004)
-#define BLSP1_AHB_CLK_ENA		BIT_32(10)
-
-/*
- * The previous boot stage seems to disable most of the UART setup before exit
- * so it must be enabled here again before the UART console can be used.
- */
-static void msm8916_enable_blsp_uart2(void)
-{
-	/* Route GPIOs to BLSP UART2 */
-	mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_TX),
-		      GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
-	mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_RX),
-		      GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
-
-	/* Enable AHB clock */
-	mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
-	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
-		;
-
-	/* Enable BLSP UART2 clock */
-	mmio_setbits_32(GCC_BLSP1_UART2_APPS_CBCR, CLK_ENABLE);
-	while (mmio_read_32(GCC_BLSP1_UART2_APPS_CBCR) & CLK_OFF)
-		;
-}
-
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	/* Initialize the debug console as early as possible */
-	msm8916_enable_blsp_uart2();
-	console_uartdm_register(&console, BLSP_UART2_BASE);
+	msm8916_early_platform_setup();
 }
 
 void bl31_plat_arch_setup(void)
 {
-	mmap_add_region(BL31_BASE, BL31_BASE, BL31_END - BL31_BASE,
-			MT_RW_DATA | MT_SECURE);
-	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
-			BL_CODE_END - BL_CODE_BASE,
-			MT_CODE | MT_SECURE);
-	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
-			BL_RO_DATA_END - BL_RO_DATA_BASE,
-			MT_RO_DATA | MT_SECURE);
-	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
-			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
-			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
-
-	mmap_add(msm8916_mmap);
-	init_xlat_tables();
+	msm8916_plat_arch_setup(BL31_BASE, BL31_END - BL31_BASE);
 	enable_mmu_el3(0);
 }
 
-static void msm8916_configure_timer(void)
-{
-	/* Set timer frequency */
-	mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, plat_get_syscnt_freq2());
-
-	/* Make frame 0 available to non-secure world */
-	mmio_write_32(APCS_QTMR + CNTNSAR, BIT_32(CNTNSAR_NS_SHIFT(0)));
-	mmio_write_32(APCS_QTMR + CNTACR_BASE(0),
-		      BIT_32(CNTACR_RPCT_SHIFT) | BIT_32(CNTACR_RVCT_SHIFT) |
-		      BIT_32(CNTACR_RFRQ_SHIFT) | BIT_32(CNTACR_RVOFF_SHIFT) |
-		      BIT_32(CNTACR_RWVT_SHIFT) | BIT_32(CNTACR_RWPT_SHIFT));
-}
-
-/*
- * The APCS register regions always start with a SECURE register that should
- * be cleared to 0 to only allow secure access. Since BL31 handles most of
- * the CPU power management, most of them can be cleared to secure access only.
- */
-#define APCS_GLB_SECURE_STS_NS		BIT_32(0)
-#define APCS_GLB_SECURE_PWR_NS		BIT_32(1)
-#define APCS_BOOT_START_ADDR_SEC	(APCS_CFG + 0x04)
-#define REMAP_EN			BIT_32(0)
-#define APCS_AA64NAA32_REG		(APCS_CFG + 0x0c)
-
-static void msm8916_configure_cpu_pm(void)
-{
-	unsigned int cpu;
-
-	/* Disallow non-secure access to boot remapper / TCM registers */
-	mmio_write_32(APCS_CFG, 0);
-
-	/*
-	 * Disallow non-secure access to power management registers.
-	 * However, allow STS and PWR since those also seem to control access
-	 * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
-	 * bits are not set, CPU frequency control fails in the non-secure world.
-	 */
-	mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
-
-	/* Disallow non-secure access to L2 SAW2 */
-	mmio_write_32(APCS_L2_SAW2, 0);
-
-	/* Disallow non-secure access to CPU ACS and SAW2 */
-	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
-		mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
-		mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
-	}
-
-	/* Make sure all further warm boots end up in BL31 and aarch64 state */
-	CASSERT((BL31_BASE & 0xffff) == 0, assert_bl31_base_64k_aligned);
-	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
-	mmio_write_32(APCS_AA64NAA32_REG, 1);
-}
-
-/*
- * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
- * which allows routing context bank interrupts to one of 3 interrupt numbers
- * ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number
- * by default to avoid special setup on the non-secure side.
- */
-#define GCC_SMMU_CFG_CBCR			(GCC_BASE + 0x12038)
-#define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x4500c)
-#define SMMU_CFG_CLK_ENA			BIT_32(12)
-#define APPS_SMMU_INTR_SEL_NS			(APPS_SMMU_QCOM + 0x2000)
-#define APPS_SMMU_INTR_SEL_NS_EN_ALL		U(0xffffffff)
-
-static void msm8916_configure_smmu(void)
-{
-	/* Enable SMMU configuration clock to enable register access */
-	mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
-	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
-		;
-
-	/* Route all context bank interrupts to non-secure interrupt */
-	mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
-
-	/* Disable configuration clock again */
-	mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
-}
-
 void bl31_platform_setup(void)
 {
 	INFO("BL31: Platform setup start\n");
-	generic_delay_timer_init();
-	msm8916_configure_timer();
-	msm8916_gicv2_init();
-	msm8916_configure_cpu_pm();
-	msm8916_configure_smmu();
+	msm8916_platform_setup();
+	msm8916_configure();
 	INFO("BL31: Platform setup done\n");
 }
 
diff --git a/plat/qti/msm8916/msm8916_config.c b/plat/qti/msm8916/msm8916_config.c
new file mode 100644
index 0000000..350ed5c
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_config.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <lib/mmio.h>
+
+#include "msm8916_config.h"
+#include "msm8916_gicv2.h"
+#include <msm8916_mmap.h>
+#include <platform_def.h>
+
+static void msm8916_configure_timer(void)
+{
+	/* Set timer frequency */
+	mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, PLAT_SYSCNT_FREQ);
+
+	/* Make all timer frames available to non-secure world */
+	mmio_write_32(APCS_QTMR + CNTNSAR, GENMASK_32(7, 0));
+}
+
+/*
+ * The APCS register regions always start with a SECURE register that should
+ * be cleared to 0 to only allow secure access. Since BL31 handles most of
+ * the CPU power management, most of them can be cleared to secure access only.
+ */
+#define APCS_GLB_SECURE_STS_NS		BIT_32(0)
+#define APCS_GLB_SECURE_PWR_NS		BIT_32(1)
+#define APCS_BOOT_START_ADDR_SEC	(APCS_CFG + 0x04)
+#define REMAP_EN			BIT_32(0)
+#define APCS_AA64NAA32_REG		(APCS_CFG + 0x0c)
+
+static void msm8916_configure_cpu_pm(void)
+{
+	unsigned int cpu;
+
+	/* Disallow non-secure access to boot remapper / TCM registers */
+	mmio_write_32(APCS_CFG, 0);
+
+	/*
+	 * Disallow non-secure access to power management registers.
+	 * However, allow STS and PWR since those also seem to control access
+	 * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
+	 * bits are not set, CPU frequency control fails in the non-secure world.
+	 */
+	mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
+
+	/* Disallow non-secure access to L2 SAW2 */
+	mmio_write_32(APCS_L2_SAW2, 0);
+
+	/* Disallow non-secure access to CPU ACS and SAW2 */
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+		mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
+		mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
+	}
+
+#ifdef __aarch64__
+	/* Make sure all further warm boots end up in BL31 and aarch64 state */
+	CASSERT((BL31_BASE & 0xffff) == 0, assert_bl31_base_64k_aligned);
+	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
+	mmio_write_32(APCS_AA64NAA32_REG, 1);
+#else
+	/* Make sure all further warm boots end up in BL32 */
+	CASSERT((BL32_BASE & 0xffff) == 0, assert_bl32_base_64k_aligned);
+	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL32_BASE | REMAP_EN);
+#endif
+}
+
+/*
+ * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
+ * which allows routing context bank interrupts to one of 3 interrupt numbers
+ * ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number
+ * by default to avoid special setup on the non-secure side.
+ */
+#define CLK_OFF					BIT_32(31)
+#define GCC_SMMU_CFG_CBCR			(GCC_BASE + 0x12038)
+#define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x4500c)
+#define SMMU_CFG_CLK_ENA			BIT_32(12)
+#define APPS_SMMU_INTR_SEL_NS			(APPS_SMMU_QCOM + 0x2000)
+#define APPS_SMMU_INTR_SEL_NS_EN_ALL		U(0xffffffff)
+
+static void msm8916_configure_smmu(void)
+{
+	/* Enable SMMU configuration clock to enable register access */
+	mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
+	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
+		;
+
+	/* Route all context bank interrupts to non-secure interrupt */
+	mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
+
+	/* Disable configuration clock again */
+	mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
+}
+
+void msm8916_configure(void)
+{
+	msm8916_gicv2_configure();
+	msm8916_configure_timer();
+	msm8916_configure_cpu_pm();
+	msm8916_configure_smmu();
+}
diff --git a/plat/qti/msm8916/msm8916_config.h b/plat/qti/msm8916/msm8916_config.h
new file mode 100644
index 0000000..992625b
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_config.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MSM8916_CONFIG_H
+#define MSM8916_CONFIG_H
+
+void msm8916_configure(void);
+
+#endif /* MSM8916_CONFIG_H */
diff --git a/plat/qti/msm8916/msm8916_gicv2.c b/plat/qti/msm8916/msm8916_gicv2.c
index 25a6628..82cecf2 100644
--- a/plat/qti/msm8916/msm8916_gicv2.c
+++ b/plat/qti/msm8916/msm8916_gicv2.c
@@ -10,6 +10,7 @@
 
 #include "msm8916_gicv2.h"
 #include <msm8916_mmap.h>
+#include <platform_def.h>
 
 #define IRQ_SEC_SGI_0		8
 #define IRQ_SEC_SGI_1		9
@@ -20,8 +21,6 @@
 #define IRQ_SEC_SGI_6		14
 #define IRQ_SEC_SGI_7		15
 
-#define IRQ_SEC_PHY_TIMER	(16 + 2)	/* PPI #2 */
-
 static const interrupt_prop_t msm8916_interrupt_props[] = {
 	INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
 		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
@@ -53,6 +52,10 @@
 void msm8916_gicv2_init(void)
 {
 	gicv2_driver_init(&msm8916_gic_data);
+}
+
+void msm8916_gicv2_configure(void)
+{
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
diff --git a/plat/qti/msm8916/msm8916_gicv2.h b/plat/qti/msm8916/msm8916_gicv2.h
index 99db0d3..919e294 100644
--- a/plat/qti/msm8916/msm8916_gicv2.h
+++ b/plat/qti/msm8916/msm8916_gicv2.h
@@ -8,5 +8,6 @@
 #define MSM8916_GICV2_H
 
 void msm8916_gicv2_init(void);
+void msm8916_gicv2_configure(void);
 
 #endif /* MSM8916_GICV2_H */
diff --git a/plat/qti/msm8916/msm8916_pm.c b/plat/qti/msm8916/msm8916_pm.c
index 6891e38..792a096 100644
--- a/plat/qti/msm8916/msm8916_pm.c
+++ b/plat/qti/msm8916/msm8916_pm.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2022, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch.h>
+#include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/delay_timer.h>
@@ -53,7 +54,14 @@
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const plat_psci_ops_t **psci_ops)
 {
+	/*
+	 * The entry point is read with caches off (and even from two different
+	 * physical addresses when read through the "boot remapper"), so make
+	 * sure it is flushed to memory.
+	 */
 	msm8916_entry_point = sec_entrypoint;
+	flush_dcache_range((uintptr_t)&msm8916_entry_point, sizeof(uintptr_t));
+
 	*psci_ops = &msm8916_psci_ops;
 	return 0;
 }
diff --git a/plat/qti/msm8916/msm8916_setup.c b/plat/qti/msm8916/msm8916_setup.c
new file mode 100644
index 0000000..26039a9
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_setup.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "msm8916_gicv2.h"
+#include <msm8916_mmap.h>
+#include "msm8916_setup.h"
+#include <uartdm_console.h>
+
+static const mmap_region_t msm8916_mmap[] = {
+	MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
+	MAP_REGION_FLAT(APCS_BASE, APCS_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
+	{},
+};
+
+static console_t console;
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return PLAT_SYSCNT_FREQ;
+}
+
+#define GPIO_CFG_FUNC(n)		((n) << 2)
+#define GPIO_CFG_DRV_STRENGTH_MA(ma)	(((ma) / 2 - 1) << 6)
+
+#define CLK_ENABLE			BIT_32(0)
+#define CLK_OFF				BIT_32(31)
+#define GCC_BLSP1_AHB_CBCR		(GCC_BASE + 0x01008)
+#define GCC_BLSP1_UART_APPS_CBCR(n)	(GCC_BASE + \
+	(((n) == 2) ? (0x0302c) : (0x0203c + (((n) - 1) * 0x1000))))
+#define GCC_APCS_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x45004)
+#define BLSP1_AHB_CLK_ENA		BIT_32(10)
+
+struct uartdm_gpios {
+	unsigned int tx, rx, func;
+};
+
+static const struct uartdm_gpios uartdm_gpio_map[] = {
+	{0, 1, 0x2}, {4, 5, 0x2},
+};
+
+/*
+ * The previous boot stage seems to disable most of the UART setup before exit
+ * so it must be enabled here again before the UART console can be used.
+ */
+static void msm8916_enable_blsp_uart(void)
+{
+	const struct uartdm_gpios *gpios = &uartdm_gpio_map[QTI_UART_NUM - 1];
+
+	CASSERT(QTI_UART_NUM > 0 && QTI_UART_NUM <= ARRAY_SIZE(uartdm_gpio_map),
+		assert_qti_blsp_uart_valid);
+
+	/* Route GPIOs to BLSP UART */
+	mmio_write_32(TLMM_GPIO_CFG(gpios->tx), GPIO_CFG_FUNC(gpios->func) |
+		      GPIO_CFG_DRV_STRENGTH_MA(8));
+	mmio_write_32(TLMM_GPIO_CFG(gpios->rx), GPIO_CFG_FUNC(gpios->func) |
+		      GPIO_CFG_DRV_STRENGTH_MA(8));
+
+	/* Enable AHB clock */
+	mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
+	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
+		;
+
+	/* Enable BLSP UART clock */
+	mmio_setbits_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM), CLK_ENABLE);
+	while (mmio_read_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM)) & CLK_OFF)
+		;
+}
+
+void msm8916_early_platform_setup(void)
+{
+	/* Initialize the debug console as early as possible */
+	msm8916_enable_blsp_uart();
+	console_uartdm_register(&console, BLSP_UART_BASE);
+
+	if (QTI_RUNTIME_UART) {
+		/* Mark UART as runtime usable */
+		console_set_scope(&console, CONSOLE_FLAG_BOOT |
+				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
+}
+
+void msm8916_plat_arch_setup(uintptr_t base, size_t size)
+{
+	mmap_add_region(base, base, size, MT_RW_DATA | MT_SECURE);
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
+			BL_RO_DATA_END - BL_RO_DATA_BASE,
+			MT_RO_DATA | MT_SECURE);
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
+
+	mmap_add(msm8916_mmap);
+	init_xlat_tables();
+}
+
+void msm8916_platform_setup(void)
+{
+	generic_delay_timer_init();
+	msm8916_gicv2_init();
+}
diff --git a/plat/qti/msm8916/msm8916_setup.h b/plat/qti/msm8916/msm8916_setup.h
new file mode 100644
index 0000000..d2de943
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_setup.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MSM8916_SETUP_H
+#define MSM8916_SETUP_H
+
+void msm8916_early_platform_setup(void);
+void msm8916_plat_arch_setup(uintptr_t base, size_t size);
+void msm8916_platform_setup(void);
+
+#endif /* MSM8916_SETUP_H */
diff --git a/plat/qti/msm8916/platform.mk b/plat/qti/msm8916/platform.mk
index e516cea..7e698fb 100644
--- a/plat/qti/msm8916/platform.mk
+++ b/plat/qti/msm8916/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+# Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,35 +7,37 @@
 include drivers/arm/gic/v2/gicv2.mk
 include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_BL_COMMON_SOURCES	:= ${XLAT_TABLES_LIB_SRCS}
+PLAT_BL_COMMON_SOURCES	:=	${GICV2_SOURCES}				\
+				${XLAT_TABLES_LIB_SRCS}				\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				plat/common/plat_gicv2.c			\
+				plat/qti/msm8916/msm8916_gicv2.c		\
+				plat/qti/msm8916/msm8916_setup.c		\
+				plat/qti/msm8916/${ARCH}/msm8916_helpers.S	\
+				plat/qti/msm8916/${ARCH}/uartdm_console.S
 
-PLAT_INCLUDES	:=	-Iinclude/plat/arm/common/${ARCH}		\
-			-Iplat/qti/msm8916/include
+MSM8916_PM_SOURCES	:=	lib/cpus/${ARCH}/cortex_a53.S			\
+				plat/common/plat_psci_common.c			\
+				plat/qti/msm8916/msm8916_config.c		\
+				plat/qti/msm8916/msm8916_cpu_boot.c		\
+				plat/qti/msm8916/msm8916_pm.c			\
+				plat/qti/msm8916/msm8916_topology.c
 
-BL31_SOURCES	+=	${GICV2_SOURCES}				\
-			drivers/delay_timer/delay_timer.c		\
-			drivers/delay_timer/generic_delay_timer.c	\
-			lib/cpus/${ARCH}/cortex_a53.S			\
-			plat/common/plat_gicv2.c			\
-			plat/common/plat_psci_common.c			\
-			plat/qti/msm8916/msm8916_bl31_setup.c		\
-			plat/qti/msm8916/msm8916_cpu_boot.c		\
-			plat/qti/msm8916/msm8916_gicv2.c		\
-			plat/qti/msm8916/msm8916_pm.c			\
-			plat/qti/msm8916/msm8916_topology.c		\
-			plat/qti/msm8916/${ARCH}/msm8916_helpers.S	\
-			plat/qti/msm8916/${ARCH}/uartdm_console.S
+BL31_SOURCES		+=	${MSM8916_PM_SOURCES}				\
+				plat/qti/msm8916/msm8916_bl31_setup.c
+
+PLAT_INCLUDES		:=	-Iplat/qti/msm8916/include
+
+ifeq (${ARCH},aarch64)
+# arm_macros.S exists only on aarch64 currently
+PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
+endif
 
 # Only BL31 is supported at the moment and is entered on a single CPU
 RESET_TO_BL31			:= 1
 COLD_BOOT_SINGLE_CPU		:= 1
 
-# Build config flags
-# ------------------
-BL31_BASE			?= 0x86500000
-BL32_BASE			?= 0x86000000
-PRELOADED_BL33_BASE		?= 0x8f600000
-
 # Have different sections for code and rodata
 SEPARATE_CODE_AND_RODATA	:= 1
 
@@ -43,10 +45,13 @@
 WARMBOOT_ENABLE_DCACHE_EARLY	:= 1
 
 # Disable features unsupported in ARMv8.0
-ENABLE_AMU			:= 0
-ENABLE_SPE_FOR_LOWER_ELS	:= 0
+ENABLE_SPE_FOR_NS		:= 0
 ENABLE_SVE_FOR_NS		:= 0
 
+# Disable workarounds unnecessary for Cortex-A53
+WORKAROUND_CVE_2017_5715	:= 0
+WORKAROUND_CVE_2022_23960	:= 0
+
 # MSM8916 uses ARM Cortex-A53 r0p0 so likely all the errata apply
 ERRATA_A53_819472		:= 1
 ERRATA_A53_824069		:= 1
@@ -58,5 +63,27 @@
 ERRATA_A53_855873		:= 0	# Workaround works only for >= r0p3
 ERRATA_A53_1530924		:= 1
 
+# Build config flags
+# ------------------
+BL31_BASE			?= 0x86500000
+PRELOADED_BL33_BASE		?= 0x8f600000
+
+ifeq (${ARCH},aarch64)
+BL32_BASE			?= BL31_LIMIT
 $(eval $(call add_define,BL31_BASE))
+else
+# There is no BL31 on aarch32, so reuse its location for BL32
+BL32_BASE			?= $(BL31_BASE)
+endif
 $(eval $(call add_define,BL32_BASE))
+
+# UART number to use for TF-A output during early boot
+QTI_UART_NUM			?= 2
+$(eval $(call assert_numeric,QTI_UART_NUM))
+$(eval $(call add_define,QTI_UART_NUM))
+
+# Set to 1 on the command line to keep using UART after early boot.
+# Requires reserving the UART and related clocks inside the normal world.
+QTI_RUNTIME_UART		?= 0
+$(eval $(call assert_boolean,QTI_RUNTIME_UART))
+$(eval $(call add_define,QTI_RUNTIME_UART))
diff --git a/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
new file mode 100644
index 0000000..78ab0c7
--- /dev/null
+++ b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <platform_sp_min.h>
+
+#include "../msm8916_config.h"
+#include "../msm8916_setup.h"
+
+static struct {
+	entry_point_info_t bl33;
+} image_ep_info = {
+	/* BL33 entry point */
+	SET_STATIC_PARAM_HEAD(bl33, PARAM_EP, VERSION_1,
+			      entry_point_info_t, NON_SECURE),
+	.bl33.pc = PRELOADED_BL33_BASE,
+	.bl33.spsr = SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, SPSR_E_LITTLE,
+				 DISABLE_ALL_EXCEPTIONS),
+};
+
+void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	msm8916_early_platform_setup();
+}
+
+void sp_min_plat_arch_setup(void)
+{
+	msm8916_plat_arch_setup(BL32_BASE, BL32_END - BL32_BASE);
+	enable_mmu_svc_mon(0);
+}
+
+void sp_min_platform_setup(void)
+{
+	INFO("SP_MIN: Platform setup start\n");
+	msm8916_platform_setup();
+	msm8916_configure();
+	INFO("SP_MIN: Platform setup done\n");
+}
+
+entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
+{
+	return &image_ep_info.bl33;
+}
diff --git a/plat/qti/msm8916/sp_min/sp_min-msm8916.mk b/plat/qti/msm8916/sp_min/sp_min-msm8916.mk
new file mode 100644
index 0000000..be07f94
--- /dev/null
+++ b/plat/qti/msm8916/sp_min/sp_min-msm8916.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES	+=	${MSM8916_PM_SOURCES}				\
+			plat/common/${ARCH}/platform_mp_stack.S		\
+			plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
+
+override RESET_TO_SP_MIN := 1
diff --git a/plat/qti/msm8916/tsp/msm8916_tsp_setup.c b/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
new file mode 100644
index 0000000..218af57
--- /dev/null
+++ b/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <platform_tsp.h>
+
+#include "../msm8916_setup.h"
+#include <platform_def.h>
+
+void tsp_early_platform_setup(void)
+{
+	msm8916_early_platform_setup();
+}
+
+void tsp_plat_arch_setup(void)
+{
+	msm8916_plat_arch_setup(BL32_BASE, BL32_END - BL32_BASE);
+	enable_mmu_el1(0);
+}
+
+void tsp_platform_setup(void)
+{
+	INFO("TSP: Platform setup start\n");
+	msm8916_platform_setup();
+	INFO("TSP: Platform setup done\n");
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+}
diff --git a/plat/qti/msm8916/tsp/tsp-msm8916.mk b/plat/qti/msm8916/tsp/tsp-msm8916.mk
new file mode 100644
index 0000000..0d50058
--- /dev/null
+++ b/plat/qti/msm8916/tsp/tsp-msm8916.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES	+=	plat/common/${ARCH}/platform_mp_stack.S		\
+			plat/qti/msm8916/tsp/msm8916_tsp_setup.c
diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk
index df07bc4..528a1d4 100644
--- a/plat/qti/sc7280/platform.mk
+++ b/plat/qti/sc7280/platform.mk
@@ -28,6 +28,7 @@
 # Enable PSCI v1.0 extended state ID format
 PSCI_EXTENDED_STATE_ID	:=  1
 ARM_RECOM_STATE_ID_ENC  :=  1
+PSCI_OS_INIT_MODE	:=  1
 
 COLD_BOOT_SINGLE_CPU		:=	1
 PROGRAMMABLE_RESET_ADDRESS	:=	1
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 9570803..81ee93e 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -1222,7 +1222,7 @@
 		break;
 	}
 #endif /* RCAR_LSI == RCAR_E3 */
-	/* Update memory mapped and register based freqency */
+	/* Update memory mapped and register based frequency */
 	write_cntfrq_el0((u_register_t )reg_cntfid);
 	mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid);
 	/* Enable counter */
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 98ef415..59db3d8 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -87,7 +87,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/rockchip/common/drivers/pmu/pmu_com.h b/plat/rockchip/common/drivers/pmu/pmu_com.h
index 5359f73..022bb02 100644
--- a/plat/rockchip/common/drivers/pmu/pmu_com.h
+++ b/plat/rockchip/common/drivers/pmu/pmu_com.h
@@ -90,7 +90,7 @@
 
 	/*
 	 * wfe/wfi tracking not possible, hopefully the host
-	 * was sucessful in enabling wfe/wfi.
+	 * was successful in enabling wfe/wfi.
 	 * We'll give a bit of additional time, like the kernel does.
 	 */
 	if ((cluster_id && clstb_cpu_wfe < 0) ||
diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c
index 0237b16..8fb3f8e 100644
--- a/plat/rockchip/common/sp_min_plat_setup.c
+++ b/plat/rockchip/common/sp_min_plat_setup.c
@@ -82,7 +82,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void sp_min_plat_arch_setup(void)
 {
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.c b/plat/rockchip/rk3288/drivers/pmu/pmu.c
index d6d7098..085976c 100644
--- a/plat/rockchip/rk3288/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.c
@@ -288,7 +288,7 @@
 	/*
 	 * We communicate with the bootrom to active the cpus other
 	 * than cpu0, after a blob of initialize code, they will
-	 * stay at wfe state, once they are actived, they will check
+	 * stay at wfe state, once they are activated, they will check
 	 * the mailbox:
 	 * sram_base_addr + 4: 0xdeadbeaf
 	 * sram_base_addr + 8: start address for pc
diff --git a/plat/rockchip/rk3288/drivers/soc/soc.c b/plat/rockchip/rk3288/drivers/soc/soc.c
index 36f410b..2316fbe 100644
--- a/plat/rockchip/rk3288/drivers/soc/soc.c
+++ b/plat/rockchip/rk3288/drivers/soc/soc.c
@@ -216,7 +216,7 @@
 
 	/*
 	 * Maybe the HW needs some times to reset the system,
-	 * so we do not hope the core to excute valid codes.
+	 * so we do not hope the core to execute valid codes.
 	 */
 	while (1)
 		;
diff --git a/plat/rockchip/rk3328/drivers/pmu/pmu.c b/plat/rockchip/rk3328/drivers/pmu/pmu.c
index a17fef9..597db97 100644
--- a/plat/rockchip/rk3328/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3328/drivers/pmu/pmu.c
@@ -202,7 +202,7 @@
 	dsb();
 	/*
 	 * Maybe the HW needs some times to reset the system,
-	 * so we do not hope the core to excute valid codes.
+	 * so we do not hope the core to execute valid codes.
 	 */
 	while (1)
 		;
@@ -210,7 +210,7 @@
 
 /*
  * For PMIC RK805, its sleep pin is connect with gpio2_d2 from rk3328.
- * If the PMIC is configed for responding the sleep pin to power off it,
+ * If the PMIC is configured for responding the sleep pin to power off it,
  * once the pin is output high,  it will get the pmic power off.
  */
 void __dead2 rockchip_soc_system_off(void)
@@ -462,7 +462,7 @@
 
 /*
  * For PMIC RK805, its sleep pin is connect with gpio2_d2 from rk3328.
- * If the PMIC is configed for responding the sleep pin
+ * If the PMIC is configured for responding the sleep pin
  * to get it into sleep mode,
  * once the pin is output high,  it will get the pmic into sleep mode.
  */
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.h b/plat/rockchip/rk3328/drivers/soc/soc.h
index e8cbc09..e081f71 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.h
+++ b/plat/rockchip/rk3328/drivers/soc/soc.h
@@ -27,7 +27,7 @@
 	DPLL_ID,
 	CPLL_ID,
 	GPLL_ID,
-	REVERVE,
+	RESERVE,
 	NPLL_ID,
 	MAX_PLL,
 };
diff --git a/plat/rockchip/rk3368/drivers/soc/soc.c b/plat/rockchip/rk3368/drivers/soc/soc.c
index 7d51bb8..9bb237f 100644
--- a/plat/rockchip/rk3368/drivers/soc/soc.c
+++ b/plat/rockchip/rk3368/drivers/soc/soc.c
@@ -202,7 +202,7 @@
 
 	/*
 	 * Maybe the HW needs some times to reset the system,
-	 * so we do not hope the core to excute valid codes.
+	 * so we do not hope the core to execute valid codes.
 	 */
 	while (1)
 	;
diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c
index 816372b..11b0373 100644
--- a/plat/rockchip/rk3399/drivers/dram/dfs.c
+++ b/plat/rockchip/rk3399/drivers/dram/dfs.c
@@ -1696,7 +1696,7 @@
 
 	pll_cnt = ARRAY_SIZE(dpll_rates_table);
 
-	/* Assumming rate_table is in descending order */
+	/* Assuming rate_table is in descending order */
 	for (i = 0; i < pll_cnt; i++) {
 		if (mhz >= dpll_rates_table[i].mhz)
 			break;
diff --git a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.h b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.h
index 9cda22c..102ba78 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.h
+++ b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.h
@@ -103,7 +103,7 @@
 	uint32_t tcksre;
 	uint32_t tcksrx;
 	uint32_t tdpd;
-	/* mode regiter timing */
+	/* mode register timing */
 	uint32_t tmod;
 	uint32_t tmrd;
 	uint32_t tmrr;
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c
index a8b1c32..caa784c 100644
--- a/plat/rockchip/rk3399/drivers/dram/suspend.c
+++ b/plat/rockchip/rk3399/drivers/dram/suspend.c
@@ -561,7 +561,7 @@
 
 	ch_count = sdram_params->num_channels;
 
-	/* LPDDR4 f2 cann't do training, all training will fail */
+	/* LPDDR4 f2 can't do training, all training will fail */
 	for (ch = 0; ch < ch_count; ch++) {
 		/*
 		 * Without this disabled for LPDDR4 we end up writing 0's
diff --git a/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c b/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
index 724968f..96b4753 100644
--- a/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
+++ b/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
@@ -376,7 +376,7 @@
 		mmio_write_32(base + SWPORTA_DDR, save->swporta_ddr);
 		mmio_write_32(base + INTEN, save->inten);
 		mmio_write_32(base + INTMASK, save->intmask);
-		mmio_write_32(base + INTTYPE_LEVEL, save->inttype_level),
+		mmio_write_32(base + INTTYPE_LEVEL, save->inttype_level);
 		mmio_write_32(base + INT_POLARITY, save->int_polarity);
 		mmio_write_32(base + DEBOUNCE, save->debounce);
 		mmio_write_32(base + LS_SYNC, save->ls_sync);
diff --git a/plat/rockchip/rk3399/drivers/m0/src/suspend.c b/plat/rockchip/rk3399/drivers/m0/src/suspend.c
index 9ad2fa2..8a0ea32 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/suspend.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/suspend.c
@@ -30,7 +30,7 @@
 	}
 
 	/*
-	 * FSM power secquence is .. -> ST_INPUT_CLAMP(step.17) -> .. ->
+	 * FSM power sequence is .. -> ST_INPUT_CLAMP(step.17) -> .. ->
 	 * ST_WAKEUP_RESET -> ST_EXT_PWRUP-> ST_RELEASE_CLAMP ->
 	 * ST_24M_OSC_EN -> .. -> ST_WAKEUP_RESET_CLR(step.26) -> ..,
 	 * INPUT_CLAMP and WAKEUP_RESET will hold the SOC not affect by
diff --git a/plat/rockchip/rk3399/drivers/secure/secure.h b/plat/rockchip/rk3399/drivers/secure/secure.h
index e31c999..79997b2 100644
--- a/plat/rockchip/rk3399/drivers/secure/secure.h
+++ b/plat/rockchip/rk3399/drivers/secure/secure.h
@@ -32,7 +32,7 @@
 /* security config pmu slave ip */
 /* All of slaves  is ns */
 #define SGRF_PMU_SLV_S_NS		BIT_WITH_WMSK(0)
-/* slaves secure attr is configed */
+/* slaves secure attr is configured */
 #define SGRF_PMU_SLV_S_CFGED		WMSK_BIT(0)
 #define SGRF_PMU_SLV_CRYPTO1_NS		WMSK_BIT(1)
 
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index 98b5ad6..e2b2934 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -343,7 +343,7 @@
 
 	/*
 	 * Maybe the HW needs some times to reset the system,
-	 * so we do not hope the core to excute valid codes.
+	 * so we do not hope the core to execute valid codes.
 	 */
 	while (1)
 		;
diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c
index db71817..80e4d8d 100644
--- a/plat/rpi/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl2_setup.c
@@ -35,7 +35,9 @@
 	params.reg_base = RPI3_SDHOST_BASE;
 	params.bus_width = MMC_BUS_WIDTH_1;
 	params.clk_rate = 50000000;
+	params.clk_rate_initial = (RPI3_SDHOST_MAX_CLOCK / HC_CLOCKDIVISOR_MAXVAL);
 	mmc_info.mmc_dev_type = MMC_IS_SD_HC;
+	mmc_info.ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4;
 	rpi3_sdhost_init(&params, &mmc_info);
 }
 
diff --git a/plat/rpi/rpi4/rpi4_pci_svc.c b/plat/rpi/rpi4/rpi4_pci_svc.c
index 7d1ca5c..e4ef5c1 100644
--- a/plat/rpi/rpi4/rpi4_pci_svc.c
+++ b/plat/rpi/rpi4/rpi4_pci_svc.c
@@ -11,7 +11,7 @@
  * it. Given that it's not ECAM compliant yet reasonably simple, it makes for
  * an excellent example of the PCI SMCCC interface.
  *
- * The PCI SMCCC interface is described in DEN0115 availabe from:
+ * The PCI SMCCC interface is described in DEN0115 available from:
  * https://developer.arm.com/documentation/den0115/latest
  */
 
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
new file mode 100644
index 0000000..f69c901
--- /dev/null
+++ b/plat/st/common/common.mk
@@ -0,0 +1,257 @@
+#
+# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RESET_TO_BL2			:=	1
+
+STM32MP_EARLY_CONSOLE		?=	0
+STM32MP_RECONFIGURE_CONSOLE	?=	0
+STM32MP_UART_BAUDRATE		?=	115200
+
+TRUSTED_BOARD_BOOT		?=	0
+STM32MP_USE_EXTERNAL_HEAP	?=	0
+
+# Use secure library from the ROM code for authentication
+STM32MP_CRYPTO_ROM_LIB		?=	0
+
+# Please don't increment this value without good understanding of
+# the monotonic counter
+STM32_TF_VERSION		?=	0
+
+# Enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC	:=	1
+
+# STM32 image header binary type for BL2
+STM32_HEADER_BL2_BINARY_TYPE	:=	0x10
+
+TF_CFLAGS			+=	-Wsign-compare
+TF_CFLAGS			+=	-Wformat-signedness
+
+# Boot devices
+STM32MP_EMMC			?=	0
+STM32MP_SDMMC			?=	0
+STM32MP_RAW_NAND		?=	0
+STM32MP_SPI_NAND		?=	0
+STM32MP_SPI_NOR			?=	0
+
+# Put both BL2 and FIP in eMMC boot partition
+STM32MP_EMMC_BOOT		?=	0
+
+# Serial boot devices
+STM32MP_UART_PROGRAMMER		?=	0
+STM32MP_USB_PROGRAMMER		?=	0
+
+$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
+$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
+DTC_CPPFLAGS			+=	${INCLUDES}
+DTC_FLAGS			+=	-Wno-unit_address_vs_reg
+ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
+DTC_FLAGS			+=	-Wno-interrupt_provider
+endif
+
+# Macros and rules to build TF binary
+STM32_TF_ELF_LDFLAGS		:=	--hash-style=gnu --as-needed
+STM32_TF_LINKERFILE		:=	${BUILD_PLAT}/${PLAT}.ld
+
+ASFLAGS				+=	-DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\"
+
+# Variables for use with stm32image
+STM32IMAGEPATH			?=	tools/stm32image
+STM32IMAGE			?=	${STM32IMAGEPATH}/stm32image${BIN_EXT}
+STM32IMAGE_SRC			:=	${STM32IMAGEPATH}/stm32image.c
+STM32_DEPS			+=	${STM32IMAGE}
+
+FIP_DEPS			+=	dtbs
+STM32MP_HW_CONFIG		:=	${BL33_CFG}
+
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config))
+
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1,,$(ENCRYPT_BL32)))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2,,$(ENCRYPT_BL32)))
+endif
+
+# Enable flags for C files
+$(eval $(call assert_booleans,\
+	$(sort \
+		PLAT_XLAT_TABLES_DYNAMIC \
+		STM32MP_EARLY_CONSOLE \
+		STM32MP_EMMC \
+		STM32MP_EMMC_BOOT \
+		STM32MP_RAW_NAND \
+		STM32MP_RECONFIGURE_CONSOLE \
+		STM32MP_SDMMC \
+		STM32MP_SPI_NAND \
+		STM32MP_SPI_NOR \
+		STM32MP_UART_PROGRAMMER \
+		STM32MP_USB_PROGRAMMER \
+)))
+
+$(eval $(call assert_numerics,\
+	$(sort \
+		STM32_TF_VERSION \
+		STM32MP_UART_BAUDRATE \
+)))
+
+$(eval $(call add_defines,\
+	$(sort \
+		PLAT_XLAT_TABLES_DYNAMIC \
+		STM32_TF_VERSION \
+		STM32MP_EARLY_CONSOLE \
+		STM32MP_EMMC \
+		STM32MP_EMMC_BOOT \
+		STM32MP_RAW_NAND \
+		STM32MP_RECONFIGURE_CONSOLE \
+		STM32MP_SDMMC \
+		STM32MP_SPI_NAND \
+		STM32MP_SPI_NOR \
+		STM32MP_UART_BAUDRATE \
+		STM32MP_UART_PROGRAMMER \
+		STM32MP_USB_PROGRAMMER \
+)))
+
+# Include paths and source files
+PLAT_INCLUDES			+=	-Iplat/st/common/include/
+
+include lib/fconf/fconf.mk
+include lib/libfdt/libfdt.mk
+include lib/zlib/zlib.mk
+
+PLAT_BL_COMMON_SOURCES		+=	common/uuid.c					\
+					plat/st/common/stm32mp_common.c
+
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES		+=	${XLAT_TABLES_LIB_SRCS}
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/clk/clk.c				\
+					drivers/delay_timer/delay_timer.c		\
+					drivers/delay_timer/generic_delay_timer.c	\
+					drivers/st/clk/stm32mp_clkfunc.c		\
+					drivers/st/ddr/stm32mp_ddr.c			\
+					drivers/st/gpio/stm32_gpio.c			\
+					drivers/st/regulator/regulator_core.c		\
+					drivers/st/regulator/regulator_fixed.c		\
+					plat/st/common/stm32mp_dt.c
+
+BL2_SOURCES			+=	${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
+BL2_SOURCES			+=	$(ZLIB_SOURCES)
+
+BL2_SOURCES			+=	drivers/io/io_fip.c				\
+					plat/st/common/bl2_io_storage.c			\
+					plat/st/common/stm32mp_fconf_io.c
+
+BL2_SOURCES			+=	drivers/io/io_block.c				\
+					drivers/io/io_mtd.c				\
+					drivers/io/io_storage.c
+
+ifneq (${DECRYPTION_SUPPORT},none)
+BL2_SOURCES			+=	drivers/io/io_encrypted.c
+endif
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+AUTH_SOURCES			:=	drivers/auth/auth_mod.c				\
+					drivers/auth/crypto_mod.c			\
+					drivers/auth/img_parser_mod.c
+
+ifeq (${GENERATE_COT},1)
+TFW_NVCTR_VAL			:=	0
+NTFW_NVCTR_VAL			:=	0
+KEY_SIZE			:=
+KEY_ALG				:=	ecdsa
+HASH_ALG			:=	sha256
+
+ifeq (${SAVE_KEYS},1)
+TRUSTED_WORLD_KEY		?=	${BUILD_PLAT}/trusted.pem
+NON_TRUSTED_WORLD_KEY		?=	${BUILD_PLAT}/non-trusted.pem
+BL32_KEY			?=	${BUILD_PLAT}/trusted_os.pem
+BL33_KEY			?=	${BUILD_PLAT}/non-trusted_os.pem
+endif
+
+endif
+TF_MBEDTLS_KEY_ALG		:=	ecdsa
+
+ifneq (${MBEDTLS_DIR},)
+MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
+${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
+
+ifeq (${MBEDTLS_MAJOR}, 2)
+MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-2.h>"
+endif
+
+ifeq (${MBEDTLS_MAJOR}, 3)
+MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-3.h>"
+endif
+endif
+
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+COT_DESC_IN_DTB			:=	1
+AUTH_SOURCES			+=	lib/fconf/fconf_cot_getter.c			\
+					lib/fconf/fconf_tbbr_getter.c			\
+					plat/st/common/stm32mp_crypto_lib.c
+
+BL2_SOURCES			+=	$(AUTH_SOURCES)					\
+					plat/st/common/stm32mp_trusted_boot.c
+endif
+
+ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
+BL2_SOURCES			+=	drivers/mmc/mmc.c				\
+					drivers/partition/gpt.c				\
+					drivers/partition/partition.c
+endif
+
+ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+BL2_SOURCES			+=	drivers/mtd/spi-mem/spi_mem.c
+endif
+
+ifeq (${STM32MP_RAW_NAND},1)
+$(eval $(call add_define_val,NAND_ONFI_DETECT,1))
+BL2_SOURCES			+=	drivers/mtd/nand/raw_nand.c
+endif
+
+ifeq (${STM32MP_SPI_NAND},1)
+BL2_SOURCES			+=	drivers/mtd/nand/spi_nand.c
+endif
+
+ifeq (${STM32MP_SPI_NOR},1)
+ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
+$(eval $(call add_define_val,STM32MP_NOR_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
+endif
+BL2_SOURCES			+=	drivers/mtd/nor/spi_nor.c
+endif
+
+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),)
+ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
+$(eval $(call add_define_val,STM32MP_NAND_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
+endif
+BL2_SOURCES			+=	drivers/mtd/nand/core.c
+endif
+
+ifneq ($(filter 1,${STM32MP_UART_PROGRAMMER} ${STM32MP_USB_PROGRAMMER}),)
+BL2_SOURCES			+=	drivers/io/io_memmap.c
+endif
+
+ifeq (${STM32MP_UART_PROGRAMMER},1)
+BL2_SOURCES			+=	plat/st/common/stm32cubeprogrammer_uart.c
+endif
+
+ifeq (${STM32MP_USB_PROGRAMMER},1)
+BL2_SOURCES			+=	drivers/usb/usb_device.c			\
+					plat/st/common/stm32cubeprogrammer_usb.c	\
+					plat/st/common/usb_dfu.c
+endif
+
+BL2_SOURCES			+=	drivers/st/ddr/stm32mp_ddr_test.c		\
+					drivers/st/ddr/stm32mp_ram.c
+
+BL2_SOURCES			+=	common/desc_image_load.c
+
+BL2_SOURCES			+=	lib/optee/optee_utils.c
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
new file mode 100644
index 0000000..fa48dfc
--- /dev/null
+++ b/plat/st/common/common_rules.mk
@@ -0,0 +1,79 @@
+#
+# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Compilation rules
+.PHONY: check_dtc_version stm32image clean_stm32image check_boot_device
+.SUFFIXES:
+
+all: check_dtc_version stm32image ${STM32_TF_STM32}
+
+distclean realclean clean: clean_stm32image
+
+bl2: check_boot_device
+
+check_boot_device:
+	@if [ ${STM32MP_EMMC} != 1 ] && \
+	    [ ${STM32MP_SDMMC} != 1 ] && \
+	    [ ${STM32MP_RAW_NAND} != 1 ] && \
+	    [ ${STM32MP_SPI_NAND} != 1 ] && \
+	    [ ${STM32MP_SPI_NOR} != 1 ] && \
+	    [ ${STM32MP_UART_PROGRAMMER} != 1 ] && \
+	    [ ${STM32MP_USB_PROGRAMMER} != 1 ]; then \
+		echo "No boot device driver is enabled"; \
+		false; \
+	fi
+
+stm32image: ${STM32IMAGE}
+
+${STM32IMAGE}: ${STM32IMAGE_SRC}
+	${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
+
+clean_stm32image:
+	${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
+
+check_dtc_version:
+	@if [ ${DTC_VERSION} -lt 10407 ]; then \
+		echo "dtc version too old (${DTC_V}), you need at least version 1.4.7"; \
+		false; \
+	fi
+
+# Create DTB file for BL2
+${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
+	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	@echo '#include "${BL2_DTSI}"' >> $@
+
+${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
+
+${BUILD_PLAT}/$(PLAT)-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb $(STM32_BINARY_MAPPING) bl2
+	@echo "  AS      $${PLAT}.S"
+	${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
+		-DDTB_BIN_PATH=\"$<\" \
+		-c $(word 2,$^) -o $@
+
+$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},$(STM32_LD_FILE),bl2))
+
+tf-a-%.elf: $(PLAT)-%.o ${STM32_TF_LINKERFILE}
+	@echo "  LDS     $<"
+	${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
+
+tf-a-%.bin: tf-a-%.elf
+	${Q}${OC} -O binary $< $@
+	@echo
+	@echo "Built $@ successfully"
+	@echo
+
+tf-a-%.stm32: tf-a-%.bin ${STM32_DEPS}
+	@echo
+	@echo "Generate $@"
+	$(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}'))
+	$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
+	${Q}${STM32IMAGE} -s $< -d $@ \
+		-l $(LOADADDR) -e ${ENTRY} \
+		-v ${STM32_TF_VERSION} \
+		-m ${STM32_HEADER_VERSION_MAJOR} \
+		-n ${STM32_HEADER_VERSION_MINOR} \
+		-b ${STM32_HEADER_BL2_BINARY_TYPE}
+	@echo
diff --git a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-2.h b/plat/st/common/include/stm32mp_mbedtls_config-2.h
similarity index 96%
rename from plat/st/stm32mp1/include/stm32mp1_mbedtls_config-2.h
rename to plat/st/common/include/stm32mp_mbedtls_config-2.h
index 2f07621..66ff346 100644
--- a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-2.h
+++ b/plat/st/common/include/stm32mp_mbedtls_config-2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-3.h b/plat/st/common/include/stm32mp_mbedtls_config-3.h
similarity index 96%
rename from plat/st/stm32mp1/include/stm32mp1_mbedtls_config-3.h
rename to plat/st/common/include/stm32mp_mbedtls_config-3.h
index d7dab1f..a812671 100644
--- a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-3.h
+++ b/plat/st/common/include/stm32mp_mbedtls_config-3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
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/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index 0da0019..ea2b8db 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -167,8 +167,8 @@
 	return ret;
 }
 
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			     void **hashed_pk_ptr, unsigned int *hashed_pk_len)
 {
 	return get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, hashed_pk_len, NULL);
 }
@@ -220,8 +220,8 @@
 	return 0;
 }
 
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			     void **hashed_pk_ptr, unsigned int *hashed_pk_len)
 {
 	static uint8_t st_pk[CRYPTO_PUBKEY_MAX_SIZE + sizeof(uint32_t)];
 	int ret;
@@ -650,13 +650,16 @@
 		    crypto_lib_init,
 		    crypto_verify_signature,
 		    crypto_verify_hash,
-		    crypto_auth_decrypt);
+		    NULL,
+		    crypto_auth_decrypt,
+		    crypto_convert_pk);
 
 #else /* No decryption support */
 REGISTER_CRYPTO_LIB("stm32_crypto_lib",
 		    crypto_lib_init,
 		    crypto_verify_signature,
 		    crypto_verify_hash,
-		    NULL);
-
+		    NULL,
+		    NULL,
+		    crypto_convert_pk);
 #endif
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index cddc695..55423ae 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,31 +1,15 @@
 #
-# 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
 #
 
+include plat/st/common/common.mk
+
 ARM_CORTEX_A7		:=	yes
 ARM_WITH_NEON		:=	yes
-RESET_TO_BL2		:=	1
 USE_COHERENT_MEM	:=	0
 
-STM32MP_EARLY_CONSOLE	?=	0
-STM32MP_RECONFIGURE_CONSOLE ?=	0
-STM32MP_UART_BAUDRATE	?=	115200
-
-TRUSTED_BOARD_BOOT	?=	0
-STM32MP_USE_EXTERNAL_HEAP ?=	0
-
-# Use secure library from the ROM code for authentication
-STM32MP_CRYPTO_ROM_LIB	?=	0
-
-# Please don't increment this value without good understanding of
-# the monotonic counter
-STM32_TF_VERSION	?=	0
-
-# Enable dynamic memory mapping
-PLAT_XLAT_TABLES_DYNAMIC :=	1
-
 # Default Device tree
 DTB_FILE_NAME		?=	stm32mp157c-ev1.dtb
 
@@ -89,17 +73,14 @@
 endif
 endif
 
-# STM32 image header binary type for BL2
-STM32_HEADER_BL2_BINARY_TYPE:=	0x10
+PKA_USE_NIST_P256	?=	0
+PKA_USE_BRAINPOOL_P256T1 ?=	0
 
 ifeq ($(AARCH32_SP),sp_min)
 # Disable Neon support: sp_min runtime may conflict with non-secure world
 TF_CFLAGS		+=	-mfloat-abi=soft
 endif
 
-TF_CFLAGS		+=	-Wsign-compare
-TF_CFLAGS		+=	-Wformat-signedness
-
 # Not needed for Cortex-A7
 WORKAROUND_CVE_2017_5715:=	0
 WORKAROUND_CVE_2022_23960:=	0
@@ -131,18 +112,6 @@
 STM32_RNG_VER		:=	2
 endif
 
-# Boot devices
-STM32MP_EMMC		?=	0
-STM32MP_SDMMC		?=	0
-STM32MP_RAW_NAND	?=	0
-STM32MP_SPI_NAND	?=	0
-STM32MP_SPI_NOR		?=	0
-STM32MP_EMMC_BOOT	?=	0
-
-# Serial boot devices
-STM32MP_USB_PROGRAMMER	?=	0
-STM32MP_UART_PROGRAMMER	?=	0
-
 # Download load address for serial boot devices
 DWL_BUFFER_BASE 	?=	0xC7000000
 
@@ -159,33 +128,17 @@
 endif
 endif
 
-$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
-$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
-DTC_CPPFLAGS		+=	${INCLUDES}
-DTC_FLAGS		+=	-Wno-unit_address_vs_reg
-ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
-DTC_FLAGS		+=	-Wno-interrupt_provider
-endif
-
 # Macros and rules to build TF binary
-STM32_TF_ELF_LDFLAGS	:=	--hash-style=gnu --as-needed
 STM32_TF_STM32		:=	$(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
-STM32_TF_LINKERFILE	:=	${BUILD_PLAT}/stm32mp1.ld
+STM32_LD_FILE		:=	plat/st/stm32mp1/stm32mp1.ld.S
+STM32_BINARY_MAPPING	:=	plat/st/stm32mp1/stm32mp1.S
 
-ASFLAGS			+= -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\"
 ifeq ($(AARCH32_SP),sp_min)
 # BL32 is built only if using SP_MIN
 BL32_DEP		:= bl32
 ASFLAGS			+= -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\"
 endif
 
-# Variables for use with stm32image
-STM32IMAGEPATH		?= tools/stm32image
-STM32IMAGE		?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
-STM32IMAGE_SRC		:= ${STM32IMAGEPATH}/stm32image.c
-
-FIP_DEPS		+=	dtbs
-STM32MP_HW_CONFIG	:=	${BL33_CFG}
 STM32MP_FW_CONFIG_NAME	:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
 STM32MP_FW_CONFIG	:=	${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
 ifneq (${AARCH32_SP},none)
@@ -193,8 +146,6 @@
 endif
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
-# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config))
 ifeq ($(GENERATE_COT),1)
 STM32MP_CFG_CERT	:=	$(BUILD_PLAT)/stm32mp_cfg_cert.crt
 # Add the STM32MP_CFG_CERT to FIP and specify the same to certtool
@@ -203,15 +154,6 @@
 ifeq ($(AARCH32_SP),sp_min)
 STM32MP_TOS_FW_CONFIG	:= $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dtb,$(DTB_FILE_NAME)))
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_TOS_FW_CONFIG},--tos-fw-config))
-else
-# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
-# in the FIP if the platform requires.
-ifneq ($(BL32_EXTRA1),)
-$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1,,$(ENCRYPT_BL32)))
-endif
-ifneq ($(BL32_EXTRA2),)
-$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2,,$(ENCRYPT_BL32)))
-endif
 endif
 
 # Enable flags for C files
@@ -219,21 +161,9 @@
 	$(sort \
 		PKA_USE_BRAINPOOL_P256T1 \
 		PKA_USE_NIST_P256 \
-		PLAT_TBBR_IMG_DEF \
-		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32MP_CRYPTO_ROM_LIB \
 		STM32MP_DDR_32BIT_INTERFACE \
 		STM32MP_DDR_DUAL_AXI_PORT \
-		STM32MP_EARLY_CONSOLE \
-		STM32MP_EMMC \
-		STM32MP_EMMC_BOOT \
-		STM32MP_RAW_NAND \
-		STM32MP_RECONFIGURE_CONSOLE \
-		STM32MP_SDMMC \
-		STM32MP_SPI_NAND \
-		STM32MP_SPI_NOR \
-		STM32MP_UART_PROGRAMMER \
-		STM32MP_USB_PROGRAMMER \
 		STM32MP_USE_EXTERNAL_HEAP \
 		STM32MP13 \
 		STM32MP15 \
@@ -246,8 +176,6 @@
 		STM32_HEADER_VERSION_MAJOR \
 		STM32_RNG_VER \
 		STM32_TF_A_COPIES \
-		STM32_TF_VERSION \
-		STM32MP_UART_BAUDRATE \
 )))
 
 $(eval $(call add_defines,\
@@ -257,41 +185,22 @@
 		PKA_USE_NIST_P256 \
 		PLAT_PARTITION_MAX_ENTRIES \
 		PLAT_TBBR_IMG_DEF \
-		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_HASH_VER \
 		STM32_HEADER_VERSION_MAJOR \
 		STM32_RNG_VER \
 		STM32_TF_A_COPIES \
-		STM32_TF_VERSION \
 		STM32MP_CRYPTO_ROM_LIB \
 		STM32MP_DDR_32BIT_INTERFACE \
 		STM32MP_DDR_DUAL_AXI_PORT \
-		STM32MP_EARLY_CONSOLE \
-		STM32MP_EMMC \
-		STM32MP_EMMC_BOOT \
-		STM32MP_RAW_NAND \
-		STM32MP_RECONFIGURE_CONSOLE \
-		STM32MP_SDMMC \
-		STM32MP_SPI_NAND \
-		STM32MP_SPI_NOR \
-		STM32MP_UART_BAUDRATE \
-		STM32MP_UART_PROGRAMMER \
-		STM32MP_USB_PROGRAMMER \
 		STM32MP_USE_EXTERNAL_HEAP \
 		STM32MP13 \
 		STM32MP15 \
 )))
 
 # Include paths and source files
-PLAT_INCLUDES		:=	-Iplat/st/common/include/
 PLAT_INCLUDES		+=	-Iplat/st/stm32mp1/include/
 
-include lib/fconf/fconf.mk
-include lib/libfdt/libfdt.mk
-
-PLAT_BL_COMMON_SOURCES	:=	common/uuid.c						\
-				plat/st/common/stm32mp_common.c				\
-				plat/st/stm32mp1/stm32mp1_private.c
+PLAT_BL_COMMON_SOURCES	+=	plat/st/stm32mp1/stm32mp1_private.c
 
 PLAT_BL_COMMON_SOURCES	+=	drivers/st/uart/aarch32/stm32_console.S
 
@@ -299,28 +208,16 @@
 PLAT_BL_COMMON_SOURCES	+=	plat/st/stm32mp1/stm32mp1_stack_protector.c
 endif
 
-include lib/xlat_tables_v2/xlat_tables.mk
-PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
-
 PLAT_BL_COMMON_SOURCES	+=	lib/cpus/aarch32/cortex_a7.S
 
 PLAT_BL_COMMON_SOURCES	+=	drivers/arm/tzc/tzc400.c				\
-				drivers/clk/clk.c					\
-				drivers/delay_timer/delay_timer.c			\
-				drivers/delay_timer/generic_delay_timer.c		\
 				drivers/st/bsec/bsec2.c					\
-				drivers/st/clk/stm32mp_clkfunc.c			\
-				drivers/st/ddr/stm32mp_ddr.c				\
 				drivers/st/ddr/stm32mp1_ddr_helpers.c			\
-				drivers/st/gpio/stm32_gpio.c				\
 				drivers/st/i2c/stm32_i2c.c				\
 				drivers/st/iwdg/stm32_iwdg.c				\
 				drivers/st/pmic/stm32mp_pmic.c				\
 				drivers/st/pmic/stpmic1.c				\
-				drivers/st/regulator/regulator_core.c			\
-				drivers/st/regulator/regulator_fixed.c			\
 				drivers/st/reset/stm32mp1_reset.c			\
-				plat/st/common/stm32mp_dt.c				\
 				plat/st/stm32mp1/stm32mp1_dbgmcu.c			\
 				plat/st/stm32mp1/stm32mp1_helper.S			\
 				plat/st/stm32mp1/stm32mp1_syscfg.c
@@ -333,195 +230,54 @@
 PLAT_BL_COMMON_SOURCES	+=	drivers/st/clk/stm32mp1_clk.c
 endif
 
-BL2_SOURCES		+=	${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
-
-BL2_SOURCES		+=	drivers/io/io_fip.c					\
-				plat/st/common/bl2_io_storage.c				\
-				plat/st/common/stm32mp_fconf_io.c			\
-				plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
+BL2_SOURCES		+=	plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
 				plat/st/stm32mp1/stm32mp1_fconf_firewall.c
 
-include lib/zlib/zlib.mk
-
 ifeq (${PSA_FWU_SUPPORT},1)
 include drivers/fwu/fwu.mk
 endif
 
-
-BL2_SOURCES		+=	$(ZLIB_SOURCES)
-
-BL2_SOURCES		+=	drivers/io/io_block.c					\
-				drivers/io/io_mtd.c					\
-				drivers/io/io_storage.c					\
-				drivers/st/crypto/stm32_hash.c				\
+BL2_SOURCES		+=	drivers/st/crypto/stm32_hash.c				\
 				plat/st/stm32mp1/bl2_plat_setup.c
 
-ifneq (${DECRYPTION_SUPPORT},none)
-BL2_SOURCES		+=	drivers/io/io_encrypted.c
-endif
-
 ifeq (${TRUSTED_BOARD_BOOT},1)
-AUTH_SOURCES		:=	drivers/auth/auth_mod.c					\
-				drivers/auth/crypto_mod.c				\
-				drivers/auth/img_parser_mod.c
-
-ifeq (${GENERATE_COT},1)
-TFW_NVCTR_VAL		:=	0
-NTFW_NVCTR_VAL		:=	0
-KEY_SIZE		:=
-KEY_ALG			:=	ecdsa
-HASH_ALG		:=	sha256
-
-ifeq (${SAVE_KEYS},1)
-TRUSTED_WORLD_KEY	?=	${BUILD_PLAT}/trusted.pem
-NON_TRUSTED_WORLD_KEY	?=	${BUILD_PLAT}/non-trusted.pem
-BL32_KEY		?=	${BUILD_PLAT}/trusted_os.pem
-BL33_KEY		?=	${BUILD_PLAT}/non-trusted_os.pem
-endif
-
-endif
-TF_MBEDTLS_KEY_ALG 	:=	ecdsa
-
-ifneq (${MBEDTLS_DIR},)
-MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
-${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
-
-ifeq (${MBEDTLS_MAJOR}, 2)
-MBEDTLS_CONFIG_FILE	?=	"<stm32mp1_mbedtls_config-2.h>"
-endif
-
-ifeq (${MBEDTLS_MAJOR}, 3)
-MBEDTLS_CONFIG_FILE	?=	"<stm32mp1_mbedtls_config-3.h>"
-endif
-endif
-
-include drivers/auth/mbedtls/mbedtls_x509.mk
-
-COT_DESC_IN_DTB		:=	1
-AUTH_SOURCES		+=	lib/fconf/fconf_cot_getter.c				\
-				lib/fconf/fconf_tbbr_getter.c				\
-				plat/st/common/stm32mp_crypto_lib.c
-
 ifeq ($(STM32MP13),1)
-AUTH_SOURCES		+=	drivers/st/crypto/stm32_pka.c
-AUTH_SOURCES		+=	drivers/st/crypto/stm32_saes.c
+BL2_SOURCES		+=	drivers/st/crypto/stm32_pka.c
+BL2_SOURCES		+=	drivers/st/crypto/stm32_saes.c
 endif
-
-BL2_SOURCES		+=	$(AUTH_SOURCES)						\
-				plat/st/common/stm32mp_trusted_boot.c
 endif
 
 ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
-BL2_SOURCES		+=	drivers/mmc/mmc.c					\
-				drivers/partition/gpt.c					\
-				drivers/partition/partition.c				\
-				drivers/st/mmc/stm32_sdmmc2.c
+BL2_SOURCES		+=	drivers/st/mmc/stm32_sdmmc2.c
 endif
 
 ifeq (${STM32MP_RAW_NAND},1)
-$(eval $(call add_define_val,NAND_ONFI_DETECT,1))
-BL2_SOURCES		+=	drivers/mtd/nand/raw_nand.c				\
-				drivers/st/fmc/stm32_fmc2_nand.c
-endif
-
-ifeq (${STM32MP_SPI_NAND},1)
-BL2_SOURCES		+=	drivers/mtd/nand/spi_nand.c
+BL2_SOURCES		+=	drivers/st/fmc/stm32_fmc2_nand.c
 endif
 
-ifeq (${STM32MP_SPI_NOR},1)
-ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
-$(eval $(call add_define_val,STM32MP_NOR_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
-endif
-BL2_SOURCES		+=	drivers/mtd/nor/spi_nor.c
-endif
-
 ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
-BL2_SOURCES		+=	drivers/mtd/spi-mem/spi_mem.c				\
-				drivers/st/spi/stm32_qspi.c
-endif
-
-ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),)
-ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
-$(eval $(call add_define_val,STM32MP_NAND_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
-endif
-BL2_SOURCES		+=	drivers/mtd/nand/core.c
+BL2_SOURCES		+=	drivers/st/spi/stm32_qspi.c
 endif
 
 ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
 BL2_SOURCES		+=	plat/st/stm32mp1/stm32mp1_boot_device.c
 endif
 
-ifneq ($(filter 1,${STM32MP_UART_PROGRAMMER} ${STM32MP_USB_PROGRAMMER}),)
-BL2_SOURCES		+=	drivers/io/io_memmap.c
-endif
-
 ifeq (${STM32MP_UART_PROGRAMMER},1)
-BL2_SOURCES		+=	drivers/st/uart/stm32_uart.c				\
-				plat/st/common/stm32cubeprogrammer_uart.c
+BL2_SOURCES		+=	drivers/st/uart/stm32_uart.c
 endif
 
 ifeq (${STM32MP_USB_PROGRAMMER},1)
 #The DFU stack uses only one end point, reduce the USB stack footprint
 $(eval $(call add_define_val,CONFIG_USBD_EP_NB,1U))
 BL2_SOURCES		+=	drivers/st/usb/stm32mp1_usb.c				\
-				drivers/usb/usb_device.c				\
-				plat/st/common/stm32cubeprogrammer_usb.c		\
-				plat/st/common/usb_dfu.c					\
 				plat/st/stm32mp1/stm32mp1_usb_dfu.c
 endif
 
-BL2_SOURCES		+=	drivers/st/ddr/stm32mp_ddr_test.c			\
-				drivers/st/ddr/stm32mp_ram.c				\
-				drivers/st/ddr/stm32mp1_ddr.c				\
+BL2_SOURCES		+=	drivers/st/ddr/stm32mp1_ddr.c				\
 				drivers/st/ddr/stm32mp1_ram.c
 
-BL2_SOURCES		+=	common/desc_image_load.c				\
-				plat/st/stm32mp1/plat_image_load.c
-
-BL2_SOURCES		+=	lib/optee/optee_utils.c
-
-# Compilation rules
-.PHONY: check_dtc_version stm32image clean_stm32image check_boot_device
-.SUFFIXES:
-
-all: check_dtc_version stm32image ${STM32_TF_STM32}
-
-distclean realclean clean: clean_stm32image
-
-bl2: check_boot_device
-
-check_boot_device:
-	@if [ ${STM32MP_EMMC} != 1 ] && \
-	    [ ${STM32MP_SDMMC} != 1 ] && \
-	    [ ${STM32MP_RAW_NAND} != 1 ] && \
-	    [ ${STM32MP_SPI_NAND} != 1 ] && \
-	    [ ${STM32MP_SPI_NOR} != 1 ] && \
-	    [ ${STM32MP_UART_PROGRAMMER} != 1 ] && \
-	    [ ${STM32MP_USB_PROGRAMMER} != 1 ]; then \
-		echo "No boot device driver is enabled"; \
-		false; \
-	fi
-
-stm32image: ${STM32IMAGE}
-
-${STM32IMAGE}: ${STM32IMAGE_SRC}
-	${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
-
-clean_stm32image:
-	${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
-
-check_dtc_version:
-	@if [ ${DTC_VERSION} -lt 10404 ]; then \
-		echo "dtc version too old (${DTC_V}), you need at least version 1.4.4"; \
-		false; \
-	fi
-
-# Create DTB file for BL2
-${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL2_DTSI}"' >> $@
-
-${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
+BL2_SOURCES		+=	plat/st/stm32mp1/plat_image_load.c
 
 ifeq ($(AARCH32_SP),sp_min)
 # Create DTB file for BL32
@@ -532,33 +288,4 @@
 ${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts
 endif
 
-${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32mp1.S bl2
-	@echo "  AS      stm32mp1.S"
-	${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
-		-DDTB_BIN_PATH=\"$<\" \
-		-c plat/st/stm32mp1/stm32mp1.S -o $@
-
-$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,bl2))
-
-tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE}
-	@echo "  LDS     $<"
-	${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
-
-tf-a-%.bin: tf-a-%.elf
-	${Q}${OC} -O binary $< $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
-
-tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin
-	@echo
-	@echo "Generate $@"
-	$(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}'))
-	$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
-	${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \
-		-l $(LOADADDR) -e ${ENTRY} \
-		-v ${STM32_TF_VERSION} \
-		-m ${STM32_HEADER_VERSION_MAJOR} \
-		-n ${STM32_HEADER_VERSION_MINOR} \
-		-b ${STM32_HEADER_BL2_BINARY_TYPE}
-	@echo
+include plat/st/common/common_rules.mk
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 7439381..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
  */
@@ -42,7 +42,7 @@
 	while (interrupt == GIC_SPURIOUS_INTERRUPT) {
 		wfi();
 
-		/* Acknoledge IT */
+		/* Acknowledge IT */
 		interrupt = gicv2_acknowledge_interrupt();
 		/* If Interrupt == 1022 it will be acknowledged by non secure */
 		if ((interrupt != PENDING_G1_INTID) &&
@@ -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/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
index a0bfdee..1bed229 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -130,7 +130,7 @@
  *
  * Return: 0 if all goes well, else appropriate error message
  */
-static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
+static int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
 					     uint32_t dir)
 {
 	/* Check for any errors already available */
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
index f4b0b4b..4005102 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
@@ -53,7 +53,7 @@
 };
 
 /**
- * k3_sec_proxy_send() - Send data over a Secure Proxy thread
+ * k3_sec_proxy_clear_rx_thread() - Clear a receive Secure Proxy thread
  * @id: Channel Identifier
  * @msg: Pointer to k3_sec_proxy_msg
  *
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index ade10a6..dacef74 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -13,6 +13,7 @@
 #include <string.h>
 
 #include <platform_def.h>
+#include <lib/bakery_lock.h>
 
 #include <common/debug.h>
 #include <sec_proxy.h>
@@ -25,6 +26,8 @@
 #endif
 static uint8_t message_sequence;
 
+DEFINE_BAKERY_LOCK(ti_sci_xfer_lock);
+
 /**
  * struct ti_sci_xfer - Structure representing a message flow
  * @tx_message:	Transmit message
@@ -62,7 +65,6 @@
 	/* Ensure we have sane transfer sizes */
 	if (rx_message_size > TI_SCI_MAX_MESSAGE_SIZE ||
 	    tx_message_size > TI_SCI_MAX_MESSAGE_SIZE ||
-	    rx_message_size < sizeof(*hdr) ||
 	    tx_message_size < sizeof(*hdr))
 		return -ERANGE;
 
@@ -70,7 +72,11 @@
 	hdr->seq = ++message_sequence;
 	hdr->type = msg_type;
 	hdr->host = TI_SCI_HOST_ID;
-	hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
+	hdr->flags = msg_flags;
+	/* Request a response if rx_message_size is non-zero */
+	if (rx_message_size != 0U) {
+		hdr->flags |= TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
+	}
 
 	xfer->tx_message.buf = tx_buf;
 	xfer->tx_message.len = tx_message_size;
@@ -89,10 +95,9 @@
  *
  * Return: 0 if all goes well, else appropriate error message
  */
-static inline int ti_sci_get_response(struct ti_sci_xfer *xfer,
-				      enum k3_sec_proxy_chan_id chan)
+static int ti_sci_get_response(struct k3_sec_proxy_msg *msg,
+			       enum k3_sec_proxy_chan_id chan)
 {
-	struct k3_sec_proxy_msg *msg = &xfer->rx_message;
 	struct ti_sci_msg_hdr *hdr;
 	unsigned int retry = 5;
 	int ret;
@@ -138,11 +143,14 @@
  *
  * Return: 0 if all goes well, else appropriate error message
  */
-static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer)
+static int ti_sci_do_xfer(struct ti_sci_xfer *xfer)
 {
-	struct k3_sec_proxy_msg *msg = &xfer->tx_message;
+	struct k3_sec_proxy_msg *tx_msg = &xfer->tx_message;
+	struct k3_sec_proxy_msg *rx_msg = &xfer->rx_message;
 	int ret;
 
+	bakery_lock_get(&ti_sci_xfer_lock);
+
 	/* Clear any spurious messages in receive queue */
 	ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE);
 	if (ret) {
@@ -151,19 +159,23 @@
 	}
 
 	/* Send the message */
-	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg);
+	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, tx_msg);
 	if (ret) {
 		ERROR("Message sending failed (%d)\n", ret);
 		return ret;
 	}
 
-	/* Get the response */
-	ret = ti_sci_get_response(xfer, SP_RESPONSE);
-	if (ret) {
-		ERROR("Failed to get response (%d)\n", ret);
-		return ret;
+	/* Get the response if requested */
+	if (rx_msg->len != 0U) {
+		ret = ti_sci_get_response(rx_msg, SP_RESPONSE);
+		if (ret != 0U) {
+			ERROR("Failed to get response (%d)\n", ret);
+			return ret;
+		}
 	}
 
+	bakery_lock_release(&ti_sci_xfer_lock);
+
 	return 0;
 }
 
@@ -398,35 +410,27 @@
 int ti_sci_device_put_no_wait(uint32_t id)
 {
 	struct ti_sci_msg_req_set_device_state req;
-	struct ti_sci_msg_hdr *hdr;
-	struct k3_sec_proxy_msg tx_message;
+	struct ti_sci_xfer xfer;
 	int ret;
 
-	/* Ensure we have sane transfer size */
-	if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE)
-		return -ERANGE;
-
-	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = ++message_sequence;
-	hdr->type = TI_SCI_MSG_SET_DEVICE_STATE;
-	hdr->host = TI_SCI_HOST_ID;
-	/* Setup with NORESPONSE flag to keep response queue clean */
-	hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+				    &req, sizeof(req),
+				    NULL, 0,
+				    &xfer);
+	if (ret != 0U) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
 
 	req.id = id;
 	req.state = MSG_DEVICE_SW_STATE_AUTO_OFF;
 
-	tx_message.buf = (uint8_t *)&req;
-	tx_message.len = sizeof(req);
-
-	 /* Send message */
-	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
-	if (ret) {
-		ERROR("Message sending failed (%d)\n", ret);
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0U) {
+		ERROR("Transfer send failed (%d)\n", ret);
 		return ret;
 	}
 
-	/* Return without waiting for response */
 	return 0;
 }
 
@@ -1382,36 +1386,28 @@
 				      uint32_t control_flags_clear)
 {
 	struct ti_sci_msg_req_set_proc_boot_ctrl req;
-	struct ti_sci_msg_hdr *hdr;
-	struct k3_sec_proxy_msg tx_message;
+	struct ti_sci_xfer xfer;
 	int ret;
 
-	/* Ensure we have sane transfer size */
-	if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE)
-		return -ERANGE;
-
-	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = ++message_sequence;
-	hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL;
-	hdr->host = TI_SCI_HOST_ID;
-	/* Setup with NORESPONSE flag to keep response queue clean */
-	hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+				    &req, sizeof(req),
+				    NULL, 0,
+				    &xfer);
+	if (ret != 0U) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
 
 	req.processor_id = proc_id;
 	req.control_flags_set = control_flags_set;
 	req.control_flags_clear = control_flags_clear;
 
-	tx_message.buf = (uint8_t *)&req;
-	tx_message.len = sizeof(req);
-
-	 /* Send message */
-	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
-	if (ret) {
-		ERROR("Message sending failed (%d)\n", ret);
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0U) {
+		ERROR("Transfer send failed (%d)\n", ret);
 		return ret;
 	}
 
-	/* Return without waiting for response */
 	return 0;
 }
 
@@ -1624,20 +1620,17 @@
 					 uint32_t status_flags_1_clr_any_wait)
 {
 	struct ti_sci_msg_req_wait_proc_boot_status req;
-	struct ti_sci_msg_hdr *hdr;
-	struct k3_sec_proxy_msg tx_message;
+	struct ti_sci_xfer xfer;
 	int ret;
 
-	/* Ensure we have sane transfer size */
-	if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE)
-		return -ERANGE;
-
-	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = ++message_sequence;
-	hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS;
-	hdr->host = TI_SCI_HOST_ID;
-	/* Setup with NORESPONSE flag to keep response queue clean */
-	hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+				    &req, sizeof(req),
+				    NULL, 0,
+				    &xfer);
+	if (ret != 0U) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
 
 	req.processor_id = proc_id;
 	req.num_wait_iterations = num_wait_iterations;
@@ -1649,17 +1642,12 @@
 	req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
 	req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
 
-	tx_message.buf = (uint8_t *)&req;
-	tx_message.len = sizeof(req);
-
-	 /* Send message */
-	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
-	if (ret) {
-		ERROR("Message sending failed (%d)\n", ret);
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0U) {
+		ERROR("Transfer send failed (%d)\n", ret);
 		return ret;
 	}
 
-	/* Return without waiting for response */
 	return 0;
 }
 
@@ -1678,39 +1666,30 @@
 		       uint64_t core_resume_addr)
 {
 	struct ti_sci_msg_req_enter_sleep req;
-	struct ti_sci_msg_hdr *hdr;
-	struct k3_sec_proxy_msg tx_message;
+	struct ti_sci_xfer xfer;
 	int ret;
 
-	/* Ensure we have sane transfer size */
-	if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) {
-		return -ERANGE;
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+				    &req, sizeof(req),
+				    NULL, 0,
+				    &xfer);
+	if (ret != 0U) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
 	}
 
-	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = ++message_sequence;
-	hdr->type = TI_SCI_MSG_ENTER_SLEEP;
-	hdr->host = TI_SCI_HOST_ID;
-	/* Setup with NORESPONSE flag to keep response queue clean */
-	hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
-
 	req.processor_id = proc_id;
 	req.mode = mode;
 	req.core_resume_lo = core_resume_addr & TISCI_ADDR_LOW_MASK;
 	req.core_resume_hi = (core_resume_addr & TISCI_ADDR_HIGH_MASK) >>
 			     TISCI_ADDR_HIGH_SHIFT;
 
-	tx_message.buf = (uint8_t *)&req;
-	tx_message.len = sizeof(req);
-
-	/* Send message */
-	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
-	if (ret != 0) {
-		ERROR("Message sending failed (%d)\n", ret);
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0U) {
+		ERROR("Transfer send failed (%d)\n", ret);
 		return ret;
 	}
 
-	/* Return without waiting for response */
 	return 0;
 }
 
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 1b1a910..36909f5 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -73,18 +73,30 @@
 } __packed;
 
 /**
- * struct ti_sci_msg_resp_version - Response for a message
+ * struct ti_sci_msg_version_req - Request for firmware version information
+ * @hdr:	Generic header
+ *
+ * Request for TI_SCI_MSG_VERSION
+ */
+struct ti_sci_msg_req_version {
+	struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_version - Response for firmware version information
  * @hdr:		Generic header
  * @firmware_description: String describing the firmware
  * @firmware_revision:	Firmware revision
  * @abi_major:		Major version of the ABI that firmware supports
  * @abi_minor:		Minor version of the ABI that firmware supports
+ * @sub_version:	Sub-version number of the firmware
+ * @patch_version:	Patch-version number of the firmware.
  *
  * In general, ABI version changes follow the rule that minor version increments
  * are backward compatible. Major revision changes in ABI may not be
  * backward compatible.
  *
- * Response to a generic message with message type TI_SCI_MSG_VERSION
+ * Response to request TI_SCI_MSG_VERSION
  */
 struct ti_sci_msg_resp_version {
 	struct ti_sci_msg_hdr hdr;
@@ -93,6 +105,8 @@
 	uint16_t firmware_revision;
 	uint8_t abi_major;
 	uint8_t abi_minor;
+	uint8_t sub_version;
+	uint8_t patch_version;
 } __packed;
 
 /**
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 242b1ea..bbfb5bb 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -63,10 +63,6 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
-
 	/* Initialize the console to provide early debug support */
 	k3_console_setup();
 
diff --git a/plat/xilinx/common/include/plat_common.h b/plat/xilinx/common/include/plat_common.h
new file mode 100644
index 0000000..676baa2
--- /dev/null
+++ b/plat/xilinx/common/include/plat_common.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Header file to contain common macros across different platforms */
+#ifndef PLAT_COMMON_H
+#define PLAT_COMMON_H
+
+#define __bf_shf(x)            (__builtin_ffsll(x) - 1U)
+#define FIELD_GET(_mask, _reg)						\
+	({								\
+		(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\
+	})
+
+#endif /* PLAT_COMMON_H */
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index ce356f6..5270e13 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,34 +10,34 @@
 
 #include <common/bl_common.h>
 
-/* For FSBL handover */
-enum fsbl_handoff {
-	FSBL_HANDOFF_SUCCESS = 0,
-	FSBL_HANDOFF_NO_STRUCT,
-	FSBL_HANDOFF_INVAL_STRUCT,
-	FSBL_HANDOFF_TOO_MANY_PARTS
+/* For Xilinx bootloader XBL handover */
+enum xbl_handoff {
+	XBL_HANDOFF_SUCCESS = 0,
+	XBL_HANDOFF_NO_STRUCT,
+	XBL_HANDOFF_INVAL_STRUCT,
+	XBL_HANDOFF_TOO_MANY_PARTS
 };
 
-#define FSBL_MAX_PARTITIONS		8U
+#define XBL_MAX_PARTITIONS		8U
 
 /* Structure corresponding to each partition entry */
-struct xfsbl_partition {
+struct xbl_partition {
 	uint64_t entry_point;
 	uint64_t flags;
 };
 
-/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */
-struct xfsbl_atf_handoff_params {
+/* Structure for handoff parameters to TrustedFirmware-A (TF-A) */
+struct xbl_handoff_params {
 	uint8_t magic[4];
 	uint32_t num_entries;
-	struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
+	struct xbl_partition partition[XBL_MAX_PARTITIONS];
 };
 
-#define ATF_HANDOFF_PARAMS_MAX_SIZE	sizeof(struct xfsbl_atf_handoff_params)
+#define HANDOFF_PARAMS_MAX_SIZE	 sizeof(struct xbl_handoff_params)
 
-enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32,
+enum xbl_handoff xbl_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
-					uint64_t atf_handoff_addr);
+					uint64_t handoff_addr);
 
 /* JEDEC Standard Manufacturer's Identification Code and Bank ID JEP106 */
 #define JEDEC_XILINX_MFID	U(0x49)
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
similarity index 95%
rename from plat/xilinx/versal/pm_service/pm_api_sys.h
rename to plat/xilinx/common/include/pm_api_sys.h
index 8625e95..3fcb62f 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,6 +40,7 @@
 					uint8_t enable, uint32_t flag);
 enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag,
 			 uint32_t ack);
+void pm_client_set_wakeup_sources(uint32_t node_id);
 enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
 				    uint32_t value, uint32_t flag);
 enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
@@ -65,8 +66,9 @@
 enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
 					uint32_t wake, uint32_t enable,
 					uint32_t flag);
+enum pm_ret_status pm_get_chipid(uint32_t *value);
 
-/**
+/*
  * Assigning of argument values into array elements.
  */
 #define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) {	\
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index eae1d98..a87923f 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,10 @@
 void pm_client_abort_suspend(void);
 void pm_client_wakeup(const struct pm_proc *proc);
 
+#if !defined(PLAT_zynqmp)
+enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq);
+#endif
+
 /* Global variables to be set in pm_client.c */
 extern const struct pm_proc *primary_proc;
 
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index 89626e5..c0308ab 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,10 +34,11 @@
 				 TZ_VERSION_MINOR)
 
 /**
- * pm_ipi - struct for capturing IPI-channel specific info
- * @local_ipi_id	Local IPI agent ID
- * @remote_ipi_id	Remote IPI Agent ID
- * @buffer_base	base address for payload buffer
+ * struct pm_ipi - struct for capturing IPI-channel specific info.
+ * @local_ipi_id: Local IPI agent ID.
+ * @remote_ipi_id: Remote IPI Agent ID.
+ * @buffer_base: base address for payload buffer.
+ *
  */
 struct pm_ipi {
 	const uint32_t local_ipi_id;
@@ -45,11 +47,12 @@
 };
 
 /**
- * pm_proc - struct for capturing processor related info
- * @node_id	node-ID of the processor
- * @pwrdn_mask	cpu-specific mask to be used for power control register
- * @ipi		pointer to IPI channel structure
- *		(in APU all processors share one IPI channel)
+ * struct pm_proc - struct for capturing processor related info.
+ * @node_id: node-ID of the processor.
+ * @pwrdn_mask: cpu-specific mask to be used for power control register.
+ * @ipi: pointer to IPI channel structure.
+ *       (in APU all processors share one IPI channel)
+ *
  */
 struct pm_proc {
 	const uint32_t node_id;
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
new file mode 100644
index 0000000..b80cf45
--- /dev/null
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal power management enums and defines */
+
+#ifndef PM_DEFS_H
+#define PM_DEFS_H
+
+#include "pm_node.h"
+
+/*********************************************************************
+ * Macro definitions
+ ********************************************************************/
+
+/* State arguments of the self suspend */
+#define PM_STATE_CPU_IDLE	0x0U
+#define PM_STATE_SUSPEND_TO_RAM	0xFU
+
+#define MAX_LATENCY		(~0U)
+#define MAX_QOS			100U
+
+/* Processor core device IDs */
+#define APU_DEVID(IDX)	NODEID(XPM_NODECLASS_DEVICE, XPM_NODESUBCL_DEV_CORE, \
+			       XPM_NODETYPE_DEV_CORE_APU, (IDX))
+
+#define XPM_DEVID_ACPU_0	APU_DEVID(XPM_NODEIDX_DEV_ACPU_0)
+#define XPM_DEVID_ACPU_1	APU_DEVID(XPM_NODEIDX_DEV_ACPU_1)
+
+#define PERIPH_DEVID(IDX)	NODEID((uint32_t)XPM_NODECLASS_DEVICE, \
+				       (uint32_t)XPM_NODESUBCL_DEV_PERIPH, \
+				       (uint32_t)XPM_NODETYPE_DEV_PERIPH, (IDX))
+
+#define PM_GET_CALLBACK_DATA		0xa01U
+#define PM_GET_TRUSTZONE_VERSION	0xa03U
+#define TF_A_PM_REGISTER_SGI		0xa04U
+
+/* PM API Versions */
+#define PM_API_BASE_VERSION		1U
+#define PM_API_VERSION_2		2U
+
+/* Loader API ids */
+#define PM_LOAD_PDI			0x701U
+#define PM_LOAD_GET_HANDOFF_PARAMS	0x70BU
+
+/* System shutdown macros */
+#define	XPM_SHUTDOWN_TYPE_SHUTDOWN	0U
+#define	XPM_SHUTDOWN_TYPE_RESET		1U
+#define	XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY	2U
+
+#define	XPM_SHUTDOWN_SUBTYPE_RST_SUBSYSTEM	0U
+#define	XPM_SHUTDOWN_SUBTYPE_RST_PS_ONLY	1U
+#define	XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM		2U
+
+/*********************************************************************
+ * Enum definitions
+ ********************************************************************/
+
+/*
+ * ioctl id
+ */
+enum {
+	IOCTL_GET_RPU_OPER_MODE = 0,
+	IOCTL_SET_RPU_OPER_MODE = 1,
+	IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
+	IOCTL_TCM_COMB_CONFIG = 3,
+	IOCTL_SET_TAPDELAY_BYPASS = 4,
+	IOCTL_SET_SGMII_MODE = 5,
+	IOCTL_SD_DLL_RESET = 6,
+	IOCTL_SET_SD_TAPDELAY = 7,
+	 /* Ioctl for clock driver */
+	IOCTL_SET_PLL_FRAC_MODE = 8,
+	IOCTL_GET_PLL_FRAC_MODE = 9,
+	IOCTL_SET_PLL_FRAC_DATA = 10,
+	IOCTL_GET_PLL_FRAC_DATA = 11,
+	IOCTL_WRITE_GGS = 12,
+	IOCTL_READ_GGS = 13,
+	IOCTL_WRITE_PGGS = 14,
+	IOCTL_READ_PGGS = 15,
+	/* IOCTL for ULPI reset */
+	IOCTL_ULPI_RESET = 16,
+	/* Set healthy bit value */
+	IOCTL_SET_BOOT_HEALTH_STATUS = 17,
+	IOCTL_AFI = 18,
+	/* Probe counter read/write */
+	IOCTL_PROBE_COUNTER_READ = 19,
+	IOCTL_PROBE_COUNTER_WRITE = 20,
+	IOCTL_OSPI_MUX_SELECT = 21,
+	/* IOCTL for USB power request */
+	IOCTL_USB_SET_STATE = 22,
+	/* IOCTL to get last reset reason */
+	IOCTL_GET_LAST_RESET_REASON = 23,
+	/* AI engine NPI ISR clear */
+	IOCTL_AIE_ISR_CLEAR = 24,
+	/* Register SGI to TF-A */
+	IOCTL_SET_SGI = 25,
+};
+
+/**
+ * enum pm_pll_param - enum represents the parameters for a phase-locked loop.
+ * @PM_PLL_PARAM_DIV2: Enable for divide by 2 function inside the PLL.
+ * @PM_PLL_PARAM_FBDIV: Feedback divisor integer portion for the PLL.
+ * @PM_PLL_PARAM_DATA: Feedback divisor fractional portion for the PLL.
+ * @PM_PLL_PARAM_PRE_SRC: Clock source for PLL input.
+ * @PM_PLL_PARAM_POST_SRC: Clock source for PLL Bypass mode.
+ * @PM_PLL_PARAM_LOCK_DLY: Lock circuit config settings for lock windowsize.
+ * @PM_PLL_PARAM_LOCK_CNT: Lock circuit counter setting.
+ * @PM_PLL_PARAM_LFHF: PLL loop filter high frequency capacitor control.
+ * @PM_PLL_PARAM_CP: PLL charge pump control.
+ * @PM_PLL_PARAM_RES: PLL loop filter resistor control.
+ * @PM_PLL_PARAM_MAX: Represents the maximum parameter value for the PLL
+ */
+enum pm_pll_param {
+	PM_PLL_PARAM_DIV2,
+	PM_PLL_PARAM_FBDIV,
+	PM_PLL_PARAM_DATA,
+	PM_PLL_PARAM_PRE_SRC,
+	PM_PLL_PARAM_POST_SRC,
+	PM_PLL_PARAM_LOCK_DLY,
+	PM_PLL_PARAM_LOCK_CNT,
+	PM_PLL_PARAM_LFHF,
+	PM_PLL_PARAM_CP,
+	PM_PLL_PARAM_RES,
+	PM_PLL_PARAM_MAX,
+};
+
+enum pm_api_id {
+	/* Miscellaneous API functions: */
+	PM_GET_API_VERSION = 1, /* Do not change or move */
+	PM_SET_CONFIGURATION,
+	PM_GET_NODE_STATUS,
+	PM_GET_OP_CHARACTERISTIC,
+	PM_REGISTER_NOTIFIER,
+	/* API for suspending of PUs: */
+	PM_REQ_SUSPEND,
+	PM_SELF_SUSPEND,
+	PM_FORCE_POWERDOWN,
+	PM_ABORT_SUSPEND,
+	PM_REQ_WAKEUP,
+	PM_SET_WAKEUP_SOURCE,
+	PM_SYSTEM_SHUTDOWN,
+	/* API for managing PM slaves: */
+	PM_REQ_NODE,
+	PM_RELEASE_NODE,
+	PM_SET_REQUIREMENT,
+	PM_SET_MAX_LATENCY,
+	/* Direct control API functions: */
+	PM_RESET_ASSERT,
+	PM_RESET_GET_STATUS,
+	PM_MMIO_WRITE,
+	PM_MMIO_READ,
+	PM_INIT_FINALIZE,
+	PM_FPGA_LOAD,
+	PM_FPGA_GET_STATUS,
+	PM_GET_CHIPID,
+	PM_SECURE_RSA_AES,
+	PM_SECURE_SHA,
+	PM_SECURE_RSA,
+	PM_PINCTRL_REQUEST,
+	PM_PINCTRL_RELEASE,
+	PM_PINCTRL_GET_FUNCTION,
+	PM_PINCTRL_SET_FUNCTION,
+	PM_PINCTRL_CONFIG_PARAM_GET,
+	PM_PINCTRL_CONFIG_PARAM_SET,
+	PM_IOCTL,
+	/* API to query information from firmware */
+	PM_QUERY_DATA,
+	/* Clock control API functions */
+	PM_CLOCK_ENABLE,
+	PM_CLOCK_DISABLE,
+	PM_CLOCK_GETSTATE,
+	PM_CLOCK_SETDIVIDER,
+	PM_CLOCK_GETDIVIDER,
+	PM_CLOCK_SETRATE,
+	PM_CLOCK_GETRATE,
+	PM_CLOCK_SETPARENT,
+	PM_CLOCK_GETPARENT,
+	PM_SECURE_IMAGE,
+	/* FPGA PL Readback */
+	PM_FPGA_READ,
+	PM_SECURE_AES,
+	/* PLL control API functions */
+	PM_PLL_SET_PARAMETER,
+	PM_PLL_GET_PARAMETER,
+	PM_PLL_SET_MODE,
+	PM_PLL_GET_MODE,
+	/* PM Register Access API */
+	PM_REGISTER_ACCESS,
+	PM_EFUSE_ACCESS,
+	PM_FPGA_GET_VERSION,
+	PM_FPGA_GET_FEATURE_LIST,
+	PM_FEATURE_CHECK = 63,
+	PM_API_MAX = 74
+};
+
+enum pm_abort_reason {
+	ABORT_REASON_WKUP_EVENT = 100,
+	ABORT_REASON_PU_BUSY,
+	ABORT_REASON_NO_PWRDN,
+	ABORT_REASON_UNKNOWN,
+};
+
+enum pm_opchar_type {
+	PM_OPCHAR_TYPE_POWER = 1,
+	PM_OPCHAR_TYPE_TEMP,
+	PM_OPCHAR_TYPE_LATENCY,
+};
+
+/*
+ * Subsystem IDs
+ */
+typedef enum {
+	XPM_SUBSYSID_PMC,
+	XPM_SUBSYSID_PSM,
+	XPM_SUBSYSID_APU,
+	XPM_SUBSYSID_RPU0_LOCK,
+	XPM_SUBSYSID_RPU0_0,
+	XPM_SUBSYSID_RPU0_1,
+	XPM_SUBSYSID_DDR0,
+	XPM_SUBSYSID_ME,
+	XPM_SUBSYSID_PL,
+	XPM_SUBSYSID_MAX,
+} XPm_SubsystemId;
+
+/* TODO: move pm_ret_status from device specific location to common location */
+/**
+ * enum pm_ret_status - enum represents the return status codes for a PM
+ *                      operation.
+ * @PM_RET_SUCCESS: success.
+ * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated).
+ * @PM_RET_ERROR_NOTSUPPORTED: feature not supported  (deprecated).
+ * @PM_RET_ERROR_NOFEATURE: feature is not available.
+ * @PM_RET_ERROR_INVALID_CRC: invalid crc in IPI communication.
+ * @PM_RET_ERROR_NOT_ENABLED: feature is not enabled.
+ * @PM_RET_ERROR_INTERNAL: internal error.
+ * @PM_RET_ERROR_CONFLICT: conflict.
+ * @PM_RET_ERROR_ACCESS: access rights violation.
+ * @PM_RET_ERROR_INVALID_NODE: invalid node.
+ * @PM_RET_ERROR_DOUBLE_REQ: duplicate request for same node.
+ * @PM_RET_ERROR_ABORT_SUSPEND: suspend procedure has been aborted.
+ * @PM_RET_ERROR_TIMEOUT: timeout in communication with PMU.
+ * @PM_RET_ERROR_NODE_USED: node is already in use.
+ * @PM_RET_ERROR_NO_FEATURE: indicates that the requested feature is not
+ *                           supported.
+ */
+enum pm_ret_status {
+	PM_RET_SUCCESS,
+	PM_RET_ERROR_ARGS = 1,
+	PM_RET_ERROR_NOTSUPPORTED = 4,
+	PM_RET_ERROR_NOFEATURE = 19,
+	PM_RET_ERROR_INVALID_CRC = 301,
+	PM_RET_ERROR_NOT_ENABLED = 29,
+	PM_RET_ERROR_INTERNAL = 2000,
+	PM_RET_ERROR_CONFLICT = 2001,
+	PM_RET_ERROR_ACCESS = 2002,
+	PM_RET_ERROR_INVALID_NODE = 2003,
+	PM_RET_ERROR_DOUBLE_REQ = 2004,
+	PM_RET_ERROR_ABORT_SUSPEND = 2005,
+	PM_RET_ERROR_TIMEOUT = 2006,
+	PM_RET_ERROR_NODE_USED = 2007,
+	PM_RET_ERROR_NO_FEATURE = 2008
+};
+
+/*
+ * Qids
+ */
+enum pm_query_id {
+	XPM_QID_INVALID,
+	XPM_QID_CLOCK_GET_NAME,
+	XPM_QID_CLOCK_GET_TOPOLOGY,
+	XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
+	XPM_QID_CLOCK_GET_MUXSOURCES,
+	XPM_QID_CLOCK_GET_ATTRIBUTES,
+	XPM_QID_PINCTRL_GET_NUM_PINS,
+	XPM_QID_PINCTRL_GET_NUM_FUNCTIONS,
+	XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
+	XPM_QID_PINCTRL_GET_FUNCTION_NAME,
+	XPM_QID_PINCTRL_GET_FUNCTION_GROUPS,
+	XPM_QID_PINCTRL_GET_PIN_GROUPS,
+	XPM_QID_CLOCK_GET_NUM_CLOCKS,
+	XPM_QID_CLOCK_GET_MAX_DIVISOR,
+	XPM_QID_PLD_GET_PARENT,
+};
+#endif /* PM_DEFS_H */
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index ede71df..976abd6 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
  * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
@@ -9,8 +9,9 @@
 #ifndef PM_IPI_H
 #define PM_IPI_H
 
-#include <plat_ipi.h>
 #include <stddef.h>
+
+#include <plat_ipi.h>
 #include "pm_common.h"
 
 #define IPI_BLOCKING		1
diff --git a/plat/xilinx/common/include/pm_node.h b/plat/xilinx/common/include/pm_node.h
new file mode 100644
index 0000000..46f6bcf
--- /dev/null
+++ b/plat/xilinx/common/include/pm_node.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal PM nodes enums and defines */
+
+#ifndef PM_NODE_H
+#define PM_NODE_H
+
+/*********************************************************************
+ * Macro definitions
+ ********************************************************************/
+
+#define NODE_CLASS_SHIFT	26U
+#define NODE_SUBCLASS_SHIFT	20U
+#define NODE_TYPE_SHIFT		14U
+#define NODE_INDEX_SHIFT	0U
+#define NODE_CLASS_MASK_BITS    GENMASK_32(5, 0)
+#define NODE_SUBCLASS_MASK_BITS GENMASK_32(5, 0)
+#define NODE_TYPE_MASK_BITS     GENMASK_32(5, 0)
+#define NODE_INDEX_MASK_BITS    GENMASK_32(13, 0)
+#define NODE_CLASS_MASK         (NODE_CLASS_MASK_BITS << NODE_CLASS_SHIFT)
+#define NODE_SUBCLASS_MASK      (NODE_SUBCLASS_MASK_BITS << NODE_SUBCLASS_SHIFT)
+#define NODE_TYPE_MASK          (NODE_TYPE_MASK_BITS << NODE_TYPE_SHIFT)
+#define NODE_INDEX_MASK         (NODE_INDEX_MASK_BITS << NODE_INDEX_SHIFT)
+
+#define NODEID(CLASS, SUBCLASS, TYPE, INDEX)	\
+	     ((((CLASS) & NODE_CLASS_MASK_BITS) << NODE_CLASS_SHIFT) | \
+	     (((SUBCLASS) & NODE_SUBCLASS_MASK_BITS) << NODE_SUBCLASS_SHIFT) | \
+	     (((TYPE) & NODE_TYPE_MASK_BITS) << NODE_TYPE_SHIFT) | \
+	     (((INDEX) & NODE_INDEX_MASK_BITS) << NODE_INDEX_SHIFT))
+
+#define NODECLASS(ID)		(((ID) & NODE_CLASS_MASK) >> NODE_CLASS_SHIFT)
+#define NODESUBCLASS(ID)	(((ID) & NODE_SUBCLASS_MASK) >> \
+				NODE_SUBCLASS_SHIFT)
+#define NODETYPE(ID)		(((ID) & NODE_TYPE_MASK) >> NODE_TYPE_SHIFT)
+#define NODEINDEX(ID)		(((ID) & NODE_INDEX_MASK) >> NODE_INDEX_SHIFT)
+
+/*********************************************************************
+ * Enum definitions
+ ********************************************************************/
+
+/* Node class types */
+enum pm_node_class {
+	XPM_NODECLASS_MIN,
+
+	XPM_NODECLASS_POWER,
+	XPM_NODECLASS_CLOCK,
+	XPM_NODECLASS_RESET,
+	XPM_NODECLASS_MEMIC,
+	XPM_NODECLASS_STMIC,
+	XPM_NODECLASS_DEVICE,
+
+	XPM_NODECLASS_MAX
+};
+
+enum pm_device_node_subclass {
+	/* Device types */
+	XPM_NODESUBCL_DEV_CORE = 1,
+	XPM_NODESUBCL_DEV_PERIPH,
+	XPM_NODESUBCL_DEV_MEM,
+	XPM_NODESUBCL_DEV_SOC,
+	XPM_NODESUBCL_DEV_MEM_CTRLR,
+	XPM_NODESUBCL_DEV_PHY,
+};
+
+enum pm_device_node_type {
+	/* Device types */
+	XPM_NODETYPE_DEV_CORE_PMC = 1,
+	XPM_NODETYPE_DEV_CORE_PSM,
+	XPM_NODETYPE_DEV_CORE_APU,
+	XPM_NODETYPE_DEV_CORE_RPU,
+	XPM_NODETYPE_DEV_OCM,
+	XPM_NODETYPE_DEV_TCM,
+	XPM_NODETYPE_DEV_L2CACHE,
+	XPM_NODETYPE_DEV_DDR,
+	XPM_NODETYPE_DEV_PERIPH,
+	XPM_NODETYPE_DEV_SOC,
+	XPM_NODETYPE_DEV_GT,
+};
+
+/* Device node Indexes */
+enum pm_device_node_idx {
+	/* Device nodes */
+	XPM_NODEIDX_DEV_MIN = 0x0,
+
+	/* Processor devices */
+	XPM_NODEIDX_DEV_PMC_PROC = 0x1,
+	XPM_NODEIDX_DEV_PSM_PROC = 0x2,
+	XPM_NODEIDX_DEV_ACPU_0 = 0x3,
+	XPM_NODEIDX_DEV_ACPU_1 = 0x4,
+	XPM_NODEIDX_DEV_RPU0_0 = 0x5,
+	XPM_NODEIDX_DEV_RPU0_1 = 0x6,
+
+	/* Memory devices */
+	XPM_NODEIDX_DEV_OCM_0 = 0x7,
+	XPM_NODEIDX_DEV_OCM_1 = 0x8,
+	XPM_NODEIDX_DEV_OCM_2 = 0x9,
+	XPM_NODEIDX_DEV_OCM_3 = 0xA,
+	XPM_NODEIDX_DEV_TCM_0_A = 0xB,
+	XPM_NODEIDX_DEV_TCM_0_B = 0xC,
+	XPM_NODEIDX_DEV_TCM_1_A = 0xD,
+	XPM_NODEIDX_DEV_TCM_1_B = 0xE,
+	XPM_NODEIDX_DEV_L2_BANK_0 = 0xF,
+	XPM_NODEIDX_DEV_DDR_0 = 0x10,
+	XPM_NODEIDX_DEV_DDR_1 = 0x11,
+	XPM_NODEIDX_DEV_DDR_2 = 0x12,
+	XPM_NODEIDX_DEV_DDR_3 = 0x13,
+	XPM_NODEIDX_DEV_DDR_4 = 0x14,
+	XPM_NODEIDX_DEV_DDR_5 = 0x15,
+	XPM_NODEIDX_DEV_DDR_6 = 0x16,
+	XPM_NODEIDX_DEV_DDR_7 = 0x17,
+
+	/* LPD Peripheral devices */
+	XPM_NODEIDX_DEV_USB_0 = 0x18,
+	XPM_NODEIDX_DEV_GEM_0 = 0x19,
+	XPM_NODEIDX_DEV_GEM_1 = 0x1A,
+	XPM_NODEIDX_DEV_SPI_0 = 0x1B,
+	XPM_NODEIDX_DEV_SPI_1 = 0x1C,
+	XPM_NODEIDX_DEV_I2C_0 = 0x1D,
+	XPM_NODEIDX_DEV_I2C_1 = 0x1E,
+	XPM_NODEIDX_DEV_CAN_FD_0 = 0x1F,
+	XPM_NODEIDX_DEV_CAN_FD_1 = 0x20,
+	XPM_NODEIDX_DEV_UART_0 = 0x21,
+	XPM_NODEIDX_DEV_UART_1 = 0x22,
+	XPM_NODEIDX_DEV_GPIO = 0x23,
+	XPM_NODEIDX_DEV_TTC_0 = 0x24,
+	XPM_NODEIDX_DEV_TTC_1 = 0x25,
+	XPM_NODEIDX_DEV_TTC_2 = 0x26,
+	XPM_NODEIDX_DEV_TTC_3 = 0x27,
+	XPM_NODEIDX_DEV_SWDT_LPD = 0x28,
+
+	/* FPD Peripheral devices */
+	XPM_NODEIDX_DEV_SWDT_FPD = 0x29,
+
+	/* PMC Peripheral devices */
+	XPM_NODEIDX_DEV_OSPI = 0x2A,
+	XPM_NODEIDX_DEV_QSPI = 0x2B,
+	XPM_NODEIDX_DEV_GPIO_PMC = 0x2C,
+	XPM_NODEIDX_DEV_I2C_PMC = 0x2D,
+	XPM_NODEIDX_DEV_SDIO_0 = 0x2E,
+	XPM_NODEIDX_DEV_SDIO_1 = 0x2F,
+
+	XPM_NODEIDX_DEV_PL_0 = 0x30,
+	XPM_NODEIDX_DEV_PL_1 = 0x31,
+	XPM_NODEIDX_DEV_PL_2 = 0x32,
+	XPM_NODEIDX_DEV_PL_3 = 0x33,
+	XPM_NODEIDX_DEV_RTC = 0x34,
+	XPM_NODEIDX_DEV_ADMA_0 = 0x35,
+	XPM_NODEIDX_DEV_ADMA_1 = 0x36,
+	XPM_NODEIDX_DEV_ADMA_2 = 0x37,
+	XPM_NODEIDX_DEV_ADMA_3 = 0x38,
+	XPM_NODEIDX_DEV_ADMA_4 = 0x39,
+	XPM_NODEIDX_DEV_ADMA_5 = 0x3A,
+	XPM_NODEIDX_DEV_ADMA_6 = 0x3B,
+	XPM_NODEIDX_DEV_ADMA_7 = 0x3C,
+	XPM_NODEIDX_DEV_IPI_0 = 0x3D,
+	XPM_NODEIDX_DEV_IPI_1 = 0x3E,
+	XPM_NODEIDX_DEV_IPI_2 = 0x3F,
+	XPM_NODEIDX_DEV_IPI_3 = 0x40,
+	XPM_NODEIDX_DEV_IPI_4 = 0x41,
+	XPM_NODEIDX_DEV_IPI_5 = 0x42,
+	XPM_NODEIDX_DEV_IPI_6 = 0x43,
+
+	/* Entire SoC */
+	XPM_NODEIDX_DEV_SOC = 0x44,
+
+	/* DDR memory controllers */
+	XPM_NODEIDX_DEV_DDRMC_0 = 0x45,
+	XPM_NODEIDX_DEV_DDRMC_1 = 0x46,
+	XPM_NODEIDX_DEV_DDRMC_2 = 0x47,
+	XPM_NODEIDX_DEV_DDRMC_3 = 0x48,
+
+	/* GT devices */
+	XPM_NODEIDX_DEV_GT_0 = 0x49,
+	XPM_NODEIDX_DEV_GT_1 = 0x4A,
+	XPM_NODEIDX_DEV_GT_2 = 0x4B,
+	XPM_NODEIDX_DEV_GT_3 = 0x4C,
+	XPM_NODEIDX_DEV_GT_4 = 0x4D,
+	XPM_NODEIDX_DEV_GT_5 = 0x4E,
+	XPM_NODEIDX_DEV_GT_6 = 0x4F,
+	XPM_NODEIDX_DEV_GT_7 = 0x50,
+	XPM_NODEIDX_DEV_GT_8 = 0x51,
+	XPM_NODEIDX_DEV_GT_9 = 0x52,
+	XPM_NODEIDX_DEV_GT_10 = 0x53,
+
+#if defined(PLAT_versal_net)
+	XPM_NODEIDX_DEV_ACPU_0_0 = 0xAF,
+	XPM_NODEIDX_DEV_ACPU_0_1 = 0xB0,
+	XPM_NODEIDX_DEV_ACPU_0_2 = 0xB1,
+	XPM_NODEIDX_DEV_ACPU_0_3 = 0xB2,
+	XPM_NODEIDX_DEV_ACPU_1_0 = 0xB3,
+	XPM_NODEIDX_DEV_ACPU_1_1 = 0xB4,
+	XPM_NODEIDX_DEV_ACPU_1_2 = 0xB5,
+	XPM_NODEIDX_DEV_ACPU_1_3 = 0xB6,
+	XPM_NODEIDX_DEV_ACPU_2_0 = 0xB7,
+	XPM_NODEIDX_DEV_ACPU_2_1 = 0xB8,
+	XPM_NODEIDX_DEV_ACPU_2_2 = 0xB9,
+	XPM_NODEIDX_DEV_ACPU_2_3 = 0xBA,
+	XPM_NODEIDX_DEV_ACPU_3_0 = 0xBB,
+	XPM_NODEIDX_DEV_ACPU_3_1 = 0xBC,
+	XPM_NODEIDX_DEV_ACPU_3_2 = 0xBD,
+	XPM_NODEIDX_DEV_ACPU_3_3 = 0xBE,
+	XPM_NODEIDX_DEV_RPU_A_0 = 0xBF,
+	XPM_NODEIDX_DEV_RPU_A_1 = 0xC0,
+	XPM_NODEIDX_DEV_RPU_B_0 = 0xC1,
+	XPM_NODEIDX_DEV_RPU_B_1 = 0xC2,
+	XPM_NODEIDX_DEV_OCM_0_0 = 0xC3,
+	XPM_NODEIDX_DEV_OCM_0_1 = 0xC4,
+	XPM_NODEIDX_DEV_OCM_0_2 = 0xC5,
+	XPM_NODEIDX_DEV_OCM_0_3 = 0xC6,
+	XPM_NODEIDX_DEV_OCM_1_0 = 0xC7,
+	XPM_NODEIDX_DEV_OCM_1_1 = 0xC8,
+	XPM_NODEIDX_DEV_OCM_1_2 = 0xC9,
+	XPM_NODEIDX_DEV_OCM_1_3 = 0xCA,
+	XPM_NODEIDX_DEV_TCM_A_0A = 0xCB,
+	XPM_NODEIDX_DEV_TCM_A_0B = 0xCC,
+	XPM_NODEIDX_DEV_TCM_A_0C = 0xCD,
+	XPM_NODEIDX_DEV_TCM_A_1A = 0xCE,
+	XPM_NODEIDX_DEV_TCM_A_1B = 0xCF,
+	XPM_NODEIDX_DEV_TCM_A_1C = 0xD0,
+	XPM_NODEIDX_DEV_TCM_B_0A = 0xD1,
+	XPM_NODEIDX_DEV_TCM_B_0B = 0xD2,
+	XPM_NODEIDX_DEV_TCM_B_0C = 0xD3,
+	XPM_NODEIDX_DEV_TCM_B_1A = 0xD4,
+	XPM_NODEIDX_DEV_TCM_B_1B = 0xD5,
+	XPM_NODEIDX_DEV_TCM_B_1C = 0xD6,
+	XPM_NODEIDX_DEV_USB_1 = 0xD7,
+	XPM_NODEIDX_DEV_PMC_WWDT = 0xD8,
+	XPM_NODEIDX_DEV_LPD_SWDT_0 = 0xD9,
+	XPM_NODEIDX_DEV_LPD_SWDT_1 = 0xDA,
+	XPM_NODEIDX_DEV_FPD_SWDT_0 = 0xDB,
+	XPM_NODEIDX_DEV_FPD_SWDT_1 = 0xDC,
+	XPM_NODEIDX_DEV_FPD_SWDT_2 = 0xDD,
+	XPM_NODEIDX_DEV_FPD_SWDT_3 = 0xDE,
+#endif
+	XPM_NODEIDX_DEV_MAX,
+};
+
+#endif /* PM_NODE_H */
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
similarity index 84%
rename from plat/xilinx/versal/pm_service/pm_svc_main.h
rename to plat/xilinx/common/include/pm_svc_main.h
index b6e764f..1a27bdf 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 8fa7bc5..399d283 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -1,6 +1,7 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,10 +46,9 @@
 static uint32_t ipi_total;
 
 /**
- * ipi_config_init() - Initialize IPI configuration data
- *
- * @ipi_config_table  - IPI configuration table
- * @ipi_total - Total number of IPI available
+ * ipi_config_table_init() - Initialize IPI configuration data.
+ * @ipi_config_table: IPI configuration table.
+ * @total_ipi: Total number of IPI available.
  *
  */
 void ipi_config_table_init(const struct ipi_config *ipi_config_table,
@@ -58,12 +58,13 @@
 	ipi_total = total_ipi;
 }
 
-/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
+/**
+ * is_ipi_mb_within_range() - verify if IPI mailbox is within range.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * Return: - 1 if within range, 0 if not.
  *
- * return - 1 if within range, 0 if not
  */
 static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
 {
@@ -77,13 +78,13 @@
 }
 
 /**
- * ipi_mb_validate() - validate IPI mailbox access
+ * ipi_mb_validate() - validate IPI mailbox access.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
+ * @is_secure: indicate if the requester is from secure software.
  *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- * @is_secure - indicate if the requester is from secure software
+ * Return: 0 success, negative value for errors.
  *
- * return - 0 success, negative value for errors
  */
 int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
 {
@@ -104,9 +105,8 @@
 
 /**
  * ipi_mb_open() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  */
 void ipi_mb_open(uint32_t local, uint32_t remote)
@@ -119,9 +119,8 @@
 
 /**
  * ipi_mb_release() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  */
 void ipi_mb_release(uint32_t local, uint32_t remote)
@@ -131,13 +130,13 @@
 }
 
 /**
- * ipi_mb_enquire_status() - Enquire IPI mailbox status
+ * ipi_mb_enquire_status() - Enquire IPI mailbox status.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * Return: 0 idle, positive value for pending sending or receiving,
+ *         negative value for errors.
  *
- * return - 0 idle, positive value for pending sending or receiving,
- *          negative value for errors
  */
 int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
 {
@@ -156,11 +155,11 @@
 	return ret;
 }
 
-/* ipi_mb_notify() - Trigger IPI mailbox notification
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- * @is_blocking - if to trigger the notification in blocking mode or not.
+/**
+ * ipi_mb_notify() - Trigger IPI mailbox notification.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
+ * @is_blocking: if to trigger the notification in blocking mode or not.
  *
  * It sets the remote bit in the IPI agent trigger register.
  *
@@ -179,10 +178,10 @@
 	}
 }
 
-/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
+/**
+ * ipi_mb_ack() - Ack IPI mailbox notification from the other end.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  * It will clear the remote bit in the isr register.
  *
@@ -193,10 +192,10 @@
 		      IPI_BIT_MASK(remote));
 }
 
-/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
+/**
+ * ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  * It will mask the remote bit in the idr register.
  *
@@ -207,10 +206,10 @@
 		      IPI_BIT_MASK(remote));
 }
 
-/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
+/**
+ * ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  * It will mask the remote bit in the idr register.
  *
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 8438aba..434cd88 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,11 +18,10 @@
 #include <lib/mmio.h>
 
 #include <ipi.h>
+#include "ipi_mailbox_svc.h"
 #include <plat_ipi.h>
 #include <plat_private.h>
 
-#include "ipi_mailbox_svc.h"
-
 /*********************************************************************
  * Macros definitions
  ********************************************************************/
@@ -46,21 +46,25 @@
 #define UNSIGNED32_MASK			0xFFFFFFFFU /* 32bit mask */
 
 /**
- * ipi_smc_handler() - SMC handler for IPI SMC calls
+ * ipi_smc_handler() - SMC handler for IPI SMC calls.
+ * @smc_fid: Function identifier.
+ * @x1: Arguments.
+ * @x2: Arguments.
+ * @x3: Arguments.
+ * @x4: Arguments.
+ * @cookie: Unused.
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
- * @smc_fid - Function identifier
- * @x1 - x4 - Arguments
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
- *
- * @return  - Unused
+ * Return: Unused.
  *
  * Determines that smc_fid is valid and supported PM SMC Function ID from the
  * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * the unknown SMC Function ID.
  *
  * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * function with rt_svc_handle signature.
+ *
  */
 uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 			 uint64_t x3, uint64_t x4, const void *cookie,
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
index af13db9..9198a98 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index de9cf4d..f45c9f0 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) 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
+ * HandoffParams
  * Parameter		bitfield	encoding
  * -----------------------------------------------------------------------------
  * Exec State		0		0 -> Aarch64, 1-> Aarch32
@@ -22,93 +23,104 @@
  * secure (TZ)		2		0 -> Non secure, 1 -> secure
  * EL			3:4		00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3
  * CPU#			5:6		00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
+ * Reserved		7:10		Reserved
+ * Cluster#		11:12		00 -> Cluster 0, 01 -> Cluster 1, 10 -> Cluster 2,
+ *					11 -> Cluster (Applicable for Versal NET only).
+ * Reserved		13:16		Reserved
  */
 
-#define FSBL_FLAGS_ESTATE_SHIFT		0U
-#define FSBL_FLAGS_ESTATE_MASK		(1U << FSBL_FLAGS_ESTATE_SHIFT)
-#define FSBL_FLAGS_ESTATE_A64		0U
-#define FSBL_FLAGS_ESTATE_A32		1U
+#define XBL_FLAGS_ESTATE_SHIFT		0U
+#define XBL_FLAGS_ESTATE_MASK		(1U << XBL_FLAGS_ESTATE_SHIFT)
+#define XBL_FLAGS_ESTATE_A64		0U
+#define XBL_FLAGS_ESTATE_A32		1U
 
-#define FSBL_FLAGS_ENDIAN_SHIFT		1U
-#define FSBL_FLAGS_ENDIAN_MASK		(1U << FSBL_FLAGS_ENDIAN_SHIFT)
-#define FSBL_FLAGS_ENDIAN_LE		0U
-#define FSBL_FLAGS_ENDIAN_BE		1U
+#define XBL_FLAGS_ENDIAN_SHIFT		1U
+#define XBL_FLAGS_ENDIAN_MASK		(1U << XBL_FLAGS_ENDIAN_SHIFT)
+#define XBL_FLAGS_ENDIAN_LE		0U
+#define XBL_FLAGS_ENDIAN_BE		1U
 
-#define FSBL_FLAGS_TZ_SHIFT		2U
-#define FSBL_FLAGS_TZ_MASK		(1U << FSBL_FLAGS_TZ_SHIFT)
-#define FSBL_FLAGS_NON_SECURE		0U
-#define FSBL_FLAGS_SECURE		1U
+#define XBL_FLAGS_TZ_SHIFT		2U
+#define XBL_FLAGS_TZ_MASK		(1U << XBL_FLAGS_TZ_SHIFT)
+#define XBL_FLAGS_NON_SECURE		0U
+#define XBL_FLAGS_SECURE		1U
 
-#define FSBL_FLAGS_EL_SHIFT		3U
-#define FSBL_FLAGS_EL_MASK		(3U << FSBL_FLAGS_EL_SHIFT)
-#define FSBL_FLAGS_EL0			0U
-#define FSBL_FLAGS_EL1			1U
-#define FSBL_FLAGS_EL2			2U
-#define FSBL_FLAGS_EL3			3U
+#define XBL_FLAGS_EL_SHIFT		3U
+#define XBL_FLAGS_EL_MASK		(3U << XBL_FLAGS_EL_SHIFT)
+#define XBL_FLAGS_EL0			0U
+#define XBL_FLAGS_EL1			1U
+#define XBL_FLAGS_EL2			2U
+#define XBL_FLAGS_EL3			3U
 
-#define FSBL_FLAGS_CPU_SHIFT		5U
-#define FSBL_FLAGS_CPU_MASK		(3U << FSBL_FLAGS_CPU_SHIFT)
-#define FSBL_FLAGS_A53_0		0U
-#define FSBL_FLAGS_A53_1		1U
-#define FSBL_FLAGS_A53_2		2U
-#define FSBL_FLAGS_A53_3		3U
+#define XBL_FLAGS_CPU_SHIFT		5U
+#define XBL_FLAGS_CPU_MASK		(3U << XBL_FLAGS_CPU_SHIFT)
+#define XBL_FLAGS_A53_0		0U
+#define XBL_FLAGS_A53_1		1U
+#define XBL_FLAGS_A53_2		2U
+#define XBL_FLAGS_A53_3		3U
+
+#if defined(PLAT_versal_net)
+#define XBL_FLAGS_CLUSTER_SHIFT		11U
+#define XBL_FLAGS_CLUSTER_MASK		GENMASK(11, 12)
+
+#define XBL_FLAGS_CLUSTER_0		0U
+#endif /* PLAT_versal_net */
 
 /**
- * @partition: Pointer to partition struct
+ * get_xbl_cpu() - Get the target CPU for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target CPU for @partition.
+ * Return: XBL_FLAGS_A53_0, XBL_FLAGS_A53_1, XBL_FLAGS_A53_2 or XBL_FLAGS_A53_3.
  *
- * Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or FSBL_FLAGS_A53_3
  */
-static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
+static int32_t get_xbl_cpu(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_CPU_MASK;
 
-	return flags >> FSBL_FLAGS_CPU_SHIFT;
+	return flags >> XBL_FLAGS_CPU_SHIFT;
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_xbl_el() - Get the target exception level for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target exception level for @partition.
+ * Return: XBL_FLAGS_EL0, XBL_FLAGS_EL1, XBL_FLAGS_EL2 or XBL_FLAGS_EL3.
  *
- * Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3
  */
-static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
+static int32_t get_xbl_el(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_EL_MASK;
 
-	return flags >> FSBL_FLAGS_EL_SHIFT;
+	return flags >> XBL_FLAGS_EL_SHIFT;
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_xbl_ss() - Get the target security state for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target security state for @partition.
+ * Return: XBL_FLAGS_NON_SECURE or XBL_FLAGS_SECURE.
  *
- * Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE
  */
-static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
+static int32_t get_xbl_ss(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_TZ_MASK;
 
-	return flags >> FSBL_FLAGS_TZ_SHIFT;
+	return flags >> XBL_FLAGS_TZ_SHIFT;
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_xbl_endian() - Get the target endianness for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target endianness for @partition.
+ * Return: SPSR_E_LITTLE or SPSR_E_BIG.
  *
- * Return: SPSR_E_LITTLE or SPSR_E_BIG
  */
-static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
+static int32_t get_xbl_endian(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_ENDIAN_MASK;
 
-	flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
+	flags >>= XBL_FLAGS_ENDIAN_SHIFT;
 
-	if (flags == FSBL_FLAGS_ENDIAN_BE) {
+	if (flags == XBL_FLAGS_ENDIAN_BE) {
 		return SPSR_E_BIG;
 	} else {
 		return SPSR_E_LITTLE;
@@ -116,57 +128,73 @@
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_xbl_estate() - Get the target execution state for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target execution state for @partition.
+ * Return: XBL_FLAGS_ESTATE_A32 or XBL_FLAGS_ESTATE_A64.
  *
- * Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64
  */
-static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
+static int32_t get_xbl_estate(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_ESTATE_MASK;
 
-	return flags >> FSBL_FLAGS_ESTATE_SHIFT;
+	return flags >> XBL_FLAGS_ESTATE_SHIFT;
 }
 
+#if defined(PLAT_versal_net)
 /**
- * Populates the bl32 and bl33 image info structures
- * @bl32:	BL32 image info structure
- * @bl33:	BL33 image info structure
- * atf_handoff_addr:  ATF handoff address
+ * get_xbl_cluster - Get the cluster number
+ * @partition: pointer to the partition structure.
  *
- * Process the handoff paramters from the FSBL and populate the BL32 and BL33
+ * Return: cluster number for the partition.
+ */
+static int32_t get_xbl_cluster(const struct xbl_partition *partition)
+{
+	uint64_t flags = partition->flags & XBL_FLAGS_CLUSTER_MASK;
+
+	return (int32_t)(flags >> XBL_FLAGS_CLUSTER_SHIFT);
+}
+#endif /* PLAT_versal_net */
+
+/**
+ * xbl_tfa_handover() - Populates the bl32 and bl33 image info structures.
+ * @bl32: BL32 image info structure.
+ * @bl33: BL33 image info structure.
+ * @tfa_handoff_addr: TF-A handoff address.
+ *
+ * Process the handoff parameters from the XBL and populate the BL32 and BL33
  * image info structures accordingly.
  *
  * Return: Return the status of the handoff. The value will be from the
- *         fsbl_handoff enum.
+ *         xbl_handoff enum.
+ *
  */
-enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32,
+enum xbl_handoff xbl_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
-					uint64_t atf_handoff_addr)
+					uint64_t handoff_addr)
 {
-	const struct xfsbl_atf_handoff_params *ATFHandoffParams;
-	if (!atf_handoff_addr) {
-		WARN("BL31: No ATF handoff structure passed\n");
-		return FSBL_HANDOFF_NO_STRUCT;
+	const struct xbl_handoff_params *HandoffParams;
+
+	if (!handoff_addr) {
+		WARN("BL31: No handoff structure passed\n");
+		return XBL_HANDOFF_NO_STRUCT;
 	}
 
-	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);
-		return FSBL_HANDOFF_INVAL_STRUCT;
+	HandoffParams = (struct xbl_handoff_params *)handoff_addr;
+	if ((HandoffParams->magic[0] != 'X') ||
+	    (HandoffParams->magic[1] != 'L') ||
+	    (HandoffParams->magic[2] != 'N') ||
+	    (HandoffParams->magic[3] != 'X')) {
+		ERROR("BL31: invalid handoff structure at %" PRIx64 "\n", handoff_addr);
+		return XBL_HANDOFF_INVAL_STRUCT;
 	}
 
-	VERBOSE("BL31: 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);
-		return FSBL_HANDOFF_TOO_MANY_PARTS;
+	VERBOSE("BL31: TF-A handoff params at:0x%" PRIx64 ", entries:%u\n",
+		handoff_addr, HandoffParams->num_entries);
+	if (HandoffParams->num_entries > XBL_MAX_PARTITIONS) {
+		ERROR("BL31: TF-A handoff params: too many partitions (%u/%u)\n",
+		      HandoffParams->num_entries, XBL_MAX_PARTITIONS);
+		return XBL_HANDOFF_TOO_MANY_PARTS;
 	}
 
 	/*
@@ -174,43 +202,55 @@
 	 * (bl32, bl33). I.e. the last applicable images in the handoff
 	 * structure will be used for the hand off
 	 */
-	for (size_t i = 0; i < ATFHandoffParams->num_entries; i++) {
+	for (size_t i = 0; i < HandoffParams->num_entries; i++) {
 		entry_point_info_t *image;
 		int32_t target_estate, target_secure, target_cpu;
 		uint32_t target_endianness, target_el;
 
 		VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
-			ATFHandoffParams->partition[i].entry_point,
-			ATFHandoffParams->partition[i].flags);
+			HandoffParams->partition[i].entry_point,
+			HandoffParams->partition[i].flags);
+
+#if defined(PLAT_versal_net)
+		uint32_t target_cluster;
 
-		target_cpu = get_fsbl_cpu(&ATFHandoffParams->partition[i]);
-		if (target_cpu != FSBL_FLAGS_A53_0) {
+		target_cluster = get_xbl_cluster(&HandoffParams->partition[i]);
+		if (target_cluster != XBL_FLAGS_CLUSTER_0) {
+			WARN("BL31: invalid target Cluster (%i)\n",
+			     target_cluster);
+			continue;
+		}
+#endif /* PLAT_versal_net */
+
+		target_cpu = get_xbl_cpu(&HandoffParams->partition[i]);
+		if (target_cpu != XBL_FLAGS_A53_0) {
 			WARN("BL31: invalid target CPU (%i)\n", target_cpu);
 			continue;
 		}
 
-		target_el = get_fsbl_el(&ATFHandoffParams->partition[i]);
-		if ((target_el == FSBL_FLAGS_EL3) ||
-		    (target_el == FSBL_FLAGS_EL0)) {
-			WARN("BL31: invalid exception level (%i)\n", target_el);
+		target_el = get_xbl_el(&HandoffParams->partition[i]);
+		if ((target_el == XBL_FLAGS_EL3) ||
+		    (target_el == XBL_FLAGS_EL0)) {
+			WARN("BL31: invalid target exception level(%i)\n",
+			     target_el);
 			continue;
 		}
 
-		target_secure = get_fsbl_ss(&ATFHandoffParams->partition[i]);
-		if (target_secure == FSBL_FLAGS_SECURE &&
-		    target_el == FSBL_FLAGS_EL2) {
+		target_secure = get_xbl_ss(&HandoffParams->partition[i]);
+		if (target_secure == XBL_FLAGS_SECURE &&
+		    target_el == XBL_FLAGS_EL2) {
 			WARN("BL31: invalid security state (%i) for exception level (%i)\n",
 			     target_secure, target_el);
 			continue;
 		}
 
-		target_estate = get_fsbl_estate(&ATFHandoffParams->partition[i]);
-		target_endianness = get_fsbl_endian(&ATFHandoffParams->partition[i]);
+		target_estate = get_xbl_estate(&HandoffParams->partition[i]);
+		target_endianness = get_xbl_endian(&HandoffParams->partition[i]);
 
-		if (target_secure == FSBL_FLAGS_SECURE) {
+		if (target_secure == XBL_FLAGS_SECURE) {
 			image = bl32;
 
-			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
+			if (target_estate == XBL_FLAGS_ESTATE_A32) {
 				bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
 							 target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
@@ -221,8 +261,8 @@
 		} else {
 			image = bl33;
 
-			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
-				if (target_el == FSBL_FLAGS_EL2) {
+			if (target_estate == XBL_FLAGS_ESTATE_A32) {
+				if (target_el == XBL_FLAGS_EL2) {
 					target_el = MODE32_hyp;
 				} else {
 					target_el = MODE32_sys;
@@ -232,7 +272,7 @@
 							 target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
 			} else {
-				if (target_el == FSBL_FLAGS_EL2) {
+				if (target_el == XBL_FLAGS_EL2) {
 					target_el = MODE_EL2;
 				} else {
 					target_el = MODE_EL1;
@@ -244,10 +284,10 @@
 		}
 
 		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
-			target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
-			ATFHandoffParams->partition[i].entry_point,
+			target_secure == XBL_FLAGS_SECURE ? "BL32" : "BL33",
+			HandoffParams->partition[i].entry_point,
 			target_el);
-		image->pc = ATFHandoffParams->partition[i].entry_point;
+		image->pc = HandoffParams->partition[i].entry_point;
 
 		if (target_endianness == SPSR_E_BIG) {
 			EP_SET_EE(image->h.attr, EP_EE_BIG);
@@ -256,5 +296,5 @@
 		}
 	}
 
-	return FSBL_HANDOFF_SUCCESS;
+	return XBL_HANDOFF_SUCCESS;
 }
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
new file mode 100644
index 0000000..ffc39bb
--- /dev/null
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Versal system level PM-API functions and communication with PMC via
+ * IPI interrupts
+ */
+
+#include <drivers/arm/gic_common.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <pm_api_sys.h>
+#include <pm_client.h>
+#include <pm_common.h>
+#include <pm_defs.h>
+#include <pm_ipi.h>
+#include "pm_svc_main.h"
+
+#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
+
+/* default shutdown/reboot scope is system(2) */
+static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
+
+/**
+ * pm_get_shutdown_scope() - Get the currently set shutdown scope.
+ *
+ * Return: Shutdown scope value.
+ *
+ */
+uint32_t pm_get_shutdown_scope(void)
+{
+	return pm_shutdown_scope;
+}
+
+/* PM API functions */
+
+/**
+ * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as
+ *                                wake sources in the XilPM.
+ * @node_id: Node id of processor.
+ *
+ */
+void pm_client_set_wakeup_sources(uint32_t node_id)
+{
+	uint32_t reg_num, device_id;
+	uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U};
+	uint32_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U;
+
+	zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
+
+	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
+		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
+		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
+
+		if (reg == 0U) {
+			continue;
+		}
+
+		while (reg != 0U) {
+			enum pm_device_node_idx node_idx;
+			uint32_t idx, irq, lowest_set = reg & (-reg);
+			enum pm_ret_status ret;
+
+			idx = (uint32_t)__builtin_ctz(lowest_set);
+			irq = base_irq + idx;
+
+			if (irq > IRQ_MAX) {
+				break;
+			}
+
+			node_idx = irq_to_pm_node_idx(irq);
+			reg &= ~lowest_set;
+
+			if (node_idx > XPM_NODEIDX_DEV_MIN) {
+				if (pm_wakeup_nodes_set[node_idx] == 0U) {
+					/* Get device ID from node index */
+					device_id = PERIPH_DEVID((uint32_t)node_idx);
+					ret = pm_set_wakeup_source(node_id,
+								   device_id, 1U,
+								   SECURE_FLAG);
+					pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
+										 1U : 0U;
+				}
+			}
+		}
+	}
+}
+
+/**
+ * pm_handle_eemi_call() - PM call for processor to send eemi payload.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ * @x0: Arguments received per SMC64 standard.
+ * @x1: Arguments received per SMC64 standard.
+ * @x2: Arguments received per SMC64 standard.
+ * @x3: Arguments received per SMC64 standard.
+ * @x4: Arguments received per SMC64 standard.
+ * @x5: Arguments received per SMC64 standard.
+ * @result: Payload received from firmware.
+ *
+ * Return: PM_RET_SUCCESS on success or error code.
+ *
+ */
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+				       uint32_t x2, uint32_t x3, uint32_t x4,
+				       uint32_t x5, uint64_t *result)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT] = {0};
+	uint32_t module_id;
+
+	module_id = (x0 & MODULE_ID_MASK) >> 8U;
+
+	//default module id is for LIBPM
+	if (module_id == 0) {
+		module_id = LIBPM_MODULE_ID;
+	}
+
+	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
+	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
+}
+
+/**
+ * pm_self_suspend() - PM call for processor to suspend itself
+ * @nid: Node id of the processor or subsystem.
+ * @latency: Requested maximum wakeup latency (not supported).
+ * @state: Requested state.
+ * @address: Resume address.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This is a blocking call, it will return only once PMU has responded.
+ * On a wakeup, resume address will be automatically set by PMU.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_self_suspend(uint32_t nid,
+				   uint32_t latency,
+				   uint32_t state,
+				   uintptr_t address, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+	uint32_t cpuid = plat_my_core_pos();
+	const struct pm_proc *proc = pm_get_proc(cpuid);
+
+	if (proc == NULL) {
+		WARN("Failed to get proc %d\n", cpuid);
+		return PM_RET_ERROR_INTERNAL;
+	}
+
+	/*
+	 * Do client specific suspend operations
+	 * (e.g. set powerdown request bit)
+	 */
+	pm_client_suspend(proc, state);
+
+	/* Send request to the PLM */
+	PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
+			 proc->node_id, latency, state, address,
+			 (address >> 32));
+	return pm_ipi_send_sync(proc, payload, NULL, 0);
+}
+
+/**
+ * pm_abort_suspend() - PM call to announce that a prior suspend request
+ *                      is to be aborted.
+ * @reason: Reason for the abort.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * Calling PU expects the PMU to abort the initiated suspend procedure.
+ * This is a non-blocking call without any acknowledge.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/*
+	 * Do client specific abort suspend operations
+	 * (e.g. enable interrupts and clear powerdown request bit)
+	 */
+	pm_client_abort_suspend();
+
+	/* Send request to the PLM */
+	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND,
+			 reason, primary_proc->node_id);
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_req_suspend() - PM call to request for another PU or subsystem to
+ *                    be suspended gracefully.
+ * @target: Node id of the targeted PU or subsystem.
+ * @ack: Flag to specify whether acknowledge is requested.
+ * @latency: Requested wakeup latency (not supported)
+ * @state: Requested state (not supported).
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
+				  uint32_t latency, uint32_t state,
+				  uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMU */
+	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
+			 latency, state);
+	if (ack == IPI_BLOCKING) {
+		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	} else {
+		return pm_ipi_send(primary_proc, payload);
+	}
+}
+
+/**
+ * pm_req_wakeup() - PM call for processor to wake up selected processor
+ *                   or subsystem.
+ * @target: Device ID of the processor or subsystem to wake up.
+ * @set_address: Resume address presence indicator.
+ *               1 - resume address specified, 0 - otherwise.
+ * @address: Resume address.
+ * @ack: Flag to specify whether acknowledge requested.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API function is either used to power up another APU core for SMP
+ * (by PSCI) or to power up an entirely different PU or subsystem, such
+ * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
+ * automatically set by PMC.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
+				 uintptr_t address, uint8_t ack, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC to perform the wake of the PU */
+	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
+			 set_address, address, ack);
+
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_get_callbackdata() - Read from IPI response buffer.
+ * @data: array of PAYLOAD_ARG_CNT elements.
+ * @count: Number of values to return.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ * @ack: 0 - Do not ack IPI after reading payload.
+ *       1 - Ack IPI after reading payload.
+ *
+ * Read value from ipi buffer response buffer.
+ * Return: Returns status, either success or error.
+ *
+ */
+enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	/* Return if interrupt is not from PMU */
+	if (pm_ipi_irq_status(primary_proc) == 0) {
+		return ret;
+	}
+
+	ret = pm_ipi_buff_read_callb(data, count);
+
+	if (ack != 0U) {
+		pm_ipi_irq_clear(primary_proc);
+	}
+
+	return ret;
+}
+
+/**
+ * pm_pll_set_param() - Set PLL parameter.
+ * @clk_id: PLL clock ID.
+ * @param: PLL parameter ID.
+ * @value: Value to set for PLL parameter.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
+				    uint32_t value, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
+			 clk_id, param, value);
+
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_pll_get_param() - Get PLL parameter value.
+ * @clk_id: PLL clock ID.
+ * @param: PLL parameter ID.
+ * @value: Buffer to store PLL parameter value.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
+				    uint32_t *value, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
+			 clk_id, param);
+
+	return pm_ipi_send_sync(primary_proc, payload, value, 1);
+}
+
+/**
+ * pm_pll_set_mode() - Set PLL mode.
+ * @clk_id: PLL clock ID.
+ * @mode: PLL mode.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
+				   uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
+			 clk_id, mode);
+
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_pll_get_mode() - Get PLL mode.
+ * @clk_id: PLL clock ID.
+ * @mode: Buffer to store PLL mode.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
+				   uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
+			 clk_id);
+
+	return pm_ipi_send_sync(primary_proc, payload, mode, 1);
+}
+
+/**
+ * pm_force_powerdown() - PM call to request for another PU or subsystem to
+ *                        be powered down forcefully.
+ * @target: Device ID of the PU node to be forced powered down.
+ * @ack: Flag to specify whether acknowledge is requested
+ * @flag: 0 - Call from secure source
+ *        1 - Call from non-secure source
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
+				      uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
+			 target, ack);
+
+	if (ack == IPI_BLOCKING) {
+		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	} else {
+		return pm_ipi_send(primary_proc, payload);
+	}
+}
+
+/**
+ * pm_system_shutdown() - PM call to request a system shutdown or restart.
+ * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
+ * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
+				      uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
+		/* Setting scope for subsequent PSCI reboot or shutdown */
+		pm_shutdown_scope = subtype;
+		return PM_RET_SUCCESS;
+	}
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
+			 type, subtype);
+
+	return pm_ipi_send_non_blocking(primary_proc, payload);
+}
+
+/**
+ * pm_query_data() -  PM API for querying firmware data.
+ * @qid: The type of data to query.
+ * @arg1: Argument 1 to requested query data call.
+ * @arg2: Argument 2 to requested query data call.
+ * @arg3: Argument 3 to requested query data call.
+ * @data: Returned output data.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * Return: 0 if success else non-zero error code of type
+ *         enum pm_ret_status.
+ *
+ */
+enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
+				 uint32_t arg3, uint32_t *data, uint32_t flag)
+{
+	uint32_t ret;
+	uint32_t version[PAYLOAD_ARG_CNT] = {0};
+	uint32_t payload[PAYLOAD_ARG_CNT];
+	uint32_t fw_api_version;
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
+			 arg1, arg2, arg3);
+
+	ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
+	if (ret == PM_RET_SUCCESS) {
+		fw_api_version = version[0] & 0xFFFFU;
+		if ((fw_api_version == 2U) &&
+		    ((qid == XPM_QID_CLOCK_GET_NAME) ||
+		     (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
+			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
+			if (ret == PM_RET_SUCCESS) {
+				ret = data[0];
+				data[0] = data[1];
+				data[1] = data[2];
+				data[2] = data[3];
+			}
+		} else {
+			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
+		}
+	}
+	return ret;
+}
+/**
+ * pm_api_ioctl() -  PM IOCTL API for device control and configs.
+ * @device_id: Device ID.
+ * @ioctl_id: ID of the requested IOCTL.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @arg3: Argument 3 to requested IOCTL call.
+ * @value: Returned output value.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * This function calls IOCTL to firmware for device control and configuration.
+ *
+ * Return: Returns status, either 0 on success or non-zero error code
+ *         of type enum pm_ret_status.
+ *
+ */
+enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
+				uint32_t arg1, uint32_t arg2, uint32_t arg3,
+				uint32_t *value, uint32_t flag)
+{
+	enum pm_ret_status ret;
+
+	switch (ioctl_id) {
+	case IOCTL_SET_PLL_FRAC_MODE:
+		ret =  pm_pll_set_mode(arg1, arg2, flag);
+		break;
+	case IOCTL_GET_PLL_FRAC_MODE:
+		ret =  pm_pll_get_mode(arg1, value, flag);
+		break;
+	case IOCTL_SET_PLL_FRAC_DATA:
+		ret =  pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
+		break;
+	case IOCTL_GET_PLL_FRAC_DATA:
+		ret =  pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
+		break;
+	case IOCTL_SET_SGI:
+		/* Get the sgi number */
+		ret = pm_register_sgi(arg1, arg2);
+		if (ret != 0) {
+			return PM_RET_ERROR_ARGS;
+		}
+		ret = PM_RET_SUCCESS;
+		break;
+	default:
+		return PM_RET_ERROR_NOTSUPPORTED;
+	}
+
+	return ret;
+}
+
+/**
+ * pm_set_wakeup_source() - PM call to specify the wakeup source while
+ *                          suspended.
+ * @target: Device id of the targeted PU or subsystem
+ * @wkup_device: Device id of the wakeup peripheral
+ * @enable: Enable or disable the specified peripheral as wake source
+ * @flag: 0 - Call from secure source
+ *        1 - Call from non-secure source
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
+					uint8_t enable, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
+			 target, wkup_device, enable);
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
+ *               words Returned supported API version and bitmasks
+ *               for IOCTL and QUERY ID
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
+				    uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+	uint32_t module_id;
+
+	/* Return version of API which are implemented in TF-A only */
+	switch (api_id) {
+	case PM_GET_CALLBACK_DATA:
+	case PM_GET_TRUSTZONE_VERSION:
+		ret_payload[0] = PM_API_VERSION_2;
+		return PM_RET_SUCCESS;
+	case TF_A_PM_REGISTER_SGI:
+		ret_payload[0] = PM_API_BASE_VERSION;
+		return PM_RET_SUCCESS;
+	default:
+		break;
+	}
+
+	module_id = (api_id & MODULE_ID_MASK) >> 8U;
+
+	/*
+	 * feature check should be done only for LIBPM module
+	 * If module_id is 0, then we consider it LIBPM module as default id
+	 */
+	if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
+		return PM_RET_SUCCESS;
+	}
+
+	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
+			 PM_FEATURE_CHECK, api_id);
+	return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
+}
+
+/**
+ * pm_load_pdi() - Load the PDI. This function provides support to load
+ *                 PDI from linux.
+ *
+ * @src: Source device of pdi(DDR, OCM, SD etc).
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
+			       uint32_t address_high, uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMU */
+	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
+			 address_high, address_low);
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_register_notifier() - PM call to register a subsystem to be notified
+ *                          about the device event.
+ * @device_id: Device ID for the Node to which the event is related.
+ * @event: Event in question.
+ * @wake: Wake subsystem upon capturing the event if value 1.
+ * @enable: Enable the registration for value 1, disable for value 0.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
+ */
+enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
+					uint32_t wake, uint32_t enable,
+					uint32_t flag)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
+			 device_id, event, wake, enable);
+
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_get_chipid() - Read silicon ID registers.
+ * @value: Buffer for two 32bit words.
+ *
+ * Return: Returns status, either success or error+reason and,
+ *         optionally, @value.
+ */
+enum pm_ret_status pm_get_chipid(uint32_t *value)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, SECURE_FLAG, PM_GET_CHIPID);
+
+	return pm_ipi_send_sync(primary_proc, payload, value, 2);
+}
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 37d0384..56567dd 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,45 +10,73 @@
 #include <arch_helpers.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
 #include <ipi.h>
 #include <plat_ipi.h>
 #include <plat_private.h>
-#include <plat/common/platform.h>
-
 #include "pm_defs.h"
 #include "pm_ipi.h"
 
 #define ERROR_CODE_MASK		(0xFFFFU)
 #define PM_OFFSET		(0U)
 
+/*
+ * ARM v8.2, the cache will turn off automatically when cpu
+ * power down. Therefore, there is no doubt to use the spin_lock here.
+ */
+#if !HW_ASSISTED_COHERENCY
 DEFINE_BAKERY_LOCK(pm_secure_lock);
+static inline void pm_ipi_lock_get(void)
+{
+	bakery_lock_get(&pm_secure_lock);
+}
+
+static inline void pm_ipi_lock_release(void)
+{
+	bakery_lock_release(&pm_secure_lock);
+}
+#else
+spinlock_t pm_secure_lock;
+static inline void pm_ipi_lock_get(void)
+{
+	spin_lock(&pm_secure_lock);
+}
+
+static inline void pm_ipi_lock_release(void)
+{
+	spin_unlock(&pm_secure_lock);
+}
+#endif
 
 /**
  * pm_ipi_init() - Initialize IPI peripheral for communication with
- *		   remote processor
+ *                 remote processor.
+ * @proc: Pointer to the processor who is initiating request.
  *
- * @proc	Pointer to the processor who is initiating request
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
- * Called from pm_setup initialization function
+ * Called from pm_setup initialization function.
  */
 void pm_ipi_init(const struct pm_proc *proc)
 {
-	bakery_lock_init(&pm_secure_lock);
 	ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
 }
 
 /**
- * pm_ipi_send_common() - Sends IPI request to the remote processor
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
+ * pm_ipi_send_common() - Sends IPI request to the remote processor.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
+ * @is_blocking: if to trigger the notification in blocking mode or not.
  *
  * Send an IPI request to the power controller. Caller needs to hold
  * the 'pm_secure_lock' lock.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
 					     uint32_t payload[PAYLOAD_ARG_CNT],
@@ -77,47 +105,49 @@
 
 /**
  * pm_ipi_send_non_blocking() - Sends IPI request to the remote processor
- *			        without blocking notification
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
+ *                              without blocking notification.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
  *
  * Send an IPI request to the power controller.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
 					    uint32_t payload[PAYLOAD_ARG_CNT])
 {
 	enum pm_ret_status ret;
 
-	bakery_lock_get(&pm_secure_lock);
+	pm_ipi_lock_get();
 
 	ret = pm_ipi_send_common(proc, payload, IPI_NON_BLOCKING);
 
-	bakery_lock_release(&pm_secure_lock);
+	pm_ipi_lock_release();
 
 	return ret;
 }
 
 /**
- * pm_ipi_send() - Sends IPI request to the remote processor
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
+ * pm_ipi_send() - Sends IPI request to the remote processor.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
  *
  * Send an IPI request to the power controller.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
 			       uint32_t payload[PAYLOAD_ARG_CNT])
 {
 	enum pm_ret_status ret;
 
-	bakery_lock_get(&pm_secure_lock);
+	pm_ipi_lock_get();
 
 	ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
 
-	bakery_lock_release(&pm_secure_lock);
+	pm_ipi_lock_release();
 
 	return ret;
 }
@@ -125,12 +155,13 @@
 
 /**
  * pm_ipi_buff_read() - Reads IPI response after remote processor has handled
- *			interrupt
- * @proc	Pointer to the processor who is waiting and reading response
- * @value	Used to return value from IPI buffer element (optional)
- * @count	Number of values to return in @value
+ *                      interrupt.
+ * @proc: Pointer to the processor who is waiting and reading response.
+ * @value: Used to return value from IPI buffer element (optional).
+ * @count: Number of values to return in @value.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
 					   uint32_t *value, size_t count)
@@ -182,13 +213,15 @@
 
 /**
  * pm_ipi_buff_read_callb() - Callback function that reads value from
- *			      ipi response buffer
- * @value	Used to return value from IPI buffer element
- * @count	Number of values to return in @value
+ *                            ipi response buffer.
+ * @value: Used to return value from IPI buffer element.
+ * @count: Number of values to return in @value.
  *
  * This callback function fills requested data in @value from ipi response
  * buffer.
- * @return 	Returns status, either success or error
+ *
+ * Return: Returns status, either success or error.
+ *
  */
 enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count)
 {
@@ -232,16 +265,17 @@
 }
 
 /**
- * pm_ipi_send_sync() - Sends IPI request to the remote processor
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
- * @value	Used to return value from IPI buffer element (optional)
- * @count	Number of values to return in @value
+ * pm_ipi_send_sync() - Sends IPI request to the remote processor.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
+ * @value: Used to return value from IPI buffer element (optional).
+ * @count: Number of values to return in @value.
  *
  * Send an IPI request to the power controller and wait for it to be handled.
  *
- * @return	Returns status, either success or error+reason and, optionally,
- *		@value
+ * Return: Returns status, either success or error+reason and, optionally,
+ *         @value.
+ *
  */
 enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
 				    uint32_t payload[PAYLOAD_ARG_CNT],
@@ -249,7 +283,7 @@
 {
 	enum pm_ret_status ret;
 
-	bakery_lock_get(&pm_secure_lock);
+	pm_ipi_lock_get();
 
 	ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
 	if (ret != PM_RET_SUCCESS) {
@@ -259,7 +293,7 @@
 	ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
 
 unlock:
-	bakery_lock_release(&pm_secure_lock);
+	pm_ipi_lock_release();
 
 	return ret;
 }
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
similarity index 78%
rename from plat/xilinx/versal/pm_service/pm_svc_main.c
rename to plat/xilinx/common/pm_service/pm_svc_main.c
index 185bfdb..fb32f2a 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,15 +11,18 @@
  */
 
 #include <errno.h>
-#include <plat_private.h>
 #include <stdbool.h>
+
+#include "../drivers/arm/gic/v3/gicv3_private.h"
+
 #include <common/runtime_svc.h>
+#include <drivers/arm/gicv3.h>
 #include <plat/common/platform.h>
+
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
-#include <drivers/arm/gicv3.h>
-#include "../drivers/arm/gic/v3/gicv3_private.h"
 
 #define MODE				0x80000000U
 
@@ -84,13 +87,13 @@
 }
 
 /**
- * pm_register_sgi() - PM register the IPI interrupt
+ * pm_register_sgi() - PM register the IPI interrupt.
+ * @sgi_num: SGI number to be used for communication.
+ * @reset: Reset to invalid SGI when reset=1.
  *
- * @sgi -  SGI number to be used for communication.
- * @reset -  Reset to invalid SGI when reset=1.
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
  * Update the SGI number to be used.
  *
@@ -115,17 +118,18 @@
 }
 
 /**
- * pm_setup() - PM service setup
+ * pm_setup() - PM service setup.
  *
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
  * Initialization functions for Versal power management for
  * communicaton with PMC.
  *
  * Called from sip_svc_setup initialization function with the
  * rt_svc_init signature.
+ *
  */
 int32_t pm_setup(void)
 {
@@ -152,14 +156,19 @@
 }
 
 /**
- * eemi_for_compatibility() - EEMI calls handler for deprecated calls
+ * eemi_for_compatibility() - EEMI calls handler for deprecated calls.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
- * @return - If EEMI API found then, uintptr_t type address, else 0
+ * Return: If EEMI API found then, uintptr_t type address, else 0.
  *
  * Some EEMI API's use case needs to be changed in Linux driver, so they
  * can take advantage of common EEMI handler in TF-A. As of now the old
  * implementation of these APIs are required to maintain backward compatibility
  * until their use case in linux driver changes.
+ *
  */
 static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
 					void *handle, uint32_t security_flag)
@@ -168,7 +177,7 @@
 
 	switch (api_id) {
 
-	case PM_IOCTL:
+	case (uint32_t)PM_IOCTL:
 	{
 		uint32_t value = 0U;
 
@@ -181,7 +190,7 @@
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
-	case PM_QUERY_DATA:
+	case (uint32_t)PM_QUERY_DATA:
 	{
 		uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
 
@@ -192,7 +201,7 @@
 			 (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
 	}
 
-	case PM_FEATURE_CHECK:
+	case (uint32_t)PM_FEATURE_CHECK:
 	{
 		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
 
@@ -214,14 +223,21 @@
 }
 
 /**
- * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI
+ * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * These EEMI APIs performs CPU specific power management tasks.
  * These EEMI APIs are invoked either from PSCI or from debugfs in kernel.
  * These calls require CPU specific processing before sending IPI request to
  * Platform Management Controller. For example enable/disable CPU specific
  * interrupts. This requires separate handler for these calls and may not be
- * handled using common eemi handler
+ * handled using common eemi handler.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0.
+ *
  */
 static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
 					   void *handle, uint32_t security_flag)
@@ -230,25 +246,25 @@
 
 	switch (api_id) {
 
-	case PM_SELF_SUSPEND:
+	case (uint32_t)PM_SELF_SUSPEND:
 		ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], security_flag);
 		SMC_RET1(handle, (u_register_t)ret);
 
-	case PM_FORCE_POWERDOWN:
+	case (uint32_t)PM_FORCE_POWERDOWN:
 		ret = pm_force_powerdown(pm_arg[0], pm_arg[1], security_flag);
 		SMC_RET1(handle, (u_register_t)ret);
 
-	case PM_REQ_SUSPEND:
+	case (uint32_t)PM_REQ_SUSPEND:
 		ret = pm_req_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
 				     pm_arg[3], security_flag);
 		SMC_RET1(handle, (u_register_t)ret);
 
-	case PM_ABORT_SUSPEND:
+	case (uint32_t)PM_ABORT_SUSPEND:
 		ret = pm_abort_suspend(pm_arg[0], security_flag);
 		SMC_RET1(handle, (u_register_t)ret);
 
-	case PM_SYSTEM_SHUTDOWN:
+	case (uint32_t)PM_SYSTEM_SHUTDOWN:
 		ret = pm_system_shutdown(pm_arg[0], pm_arg[1], security_flag);
 		SMC_RET1(handle, (u_register_t)ret);
 
@@ -258,11 +274,18 @@
 }
 
 /**
- * TF_A_specific_handler() - SMC handler for TF-A specific functionality
+ * TF_A_specific_handler() - SMC handler for TF-A specific functionality.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * These EEMI calls performs functionality that does not require
  * IPI transaction. The handler ends in TF-A and returns requested data to
  * kernel from TF-A.
+ *
+ * Return: If TF-A specific API found then, uintptr_t type address, else 0
+ *
  */
 static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
 				       void *handle, uint32_t security_flag)
@@ -306,7 +329,11 @@
 }
 
 /**
- * eemi_handler() - Prepare EEMI payload and perform IPI transaction
+ * eemi_handler() - Prepare EEMI payload and perform IPI transaction.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * EEMI - Embedded Energy Management Interface is Xilinx proprietary protocol
  * to allow communication between power management controller and different
@@ -314,6 +341,9 @@
  *
  * This handler prepares EEMI protocol payload received from kernel and performs
  * IPI transaction.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0
+ *
  */
 static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
 			      void *handle, uint32_t security_flag)
@@ -330,7 +360,7 @@
 	 * receive only 4 words from TF-A. So, this needs to be handled separately
 	 * than other eemi calls.
 	 */
-	if (api_id == PM_QUERY_DATA) {
+	if (api_id == (uint32_t)PM_QUERY_DATA) {
 		if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
 		    pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
 		    ret == PM_RET_SUCCESS) {
@@ -345,20 +375,24 @@
 
 /**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - SMC64 Arguments from kernel
- *	      x3 (upper 32-bits) and x4 are Unused
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
+ * @smc_fid: Function Identifier.
+ * @x1: SMC64 Arguments from kernel.
+ * @x2: SMC64 Arguments from kernel.
+ * @x3: SMC64 Arguments from kernel (upper 32-bits).
+ * @x4: Unused.
+ * @cookie: Unused.
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
- * @return  - Unused
+ * Return: Unused.
  *
  * Determines that smc_fid is valid and supported PM SMC Function ID from the
  * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * the unknown SMC Function ID.
  *
  * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * function with rt_svc_handle signature.
+ *
  */
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
diff --git a/plat/xilinx/common/versal.c b/plat/xilinx/common/versal.c
new file mode 100644
index 0000000..3ea022c
--- /dev/null
+++ b/plat/xilinx/common/versal.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <services/arm_arch_svc.h>
+
+#include <plat_private.h>
+#include <plat_startup.h>
+#include <pm_api_sys.h>
+
+/**
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ *                                     feature is availabile for platform.
+ * @fid: SMCCC function id.
+ *
+ * Return: SMC_ARCH_CALL_SUCCESS - if SMCCC feature is available.
+ *         SMC_ARCH_CALL_NOT_SUPPORTED - Otherwise.
+ *
+ */
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+}
+
+/**
+ * plat_get_soc_version() - Get the SOC version of the platform.
+ *
+ * Return: SiP defined SoC version in JEP-106.
+ *
+ * This function is called when the SoC_ID_type == 0.
+ * For further details please refer to section 7.4 of SMC Calling Convention.
+ */
+int32_t plat_get_soc_version(void)
+{
+	uint32_t manfid;
+
+	manfid = SOC_ID_SET_JEP_106(JEDEC_XILINX_BKID, JEDEC_XILINX_MFID);
+
+	return (int32_t)(manfid | (platform_version & SOC_ID_IMPL_DEF_MASK));
+}
+
+/**
+ * plat_get_soc_revision() - Get the SOC revision for the platform.
+ *
+ * Return: SiP defined SoC revision.
+ *
+ * This function is called when the  SoC_ID_type == 1
+ * For further details please refer to section 7.4 of SMC Calling Convention
+ */
+int32_t plat_get_soc_revision(void)
+{
+	return (platform_id & SOC_ID_REV_MASK);
+}
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index ed7f270..93deedc 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,19 +1,24 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_ipi.h>
-#include <versal_def.h>
-#include <plat_private.h>
 #include <common/debug.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
+#include <plat_common.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+#include <pm_api_sys.h>
+#include <versal_def.h>
+
+uint32_t platform_id, platform_version;
+
 /*
  * Table of regions to map using the MMU.
  * This doesn't include TZRAM as the 'mem_layout' argument passed to
@@ -23,7 +28,7 @@
 	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(FPD_MAINCCI_BASE, FPD_MAINCCI_SIZE, MT_DEVICE | MT_RW |
+	MAP_REGION_FLAT(PLAT_ARM_CCI_BASE, PLAT_ARM_CCI_SIZE, MT_DEVICE | MT_RW |
 			MT_SECURE),
 	{ 0 }
 };
@@ -53,3 +58,18 @@
 	return VERSAL_CPU_CLOCK;
 }
 
+void board_detection(void)
+{
+	uint32_t plat_info[2];
+
+	if (pm_get_chipid(plat_info) != PM_RET_SUCCESS) {
+		/* If the call is failed we cannot proceed with further
+		 * setup. TF-A to panic in this situation.
+		 */
+		NOTICE("Failed to read the chip information");
+		panic();
+	}
+
+	platform_id = FIELD_GET(PLATFORM_MASK, plat_info[1]);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, plat_info[1]);
+}
diff --git a/plat/xilinx/versal/aarch64/versal_helpers.S b/plat/xilinx/versal/aarch64/versal_helpers.S
index 26eb052..f868b18 100644
--- a/plat/xilinx/versal/aarch64/versal_helpers.S
+++ b/plat/xilinx/versal/aarch64/versal_helpers.S
@@ -1,12 +1,14 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <arch.h>
 #include <asm_macros.S>
+
+#include <arch.h>
 #include <drivers/arm/gicv3.h>
+
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 995c852..0ef92a6 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -1,15 +1,14 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include <errno.h>
-#include <plat_arm.h>
-#include <plat_private.h>
+
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
@@ -17,14 +16,16 @@
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
-#include <versal_def.h>
+#include <plat_arm.h>
+
 #include <plat_private.h>
 #include <plat_startup.h>
-#include <pm_ipi.h>
-#include "pm_client.h"
 #include "pm_api_sys.h"
+#include "pm_client.h"
+#include <pm_ipi.h>
+#include <versal_def.h>
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
@@ -67,10 +68,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 = HANDOFF_PARAMS_MAX_SIZE;
 	enum pm_ret_status ret_status;
-	uint64_t addr[ATF_HANDOFF_PARAMS_MAX_SIZE];
+	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
 	if (VERSAL_CONSOLE_IS(pl011) || (VERSAL_CONSOLE_IS(pl011_1))) {
 		static console_t versal_runtime_console;
@@ -97,9 +98,9 @@
 
 	/* Initialize the platform config for future decision making */
 	versal_config_setup();
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
+
+	/* Get platform related information */
+	board_detection();
 
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
@@ -119,20 +120,20 @@
 	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 xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
 						  &bl33_image_ep_info,
-						  atf_handoff_addr);
-	if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) {
+						  tfa_handoff_addr);
+	if (ret == XBL_HANDOFF_NO_STRUCT || ret == XBL_HANDOFF_INVAL_STRUCT) {
 		bl31_set_default_config();
-	} else if (ret == FSBL_HANDOFF_TOO_MANY_PARTS) {
+	} else if (ret == XBL_HANDOFF_TOO_MANY_PARTS) {
 		ERROR("BL31: Error too many partitions %u\n", ret);
-	} else if (ret != FSBL_HANDOFF_SUCCESS) {
+	} else if (ret != XBL_HANDOFF_SUCCESS) {
 		panic();
 	} else {
 		INFO("BL31: PLM to TF-A handover success %u\n", ret);
@@ -232,5 +233,5 @@
 	};
 
 	setup_page_tables(bl_regions, plat_versal_get_mmap());
-	enable_mmu_el3(0);
+	enable_mmu(0);
 }
diff --git a/plat/xilinx/versal/include/plat_ipi.h b/plat/xilinx/versal/include/plat_ipi.h
index 9143dc6..4f7cb5f 100644
--- a/plat/xilinx/versal/include/plat_ipi.h
+++ b/plat/xilinx/versal/include/plat_ipi.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +10,10 @@
 #ifndef PLAT_IPI_H
 #define PLAT_IPI_H
 
-#include <ipi.h>
 #include <stdint.h>
 
+#include <ipi.h>
+
 /*********************************************************************
  * IPI agent IDs macros
  ********************************************************************/
@@ -28,16 +30,14 @@
  ********************************************************************/
 #define IPI_BUFFER_BASEADDR	0xFF3F0000U
 
-#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
-#define IPI_BUFFER_PMC_BASE	(IPI_BUFFER_BASEADDR + 0x200U)
+#define IPI_LOCAL_ID		IPI_ID_APU
+#define IPI_REMOTE_ID		IPI_ID_PMC
 
-#define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
-#define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
+#define IPI_BUFFER_LOCAL_BASE	(IPI_BUFFER_BASEADDR + (IPI_LOCAL_ID * 0x200U))
+#define IPI_BUFFER_REMOTE_BASE	(IPI_BUFFER_BASEADDR + (IPI_REMOTE_ID * 0x200U))
 
-#define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
-
-#define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
-#define IPI_BUFFER_TARGET_REMOTE_OFFSET	IPI_BUFFER_TARGET_PMC_OFFSET
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	(IPI_LOCAL_ID * 0x40U)
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	(IPI_REMOTE_ID * 0x40U)
 
 #define IPI_BUFFER_MAX_WORDS	8
 
@@ -51,4 +51,20 @@
 /* Configure IPI table for versal */
 void versal_ipi_config_table_init(void);
 
+/* IPI registers and bitfields */
+#define PMC_REG_BASE		U(0xFF320000)
+#define PMC_IPI_TRIG_BIT	(1U << 1U)
+#define IPI0_REG_BASE		U(0xFF330000)
+#define IPI0_TRIG_BIT		(1U << 2U)
+#define IPI1_REG_BASE		U(0xFF340000)
+#define IPI1_TRIG_BIT		(1U << 3U)
+#define IPI2_REG_BASE		U(0xFF350000)
+#define IPI2_TRIG_BIT		(1U << 4U)
+#define IPI3_REG_BASE		U(0xFF360000)
+#define IPI3_TRIG_BIT		(1U << 5U)
+#define IPI4_REG_BASE		U(0xFF370000)
+#define IPI4_TRIG_BIT		(1U << 5U)
+#define IPI5_REG_BASE		U(0xFF380000)
+#define IPI5_TRIG_BIT		(1U << 6U)
+
 #endif /* PLAT_IPI_H */
diff --git a/plat/xilinx/versal/include/plat_macros.S b/plat/xilinx/versal/include/plat_macros.S
index 3a52212..41193a5 100644
--- a/plat/xilinx/versal/include/plat_macros.S
+++ b/plat/xilinx/versal/include/plat_macros.S
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -102,8 +103,8 @@
 	 * ---------------------------------------------
 	 */
 	.macro plat_crash_print_regs
-	mov_imm	x17, PLAT_VERSAL_GICD_BASE
-	mov_imm	x16, PLAT_VERSAL_GICR_BASE
+	mov_imm	x17, PLAT_GICD_BASE_VALUE
+	mov_imm	x16, PLAT_GICR_BASE_VALUE
 	versal_print_gic_regs
 	.endm
 
diff --git a/plat/xilinx/versal/include/plat_pm_common.h b/plat/xilinx/versal/include/plat_pm_common.h
index 4c057b8..0b4a115 100644
--- a/plat/xilinx/versal/include/plat_pm_common.h
+++ b/plat/xilinx/versal/include/plat_pm_common.h
@@ -12,8 +12,10 @@
 #ifndef PLAT_PM_COMMON_H
 #define PLAT_PM_COMMON_H
 
-#include <common/debug.h>
 #include <stdint.h>
+
+#include <common/debug.h>
+
 #include "pm_defs.h"
 
 #define NON_SECURE_FLAG		1U
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 818797d..48f64ea 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,8 @@
 #ifndef PLAT_PRIVATE_H
 #define PLAT_PRIVATE_H
 
-#include <lib/xlat_tables/xlat_tables.h>
 #include <bl31/interrupt_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 
 typedef struct versal_intr_info_type_el3 {
 	uint32_t id;
@@ -21,6 +21,9 @@
 
 const mmap_region_t *plat_versal_get_mmap(void);
 
+extern uint32_t platform_id, platform_version;
+
+void board_detection(void);
 void plat_versal_gic_driver_init(void);
 void plat_versal_gic_init(void);
 void plat_versal_gic_cpuif_enable(void);
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 6d95fdc..6c1d8b6 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,12 +33,12 @@
  */
 #ifndef VERSAL_ATF_MEM_BASE
 # define BL31_BASE			U(0xfffe0000)
-# define BL31_LIMIT			U(0xffffffff)
+# define BL31_LIMIT			U(0x100000000)
 #else
 # define BL31_BASE			(VERSAL_ATF_MEM_BASE)
-# define BL31_LIMIT			(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE - 1)
+# define BL31_LIMIT			(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE)
 # ifdef VERSAL_ATF_MEM_PROGBITS_SIZE
-#  define BL31_PROGBITS_LIMIT		(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE - 1)
+#  define BL31_PROGBITS_LIMIT		(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE)
 # endif
 #endif
 
@@ -46,10 +47,10 @@
  ******************************************************************************/
 #ifndef VERSAL_BL32_MEM_BASE
 # define BL32_BASE			U(0x60000000)
-# define BL32_LIMIT			U(0x7fffffff)
+# define BL32_LIMIT			U(0x80000000)
 #else
 # define BL32_BASE			(VERSAL_BL32_MEM_BASE)
-# define BL32_LIMIT			(VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE - 1)
+# define BL32_LIMIT			(VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE)
 #endif
 
 /*******************************************************************************
@@ -65,7 +66,7 @@
  * TSP  specific defines.
  ******************************************************************************/
 #define TSP_SEC_MEM_BASE		BL32_BASE
-#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1)
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
 
 /* ID of the secure physical generic timer interrupt used by the TSP */
 #define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
@@ -81,8 +82,8 @@
 #define CACHE_WRITEBACK_SHIFT	6
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
 
-#define PLAT_VERSAL_GICD_BASE	U(0xF9000000)
-#define PLAT_VERSAL_GICR_BASE	U(0xF9080000)
+#define PLAT_GICD_BASE_VALUE	U(0xF9000000)
+#define PLAT_GICR_BASE_VALUE	U(0xF9080000)
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -101,4 +102,6 @@
 	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
 
+#define IRQ_MAX		142U
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index ce4d98c..a8cf0df 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,9 @@
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
+#define PLATFORM_MASK                  GENMASK(27U, 24U)
+#define PLATFORM_VERSION_MASK          GENMASK(31U, 28U)
+
 /* number of interrupt handlers. increase as required */
 #define MAX_INTR_EL3			2
 /* List all consoles */
@@ -50,6 +53,7 @@
  * CCI-400 related constants
  ******************************************************************************/
 #define PLAT_ARM_CCI_BASE		0xFD000000
+#define PLAT_ARM_CCI_SIZE		0x00100000
 #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	4
 #define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX	5
 
@@ -110,9 +114,6 @@
 #define CRF_RST_APU_ACPU_RESET		(1 << 0)
 #define CRF_RST_APU_ACPU_PWRON_RESET	(1 << 10)
 
-#define FPD_MAINCCI_BASE	0xFD000000
-#define FPD_MAINCCI_SIZE	0x00100000
-
 /* APU registers and bitfields */
 #define FPD_APU_BASE		0xFD5C0000U
 #define FPD_APU_CONFIG_0	(FPD_APU_BASE + 0x20U)
@@ -128,20 +129,4 @@
 #define PMC_GLOBAL_BASE			0xF1110000U
 #define PMC_GLOBAL_GLOB_GEN_STORAGE4	(PMC_GLOBAL_BASE + 0x40U)
 
-/* IPI registers and bitfields */
-#define PMC_REG_BASE		U(0xFF320000)
-#define PMC_IPI_TRIG_BIT	(1U << 1U)
-#define IPI0_REG_BASE		U(0xFF330000)
-#define IPI0_TRIG_BIT		(1U << 2U)
-#define IPI1_REG_BASE		U(0xFF340000)
-#define IPI1_TRIG_BIT		(1U << 3U)
-#define IPI2_REG_BASE		U(0xFF350000)
-#define IPI2_TRIG_BIT		(1U << 4U)
-#define IPI3_REG_BASE		U(0xFF360000)
-#define IPI3_TRIG_BIT		(1U << 5U)
-#define IPI4_REG_BASE		U(0xFF370000)
-#define IPI4_TRIG_BIT		(1U << 5U)
-#define IPI5_REG_BASE		U(0xFF380000)
-#define IPI5_TRIG_BIT		(1U << 6U)
-
 #endif /* VERSAL_DEF_H */
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 6787f31..56d98f7 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -1,21 +1,23 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
-#include <plat_arm.h>
-#include <plat_private.h>
-#include <pm_common.h>
+
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
-#include <plat/common/platform.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
 
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
+#include <pm_common.h>
 
 static uintptr_t versal_sec_entry;
 
@@ -44,9 +46,9 @@
 
 /**
  * versal_pwr_domain_suspend() - This function sends request to PMC to suspend
- * core.
+ *                               core.
+ * @target_state: Targated state.
  *
- * @target_state	Targated state
  */
 static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
@@ -81,9 +83,9 @@
 
 /**
  * versal_pwr_domain_suspend_finish() - This function performs actions to finish
- * suspend procedure.
+ *                                      suspend procedure.
+ * @target_state: Targated state.
  *
- * @target_state	Targated state
  */
 static void versal_pwr_domain_suspend_finish(
 					const psci_power_state_t *target_state)
@@ -120,8 +122,9 @@
 }
 
 /**
- * versal_system_off() - This function sends the system off request
- * to firmware.  This function does not return.
+ * versal_system_off() - This function sends the system off request to firmware.
+ *                       This function does not return.
+ *
  */
 static void __dead2 versal_system_off(void)
 {
@@ -135,8 +138,10 @@
 }
 
 /**
- * versal_system_reset() - This function sends the reset request
- * to firmware for the system to reset.  This function does not return.
+ * versal_system_reset() - This function sends the reset request to firmware
+ *                         for the system to reset.  This function does not
+ *			   return.
+ *
  */
 static void __dead2 versal_system_reset(void)
 {
@@ -150,9 +155,9 @@
 }
 
 /**
- * versal_pwr_domain_off() - This function performs actions to turn off core
+ * versal_pwr_domain_off() - This function performs actions to turn off core.
+ * @target_state: Targated state.
  *
- * @target_state	Targated state
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
@@ -181,12 +186,12 @@
 
 /**
  * versal_validate_power_state() - This function ensures that the power state
- * parameter in request is valid.
+ *                                 parameter in request is valid.
+ * @power_state: Power state of core.
+ * @req_state: Requested state.
  *
- * @power_state		Power state of core
- * @req_state		Requested state
+ * Return: Returns status, either success or reason.
  *
- * @return	Returns status, either success or reason
  */
 static int32_t versal_validate_power_state(uint32_t power_state,
 				       psci_power_state_t *req_state)
@@ -213,9 +218,9 @@
 }
 
 /**
- * versal_get_sys_suspend_power_state() -  Get power state for system suspend
+ * versal_get_sys_suspend_power_state() - Get power state for system suspend.
+ * @req_state: Requested state.
  *
- * @req_state	Requested state
  */
 static void versal_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
diff --git a/plat/xilinx/versal/plat_topology.c b/plat/xilinx/versal/plat_topology.c
index 6a94544..5f38599 100644
--- a/plat/xilinx/versal/plat_topology.c
+++ b/plat/xilinx/versal/plat_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c
index 132c7b7..ba17b1d 100644
--- a/plat/xilinx/versal/plat_versal.c
+++ b/plat/xilinx/versal/plat_versal.c
@@ -1,12 +1,13 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_private.h>
 #include <plat/common/platform.h>
 
+#include <plat_private.h>
+
 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
 	if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 8087297..0b6aea0 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -1,4 +1,5 @@
-# Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -52,10 +53,9 @@
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/xlat_tables_common.c		\
-				lib/xlat_tables/aarch64/xlat_tables.c		\
-				drivers/arm/dcc/dcc_console.c			\
+PLAT_BL_COMMON_SOURCES	:= 	drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV3_SOURCES}				\
@@ -65,7 +65,8 @@
 				plat/arm/common/arm_common.c			\
 				plat/common/plat_gicv3.c			\
 				plat/xilinx/versal/aarch64/versal_helpers.S	\
-				plat/xilinx/versal/aarch64/versal_common.c
+				plat/xilinx/versal/aarch64/versal_common.c	\
+				${XLAT_TABLES_LIB_SRCS}
 
 VERSAL_CONSOLE	?=	pl011
 ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc))
@@ -82,6 +83,9 @@
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/pm_service/pm_ipi.c		\
+				plat/xilinx/common/pm_service/pm_api_sys.c	\
+				plat/xilinx/common/pm_service/pm_svc_main.c	\
+				plat/xilinx/common/versal.c			\
 				plat/xilinx/versal/bl31_versal_setup.c		\
 				plat/xilinx/versal/plat_psci.c			\
 				plat/xilinx/versal/plat_versal.c		\
@@ -89,8 +93,6 @@
 				plat/xilinx/versal/sip_svc_setup.c		\
 				plat/xilinx/versal/versal_gicv3.c		\
 				plat/xilinx/versal/versal_ipi.c			\
-				plat/xilinx/versal/pm_service/pm_svc_main.c	\
-				plat/xilinx/versal/pm_service/pm_api_sys.c	\
 				plat/xilinx/versal/pm_service/pm_client.c
 
 ifeq ($(HARDEN_SLS_ALL), 1)
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
deleted file mode 100644
index cc99f11..0000000
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/*
- * Versal system level PM-API functions and communication with PMC via
- * IPI interrupts
- */
-
-#include <pm_common.h>
-#include <pm_ipi.h>
-#include <plat/common/platform.h>
-#include "pm_api_sys.h"
-#include "pm_client.h"
-#include "pm_defs.h"
-#include "pm_svc_main.h"
-
-/* default shutdown/reboot scope is system(2) */
-static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
-
-/**
- * pm_get_shutdown_scope() - Get the currently set shutdown scope
- *
- * @return	Shutdown scope value
- */
-uint32_t pm_get_shutdown_scope(void)
-{
-	return pm_shutdown_scope;
-}
-
-/* PM API functions */
-
-/**
- * pm_handle_eemi_call() - PM call for processor to send eemi payload
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- * @x0 to x5	Arguments received per SMC64 standard
- * @result	Payload received from firmware
- *
- * @return	 PM_RET_SUCCESS on success or error code
- */
-enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
-				       uint32_t x2, uint32_t x3, uint32_t x4,
-				       uint32_t x5, uint64_t *result)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT] = {0};
-	uint32_t module_id;
-
-	module_id = (x0 & MODULE_ID_MASK) >> 8U;
-
-	//default module id is for LIBPM
-	if (module_id == 0) {
-		module_id = LIBPM_MODULE_ID;
-	}
-
-	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
-	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
-}
-
-/**
- * pm_self_suspend() - PM call for processor to suspend itself
- * @nid		Node id of the processor or subsystem
- * @latency	Requested maximum wakeup latency (not supported)
- * @state	Requested state
- * @address	Resume address
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * This is a blocking call, it will return only once PMU has responded.
- * On a wakeup, resume address will be automatically set by PMU.
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_self_suspend(uint32_t nid,
-				   uint32_t latency,
-				   uint32_t state,
-				   uintptr_t address, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-	uint32_t cpuid = plat_my_core_pos();
-	const struct pm_proc *proc = pm_get_proc(cpuid);
-
-	if (proc == NULL) {
-		WARN("Failed to get proc %d\n", cpuid);
-		return PM_RET_ERROR_INTERNAL;
-	}
-
-	/*
-	 * Do client specific suspend operations
-	 * (e.g. set powerdown request bit)
-	 */
-	pm_client_suspend(proc, state);
-
-	/* Send request to the PLM */
-	PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
-			 proc->node_id, latency, state, address,
-			 (address >> 32));
-	return pm_ipi_send_sync(proc, payload, NULL, 0);
-}
-
-/**
- * pm_abort_suspend() - PM call to announce that a prior suspend request
- *			is to be aborted.
- * @reason	Reason for the abort
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * Calling PU expects the PMU to abort the initiated suspend procedure.
- * This is a non-blocking call without any acknowledge.
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/*
-	 * Do client specific abort suspend operations
-	 * (e.g. enable interrupts and clear powerdown request bit)
-	 */
-	pm_client_abort_suspend();
-
-	/* Send request to the PLM */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND,
-			 reason, primary_proc->node_id);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_req_suspend() - PM call to request for another PU or subsystem to
- *		      be suspended gracefully.
- * @target	Node id of the targeted PU or subsystem
- * @ack		Flag to specify whether acknowledge is requested
- * @latency	Requested wakeup latency (not supported)
- * @state	Requested state (not supported)
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
-				  uint32_t latency, uint32_t state,
-				  uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
-			 latency, state);
-	if (ack == IPI_BLOCKING) {
-		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	} else {
-		return pm_ipi_send(primary_proc, payload);
-	}
-}
-
-/**
- * pm_req_wakeup() - PM call for processor to wake up selected processor
- *		     or subsystem
- * @target	Device ID of the processor or subsystem to wake up
- * @set_address	Resume address presence indicator
- *		1 - resume address specified, 0 - otherwise
- * @address	Resume address
- * @ack		Flag to specify whether acknowledge requested
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * This API function is either used to power up another APU core for SMP
- * (by PSCI) or to power up an entirely different PU or subsystem, such
- * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
- * automatically set by PMC.
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
-				 uintptr_t address, uint8_t ack, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC to perform the wake of the PU */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
-			 set_address, address, ack);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_get_callbackdata() - Read from IPI response buffer
- * @data - array of PAYLOAD_ARG_CNT elements
- * @flag - 0 - Call from secure source
- *	   1 - Call from non-secure source
- * @ack - 0 - Do not ack IPI after reading payload
- *        1 - Ack IPI after reading payload
- *
- * Read value from ipi buffer response buffer.
- * @return	Returns status, either success or error
- */
-enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
-{
-	enum pm_ret_status ret = PM_RET_SUCCESS;
-	/* Return if interrupt is not from PMU */
-	if (pm_ipi_irq_status(primary_proc) == 0) {
-		return ret;
-	}
-
-	ret = pm_ipi_buff_read_callb(data, count);
-
-	if (ack != 0U) {
-		pm_ipi_irq_clear(primary_proc);
-	}
-
-	return ret;
-}
-
-/**
- * pm_pll_set_param() - Set PLL parameter
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * @clk_id	PLL clock ID
- * @param	PLL parameter ID
- * @value	Value to set for PLL parameter
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
-				    uint32_t value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
-			 clk_id, param, value);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_param() - Get PLL parameter value
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * @clk_id	PLL clock ID
- * @param	PLL parameter ID
- * @value:	Buffer to store PLL parameter value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
-				    uint32_t *value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
-			 clk_id, param);
-
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pll_set_mode() - Set PLL mode
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * @clk_id	PLL clock ID
- * @mode	PLL mode
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
-			 clk_id, mode);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_mode() - Get PLL mode
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * @clk_id	PLL clock ID
- * @mode:	Buffer to store PLL mode
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, mode, 1);
-}
-
-/**
- * pm_force_powerdown() - PM call to request for another PU or subsystem to
- *			  be powered down forcefully
- * @target	Device ID of the PU node to be forced powered down.
- * @ack		Flag to specify whether acknowledge is requested
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
-				      uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
-			 target, ack);
-
-	if (ack == IPI_BLOCKING) {
-		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	} else {
-		return pm_ipi_send(primary_proc, payload);
-	}
-}
-
-/**
- * pm_system_shutdown() - PM call to request a system shutdown or restart
- * @type	Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
- * @subtype	Scope: 0=APU-subsystem, 1=PS, 2=system
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
-				      uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
-		/* Setting scope for subsequent PSCI reboot or shutdown */
-		pm_shutdown_scope = subtype;
-		return PM_RET_SUCCESS;
-	}
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
-			 type, subtype);
-
-	return pm_ipi_send_non_blocking(primary_proc, payload);
-}
-
-/**
- * pm_query_data() -  PM API for querying firmware data
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * @qid	The type of data to query
- * @arg1	Argument 1 to requested query data call
- * @arg2	Argument 2 to requested query data call
- * @arg3	Argument 3 to requested query data call
- * @data	Returned output data
- * @flag 0 - Call from secure source
- *	1 - Call from non-secure source
- *
- * @retur - 0 if success else non-zero error code of type
- * enum pm_ret_status
- */
-enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
-				 uint32_t arg3, uint32_t *data, uint32_t flag)
-{
-	uint32_t ret;
-	uint32_t version[PAYLOAD_ARG_CNT] = {0};
-	uint32_t payload[PAYLOAD_ARG_CNT];
-	uint32_t fw_api_version;
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
-			 arg1, arg2, arg3);
-
-	ret = pm_feature_check(PM_QUERY_DATA, &version[0], flag);
-	if (ret == PM_RET_SUCCESS) {
-		fw_api_version = version[0] & 0xFFFFU;
-		if ((fw_api_version == 2U) &&
-		    ((qid == XPM_QID_CLOCK_GET_NAME) ||
-		     (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-			if (ret == PM_RET_SUCCESS) {
-				ret = data[0];
-				data[0] = data[1];
-				data[1] = data[2];
-				data[2] = data[3];
-			}
-		} else {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-		}
-	}
-	return ret;
-}
-/**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * @device_id	Device ID
- * @ioctl_id	ID of the requested IOCTL
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @arg3	Argument 3 to requested IOCTL call
- * @value	Returned output value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * This function calls IOCTL to firmware for device control and configuration.
- *
- * @return	Returns status, either 0 on success or non-zero error code
- * of type enum pm_ret_status
- */
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag)
-{
-	enum pm_ret_status ret;
-
-	switch (ioctl_id) {
-	case IOCTL_SET_PLL_FRAC_MODE:
-		ret =  pm_pll_set_mode(arg1, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_MODE:
-		ret =  pm_pll_get_mode(arg1, value, flag);
-		break;
-	case IOCTL_SET_PLL_FRAC_DATA:
-		ret =  pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_DATA:
-		ret =  pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value, flag);
-		break;
-	case IOCTL_SET_SGI:
-		/* Get the sgi number */
-		ret = pm_register_sgi(arg1, arg2);
-		if (ret != 0) {
-			return PM_RET_ERROR_ARGS;
-		}
-		ret = PM_RET_SUCCESS;
-		break;
-	default:
-		return PM_RET_ERROR_NOTSUPPORTED;
-	}
-
-	return ret;
-}
-
-/**
- * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
- * @target	Device id of the targeted PU or subsystem
- * @wkup_node	Device id of the wakeup peripheral
- * @enable	Enable or disable the specified peripheral as wake source
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
-					uint8_t enable, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
-			 target, wkup_device, enable);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_feature_check() - Returns the supported API version if supported
- * @api_id	API ID to check
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
- *		words Returned supported API version and bitmasks
- *		for IOCTL and QUERY ID
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
-				    uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-	uint32_t module_id;
-
-	/* Return version of API which are implemented in ATF only */
-	switch (api_id) {
-	case PM_GET_CALLBACK_DATA:
-	case PM_GET_TRUSTZONE_VERSION:
-		ret_payload[0] = PM_API_VERSION_2;
-		return PM_RET_SUCCESS;
-	case TF_A_PM_REGISTER_SGI:
-		ret_payload[0] = PM_API_BASE_VERSION;
-		return PM_RET_SUCCESS;
-	default:
-		break;
-	}
-
-	module_id = (api_id & MODULE_ID_MASK) >> 8U;
-
-	/*
-	 * feature check should be done only for LIBPM module
-	 * If module_id is 0, then we consider it LIBPM module as default id
-	 */
-	if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
-		return PM_RET_SUCCESS;
-	}
-
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
-			 PM_FEATURE_CHECK, api_id);
-	return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
-}
-
-/**
- * pm_load_pdi() - Load the PDI
- *
- * This function provides support to load PDI from linux
- *
- * src:        Source device of pdi(DDR, OCM, SD etc)
- * address_low: lower 32-bit Linear memory space address
- * address_high: higher 32-bit Linear memory space address
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return      Returns status, either success or error+reason
- */
-enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
-			       uint32_t address_high, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
-			 address_high, address_low);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_register_notifier() - PM call to register a subsystem to be notified
- * 			    about the device event
- * @device_id	Device ID for the Node to which the event is related
- * @event	Event in question
- * @wake	Wake subsystem upon capturing the event if value 1
- * @enable	Enable the registration for value 1, disable for value 0
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
-					uint32_t wake, uint32_t enable,
-					uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
-			 device_id, event, wake, enable);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 54f4eb2..ccbfe77 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,29 +11,29 @@
  */
 
 #include <assert.h>
-#include <plat_ipi.h>
-#include <platform_def.h>
-#include <versal_def.h>
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
-#include <drivers/arm/gicv3.h>
-#include <drivers/arm/gic_common.h>
 #include <plat/common/platform.h>
+
+#include <plat_ipi.h>
+#include <platform_def.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_defs.h"
+#include <versal_def.h>
 
 #define UNDEFINED_CPUID		(~0)
-#define IRQ_MAX		142U
-#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
 
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
 static const struct pm_ipi apu_ipi = {
-	.local_ipi_id = IPI_ID_APU,
-	.remote_ipi_id = IPI_ID_PMC,
-	.buffer_base = IPI_BUFFER_APU_BASE,
+	.local_ipi_id = IPI_LOCAL_ID,
+	.remote_ipi_id = IPI_REMOTE_ID,
+	.buffer_base = IPI_BUFFER_LOCAL_BASE,
 };
 
 /* Order in pm_procs_all array must match cpu ids */
@@ -51,122 +52,137 @@
 
 const struct pm_proc *primary_proc = &pm_procs_all[0];
 
-/* Interrupt to PM node index map */
-static enum pm_device_node_idx irq_node_map[IRQ_MAX + 1] = {
-	[13] = XPM_NODEIDX_DEV_GPIO,
-	[14] = XPM_NODEIDX_DEV_I2C_0,
-	[15] = XPM_NODEIDX_DEV_I2C_1,
-	[16] = XPM_NODEIDX_DEV_SPI_0,
-	[17] = XPM_NODEIDX_DEV_SPI_1,
-	[18] = XPM_NODEIDX_DEV_UART_0,
-	[19] = XPM_NODEIDX_DEV_UART_1,
-	[20] = XPM_NODEIDX_DEV_CAN_FD_0,
-	[21] = XPM_NODEIDX_DEV_CAN_FD_1,
-	[22] = XPM_NODEIDX_DEV_USB_0,
-	[23] = XPM_NODEIDX_DEV_USB_0,
-	[24] = XPM_NODEIDX_DEV_USB_0,
-	[25] = XPM_NODEIDX_DEV_USB_0,
-	[26] = XPM_NODEIDX_DEV_USB_0,
-	[37] = XPM_NODEIDX_DEV_TTC_0,
-	[38] = XPM_NODEIDX_DEV_TTC_0,
-	[39] = XPM_NODEIDX_DEV_TTC_0,
-	[40] = XPM_NODEIDX_DEV_TTC_1,
-	[41] = XPM_NODEIDX_DEV_TTC_1,
-	[42] = XPM_NODEIDX_DEV_TTC_1,
-	[43] = XPM_NODEIDX_DEV_TTC_2,
-	[44] = XPM_NODEIDX_DEV_TTC_2,
-	[45] = XPM_NODEIDX_DEV_TTC_2,
-	[46] = XPM_NODEIDX_DEV_TTC_3,
-	[47] = XPM_NODEIDX_DEV_TTC_3,
-	[48] = XPM_NODEIDX_DEV_TTC_3,
-	[56] = XPM_NODEIDX_DEV_GEM_0,
-	[57] = XPM_NODEIDX_DEV_GEM_0,
-	[58] = XPM_NODEIDX_DEV_GEM_1,
-	[59] = XPM_NODEIDX_DEV_GEM_1,
-	[60] = XPM_NODEIDX_DEV_ADMA_0,
-	[61] = XPM_NODEIDX_DEV_ADMA_1,
-	[62] = XPM_NODEIDX_DEV_ADMA_2,
-	[63] = XPM_NODEIDX_DEV_ADMA_3,
-	[64] = XPM_NODEIDX_DEV_ADMA_4,
-	[65] = XPM_NODEIDX_DEV_ADMA_5,
-	[66] = XPM_NODEIDX_DEV_ADMA_6,
-	[67] = XPM_NODEIDX_DEV_ADMA_7,
-	[74] = XPM_NODEIDX_DEV_USB_0,
-	[126] = XPM_NODEIDX_DEV_SDIO_0,
-	[127] = XPM_NODEIDX_DEV_SDIO_0,
-	[128] = XPM_NODEIDX_DEV_SDIO_1,
-	[129] = XPM_NODEIDX_DEV_SDIO_1,
-	[142] = XPM_NODEIDX_DEV_RTC,
-};
-
 /**
- * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number
- * @irq:	Interrupt number
+ * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
+ * @irq: Interrupt number
  *
- * Return:	PM node index corresponding to the specified interrupt
- */
-static enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
-{
-	assert(irq <= IRQ_MAX);
-	return irq_node_map[irq];
-}
-
-/**
- * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as
- *				  wake sources in the LibPM.
- * @node_id:	Node id of processor
+ * Return: PM node index corresponding to the specified interrupt.
+ *
  */
-static void pm_client_set_wakeup_sources(uint32_t node_id)
+enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
 {
-	uint32_t reg_num;
-	uint32_t device_id;
-	uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = { 0U };
-	uintptr_t isenabler1 = PLAT_VERSAL_GICD_BASE + GICD_ISENABLER + 4;
-
-	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
-		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
-		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
-
-		if (reg == 0U) {
-			continue;
-		}
-
-		while (reg != 0U) {
-			enum pm_device_node_idx node_idx;
-			uint32_t idx, irq, lowest_set = reg & (-reg);
-			enum pm_ret_status ret;
-
-			idx = __builtin_ctz(lowest_set);
-			irq = base_irq + idx;
-
-			if (irq > IRQ_MAX) {
-				break;
-			}
+	enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
 
-			node_idx = irq_to_pm_node_idx(irq);
-			reg &= ~lowest_set;
+	assert(irq <= IRQ_MAX);
 
-			if (node_idx > XPM_NODEIDX_DEV_MIN && node_idx < XPM_NODEIDX_DEV_MAX) {
-				if (pm_wakeup_nodes_set[node_idx] == 0U) {
-					/* Get device ID from node index */
-					device_id = PERIPH_DEVID(node_idx);
-					ret = pm_set_wakeup_source(node_id,
-								   device_id, 1,
-								   SECURE_FLAG);
-					pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
-											 1 : 0;
-				}
-			}
-		}
+	switch (irq) {
+	case 13:
+		dev_idx = XPM_NODEIDX_DEV_GPIO;
+		break;
+	case 14:
+		dev_idx = XPM_NODEIDX_DEV_I2C_0;
+		break;
+	case 15:
+		dev_idx = XPM_NODEIDX_DEV_I2C_1;
+		break;
+	case 16:
+		dev_idx = XPM_NODEIDX_DEV_SPI_0;
+		break;
+	case 17:
+		dev_idx = XPM_NODEIDX_DEV_SPI_1;
+		break;
+	case 18:
+		dev_idx = XPM_NODEIDX_DEV_UART_0;
+		break;
+	case 19:
+		dev_idx = XPM_NODEIDX_DEV_UART_1;
+		break;
+	case 20:
+		dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
+		break;
+	case 21:
+		dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
+		break;
+	case 22:
+	case 23:
+	case 24:
+	case 25:
+	case 26:
+		dev_idx = XPM_NODEIDX_DEV_USB_0;
+		break;
+	case 37:
+	case 38:
+	case 39:
+		dev_idx = XPM_NODEIDX_DEV_TTC_0;
+		break;
+	case 40:
+	case 41:
+	case 42:
+		dev_idx = XPM_NODEIDX_DEV_TTC_1;
+		break;
+	case 43:
+	case 44:
+	case 45:
+		dev_idx = XPM_NODEIDX_DEV_TTC_2;
+		break;
+	case 46:
+	case 47:
+	case 48:
+		dev_idx = XPM_NODEIDX_DEV_TTC_3;
+		break;
+	case 56:
+	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;
 	}
+
+	return dev_idx;
 }
 
 /**
- * pm_client_suspend() - Client-specific suspend actions
+ * pm_client_suspend() - Client-specific suspend actions.
+ * @proc: processor which need to suspend.
+ * @state: desired suspend state.
  *
  * This function should contain any PU-specific actions
  * required prior to sending suspend request to PMU
  * Actions taken depend on the state system is suspending to.
+ *
  */
 void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
@@ -184,10 +200,11 @@
 }
 
 /**
- * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions.
  *
  * This function should contain any PU-specific actions
- * required for aborting a prior suspend request
+ * required for aborting a prior suspend request.
+ *
  */
 void pm_client_abort_suspend(void)
 {
@@ -204,10 +221,11 @@
 }
 
 /**
- * pm_get_cpuid() - get the local cpu ID for a global node ID
- * @nid:	node id of the processor
+ * pm_get_cpuid() - get the local cpu ID for a global node ID.
+ * @nid: node id of the processor.
+ *
+ * Return: the cpu ID (starting from 0) for the subsystem.
  *
- * Return: the cpu ID (starting from 0) for the subsystem
  */
 static uint32_t pm_get_cpuid(uint32_t nid)
 {
@@ -220,10 +238,12 @@
 }
 
 /**
- * pm_client_wakeup() - Client-specific wakeup actions
+ * pm_client_wakeup() - Client-specific wakeup actions.
+ * @proc: Processor which need to wakeup.
  *
  * This function should contain any PU-specific actions
- * required for waking up another APU core
+ * required for waking up another APU core.
+ *
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
@@ -244,10 +264,11 @@
 }
 
 /**
- * pm_get_proc() - returns pointer to the proc structure
- * @cpuid:	id of the cpu whose proc struct pointer should be returned
+ * pm_get_proc() - returns pointer to the proc structure.
+ * @cpuid: id of the cpu whose proc struct pointer should be returned.
+ *
+ * Return: pointer to a proc structure if proc is found, otherwise NULL.
  *
- * Return: pointer to a proc structure if proc is found, otherwise NULL
  */
 const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
deleted file mode 100644
index dbc801c..0000000
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* Versal power management enums and defines */
-
-#ifndef PM_DEFS_H
-#define PM_DEFS_H
-
-#include "pm_node.h"
-
-/*********************************************************************
- * Macro definitions
- ********************************************************************/
-
-/* State arguments of the self suspend */
-#define PM_STATE_CPU_IDLE	0x0U
-#define PM_STATE_SUSPEND_TO_RAM	0xFU
-
-#define MAX_LATENCY		(~0U)
-#define MAX_QOS			100U
-
-/* Processor core device IDs */
-#define APU_DEVID(IDX)	NODEID(XPM_NODECLASS_DEVICE, XPM_NODESUBCL_DEV_CORE, \
-			       XPM_NODETYPE_DEV_CORE_APU, (IDX))
-
-#define XPM_DEVID_ACPU_0	APU_DEVID(XPM_NODEIDX_DEV_ACPU_0)
-#define XPM_DEVID_ACPU_1	APU_DEVID(XPM_NODEIDX_DEV_ACPU_1)
-
-#define PERIPH_DEVID(IDX)	NODEID(XPM_NODECLASS_DEVICE, \
-				       XPM_NODESUBCL_DEV_PERIPH, \
-				       XPM_NODETYPE_DEV_PERIPH, (IDX))
-
-#define PM_GET_CALLBACK_DATA		0xa01U
-#define PM_GET_TRUSTZONE_VERSION	0xa03U
-#define TF_A_PM_REGISTER_SGI		0xa04U
-
-/* PM API Versions */
-#define PM_API_BASE_VERSION		1U
-#define PM_API_VERSION_2		2U
-
-/* PM API ids */
-#define PM_REGISTER_NOTIFIER		5U
-#define PM_REQ_SUSPEND			6U
-#define PM_SELF_SUSPEND			7U
-#define PM_FORCE_POWERDOWN		8U
-#define PM_ABORT_SUSPEND		9U
-#define PM_REQ_WAKEUP			10U
-#define PM_SET_WAKEUP_SOURCE		11U
-#define PM_SYSTEM_SHUTDOWN		12U
-#define PM_IOCTL			34U
-#define PM_QUERY_DATA			35U
-#define PM_PLL_SET_PARAMETER		48U
-#define PM_PLL_GET_PARAMETER		49U
-#define PM_PLL_SET_MODE			50U
-#define PM_PLL_GET_MODE			51U
-#define PM_FEATURE_CHECK		63U
-
-/* Loader API ids */
-#define PM_LOAD_PDI			0x701U
-#define PM_LOAD_GET_HANDOFF_PARAMS	0x70BU
-
-/* IOCTL IDs for clock driver */
-#define IOCTL_SET_PLL_FRAC_MODE		8U
-#define	IOCTL_GET_PLL_FRAC_MODE		9U
-#define	IOCTL_SET_PLL_FRAC_DATA		10U
-#define	IOCTL_GET_PLL_FRAC_DATA		11U
-#define	IOCTL_SET_SGI			25U
-
-/* Parameter ID for PLL IOCTLs */
-/* Fractional data portion for PLL */
-#define PM_PLL_PARAM_DATA	2
-
-/* System shutdown macros */
-#define	XPM_SHUTDOWN_TYPE_SHUTDOWN	0U
-#define	XPM_SHUTDOWN_TYPE_RESET		1U
-#define	XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY	2U
-
-#define	XPM_SHUTDOWN_SUBTYPE_RST_SUBSYSTEM	0U
-#define	XPM_SHUTDOWN_SUBTYPE_RST_PS_ONLY	1U
-#define	XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM		2U
-
-/*********************************************************************
- * Enum definitions
- ********************************************************************/
-
-enum pm_abort_reason {
-	ABORT_REASON_WKUP_EVENT = 100,
-	ABORT_REASON_PU_BUSY,
-	ABORT_REASON_NO_PWRDN,
-	ABORT_REASON_UNKNOWN,
-};
-
-enum pm_opchar_type {
-	PM_OPCHAR_TYPE_POWER = 1,
-	PM_OPCHAR_TYPE_TEMP,
-	PM_OPCHAR_TYPE_LATENCY,
-};
-
-/**
- * Subsystem IDs
- */
-typedef enum {
-	XPM_SUBSYSID_PMC,
-	XPM_SUBSYSID_PSM,
-	XPM_SUBSYSID_APU,
-	XPM_SUBSYSID_RPU0_LOCK,
-	XPM_SUBSYSID_RPU0_0,
-	XPM_SUBSYSID_RPU0_1,
-	XPM_SUBSYSID_DDR0,
-	XPM_SUBSYSID_ME,
-	XPM_SUBSYSID_PL,
-	XPM_SUBSYSID_MAX,
-} XPm_SubsystemId;
-
-/* TODO: move pm_ret_status from device specific location to common location */
-/**
- * @PM_RET_SUCCESS:		success
- * @PM_RET_ERROR_ARGS:		illegal arguments provided (deprecated)
- * @PM_RET_ERROR_NOTSUPPORTED:	feature not supported  (deprecated)
- * @PM_RET_ERROR_NOFEATURE:	feature is not available
- * @PM_RET_ERROR_INVALID_CRC:	invalid crc in IPI communication
- * @PM_RET_ERROR_INTERNAL:	internal error
- * @PM_RET_ERROR_CONFLICT:	conflict
- * @PM_RET_ERROR_ACCESS:	access rights violation
- * @PM_RET_ERROR_INVALID_NODE:	invalid node
- * @PM_RET_ERROR_DOUBLE_REQ:	duplicate request for same node
- * @PM_RET_ERROR_ABORT_SUSPEND:	suspend procedure has been aborted
- * @PM_RET_ERROR_TIMEOUT:	timeout in communication with PMU
- * @PM_RET_ERROR_NODE_USED:	node is already in use
- */
-enum pm_ret_status {
-	PM_RET_SUCCESS,
-	PM_RET_ERROR_ARGS = 1,
-	PM_RET_ERROR_NOTSUPPORTED = 4,
-	PM_RET_ERROR_NOFEATURE = 19,
-	PM_RET_ERROR_INVALID_CRC = 301,
-	PM_RET_ERROR_INTERNAL = 2000,
-	PM_RET_ERROR_CONFLICT = 2001,
-	PM_RET_ERROR_ACCESS = 2002,
-	PM_RET_ERROR_INVALID_NODE = 2003,
-	PM_RET_ERROR_DOUBLE_REQ = 2004,
-	PM_RET_ERROR_ABORT_SUSPEND = 2005,
-	PM_RET_ERROR_TIMEOUT = 2006,
-	PM_RET_ERROR_NODE_USED = 2007
-};
-
-/**
- * Qids
- */
-enum pm_query_id {
-	XPM_QID_INVALID,
-	XPM_QID_CLOCK_GET_NAME,
-	XPM_QID_CLOCK_GET_TOPOLOGY,
-	XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
-	XPM_QID_CLOCK_GET_MUXSOURCES,
-	XPM_QID_CLOCK_GET_ATTRIBUTES,
-	XPM_QID_PINCTRL_GET_NUM_PINS,
-	XPM_QID_PINCTRL_GET_NUM_FUNCTIONS,
-	XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
-	XPM_QID_PINCTRL_GET_FUNCTION_NAME,
-	XPM_QID_PINCTRL_GET_FUNCTION_GROUPS,
-	XPM_QID_PINCTRL_GET_PIN_GROUPS,
-	XPM_QID_CLOCK_GET_NUM_CLOCKS,
-	XPM_QID_CLOCK_GET_MAX_DIVISOR,
-	XPM_QID_PLD_GET_PARENT,
-};
-#endif /* PM_DEFS_H */
diff --git a/plat/xilinx/versal/pm_service/pm_node.h b/plat/xilinx/versal/pm_service/pm_node.h
deleted file mode 100644
index 1b82ec7..0000000
--- a/plat/xilinx/versal/pm_service/pm_node.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* Versal PM nodes enums and defines */
-
-#ifndef PM_NODE_H
-#define PM_NODE_H
-
-/*********************************************************************
- * Macro definitions
- ********************************************************************/
-
-#define NODE_CLASS_SHIFT	26U
-#define NODE_SUBCLASS_SHIFT	20U
-#define NODE_TYPE_SHIFT		14U
-#define NODE_INDEX_SHIFT	0U
-#define NODE_CLASS_MASK_BITS    0x3F
-#define NODE_SUBCLASS_MASK_BITS 0x3F
-#define NODE_TYPE_MASK_BITS     0x3F
-#define NODE_INDEX_MASK_BITS    0x3FFF
-#define NODE_CLASS_MASK         (NODE_CLASS_MASK_BITS << NODE_CLASS_SHIFT)
-#define NODE_SUBCLASS_MASK      (NODE_SUBCLASS_MASK_BITS << NODE_SUBCLASS_SHIFT)
-#define NODE_TYPE_MASK          (NODE_TYPE_MASK_BITS << NODE_TYPE_SHIFT)
-#define NODE_INDEX_MASK         (NODE_INDEX_MASK_BITS << NODE_INDEX_SHIFT)
-
-#define NODEID(CLASS, SUBCLASS, TYPE, INDEX)	\
-	     ((((CLASS) & NODE_CLASS_MASK_BITS) << NODE_CLASS_SHIFT) | \
-	     (((SUBCLASS) & NODE_SUBCLASS_MASK_BITS) << NODE_SUBCLASS_SHIFT) | \
-	     (((TYPE) & NODE_TYPE_MASK_BITS) << NODE_TYPE_SHIFT) | \
-	     (((INDEX) & NODE_INDEX_MASK_BITS) << NODE_INDEX_SHIFT))
-
-#define NODECLASS(ID)		(((ID) & NODE_CLASS_MASK) >> NODE_CLASS_SHIFT)
-#define NODESUBCLASS(ID)	(((ID) & NODE_SUBCLASS_MASK) >> \
-				NODE_SUBCLASS_SHIFT)
-#define NODETYPE(ID)		(((ID) & NODE_TYPE_MASK) >> NODE_TYPE_SHIFT)
-#define NODEINDEX(ID)		(((ID) & NODE_INDEX_MASK) >> NODE_INDEX_SHIFT)
-
-/*********************************************************************
- * Enum definitions
- ********************************************************************/
-
-/* Node class types */
-enum pm_node_class {
-	XPM_NODECLASS_MIN,
-
-	XPM_NODECLASS_POWER,
-	XPM_NODECLASS_CLOCK,
-	XPM_NODECLASS_RESET,
-	XPM_NODECLASS_MEMIC,
-	XPM_NODECLASS_STMIC,
-	XPM_NODECLASS_DEVICE,
-
-	XPM_NODECLASS_MAX
-};
-
-enum pm_device_node_subclass {
-	/* Device types */
-	XPM_NODESUBCL_DEV_CORE = 1,
-	XPM_NODESUBCL_DEV_PERIPH,
-	XPM_NODESUBCL_DEV_MEM,
-	XPM_NODESUBCL_DEV_SOC,
-	XPM_NODESUBCL_DEV_MEM_CTRLR,
-	XPM_NODESUBCL_DEV_PHY,
-};
-
-enum pm_device_node_type {
-	/* Device types */
-	XPM_NODETYPE_DEV_CORE_PMC = 1,
-	XPM_NODETYPE_DEV_CORE_PSM,
-	XPM_NODETYPE_DEV_CORE_APU,
-	XPM_NODETYPE_DEV_CORE_RPU,
-	XPM_NODETYPE_DEV_OCM,
-	XPM_NODETYPE_DEV_TCM,
-	XPM_NODETYPE_DEV_L2CACHE,
-	XPM_NODETYPE_DEV_DDR,
-	XPM_NODETYPE_DEV_PERIPH,
-	XPM_NODETYPE_DEV_SOC,
-	XPM_NODETYPE_DEV_GT,
-};
-
-/* Device node Indexes */
-enum pm_device_node_idx {
-	/* Device nodes */
-	XPM_NODEIDX_DEV_MIN,
-
-	/* Processor devices */
-	XPM_NODEIDX_DEV_PMC_PROC,
-	XPM_NODEIDX_DEV_PSM_PROC,
-	XPM_NODEIDX_DEV_ACPU_0,
-	XPM_NODEIDX_DEV_ACPU_1,
-	XPM_NODEIDX_DEV_RPU0_0,
-	XPM_NODEIDX_DEV_RPU0_1,
-
-	/* Memory devices */
-	XPM_NODEIDX_DEV_OCM_0,
-	XPM_NODEIDX_DEV_OCM_1,
-	XPM_NODEIDX_DEV_OCM_2,
-	XPM_NODEIDX_DEV_OCM_3,
-	XPM_NODEIDX_DEV_TCM_0_A,
-	XPM_NODEIDX_DEV_TCM_0_B,
-	XPM_NODEIDX_DEV_TCM_1_A,
-	XPM_NODEIDX_DEV_TCM_1_B,
-	XPM_NODEIDX_DEV_L2_BANK_0,
-	XPM_NODEIDX_DEV_DDR_0,
-	XPM_NODEIDX_DEV_DDR_1,
-	XPM_NODEIDX_DEV_DDR_2,
-	XPM_NODEIDX_DEV_DDR_3,
-	XPM_NODEIDX_DEV_DDR_4,
-	XPM_NODEIDX_DEV_DDR_5,
-	XPM_NODEIDX_DEV_DDR_6,
-	XPM_NODEIDX_DEV_DDR_7,
-
-	/* LPD Peripheral devices */
-	XPM_NODEIDX_DEV_USB_0,
-	XPM_NODEIDX_DEV_GEM_0,
-	XPM_NODEIDX_DEV_GEM_1,
-	XPM_NODEIDX_DEV_SPI_0,
-	XPM_NODEIDX_DEV_SPI_1,
-	XPM_NODEIDX_DEV_I2C_0,
-	XPM_NODEIDX_DEV_I2C_1,
-	XPM_NODEIDX_DEV_CAN_FD_0,
-	XPM_NODEIDX_DEV_CAN_FD_1,
-	XPM_NODEIDX_DEV_UART_0,
-	XPM_NODEIDX_DEV_UART_1,
-	XPM_NODEIDX_DEV_GPIO,
-	XPM_NODEIDX_DEV_TTC_0,
-	XPM_NODEIDX_DEV_TTC_1,
-	XPM_NODEIDX_DEV_TTC_2,
-	XPM_NODEIDX_DEV_TTC_3,
-	XPM_NODEIDX_DEV_SWDT_LPD,
-
-	/* FPD Peripheral devices */
-	XPM_NODEIDX_DEV_SWDT_FPD,
-
-	/* PMC Peripheral devices */
-	XPM_NODEIDX_DEV_OSPI,
-	XPM_NODEIDX_DEV_QSPI,
-	XPM_NODEIDX_DEV_GPIO_PMC,
-	XPM_NODEIDX_DEV_I2C_PMC,
-	XPM_NODEIDX_DEV_SDIO_0,
-	XPM_NODEIDX_DEV_SDIO_1,
-
-	XPM_NODEIDX_DEV_PL_0,
-	XPM_NODEIDX_DEV_PL_1,
-	XPM_NODEIDX_DEV_PL_2,
-	XPM_NODEIDX_DEV_PL_3,
-	XPM_NODEIDX_DEV_RTC,
-	XPM_NODEIDX_DEV_ADMA_0,
-	XPM_NODEIDX_DEV_ADMA_1,
-	XPM_NODEIDX_DEV_ADMA_2,
-	XPM_NODEIDX_DEV_ADMA_3,
-	XPM_NODEIDX_DEV_ADMA_4,
-	XPM_NODEIDX_DEV_ADMA_5,
-	XPM_NODEIDX_DEV_ADMA_6,
-	XPM_NODEIDX_DEV_ADMA_7,
-	XPM_NODEIDX_DEV_IPI_0,
-	XPM_NODEIDX_DEV_IPI_1,
-	XPM_NODEIDX_DEV_IPI_2,
-	XPM_NODEIDX_DEV_IPI_3,
-	XPM_NODEIDX_DEV_IPI_4,
-	XPM_NODEIDX_DEV_IPI_5,
-	XPM_NODEIDX_DEV_IPI_6,
-
-	/* Entire SoC */
-	XPM_NODEIDX_DEV_SOC,
-
-	/* DDR memory controllers */
-	XPM_NODEIDX_DEV_DDRMC_0,
-	XPM_NODEIDX_DEV_DDRMC_1,
-	XPM_NODEIDX_DEV_DDRMC_2,
-	XPM_NODEIDX_DEV_DDRMC_3,
-
-	/* GT devices */
-	XPM_NODEIDX_DEV_GT_0,
-	XPM_NODEIDX_DEV_GT_1,
-	XPM_NODEIDX_DEV_GT_2,
-	XPM_NODEIDX_DEV_GT_3,
-	XPM_NODEIDX_DEV_GT_4,
-	XPM_NODEIDX_DEV_GT_5,
-	XPM_NODEIDX_DEV_GT_6,
-	XPM_NODEIDX_DEV_GT_7,
-	XPM_NODEIDX_DEV_GT_8,
-	XPM_NODEIDX_DEV_GT_9,
-	XPM_NODEIDX_DEV_GT_10,
-
-	XPM_NODEIDX_DEV_MAX
-};
-
-#endif /* PM_NODE_H */
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index 28a4cb9..b30254d 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,7 +41,9 @@
 /**
  * sip_svc_setup() - Setup SiP Service
  *
- * Invokes PM setup
+ * Return: 0 on success,negative error code on failure.
+ *
+ * Invokes PM setup.
  */
 static int32_t sip_svc_setup(void)
 {
@@ -51,10 +54,20 @@
 }
 
 /**
- * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ * sip_svc_smc_handler() - Top-level SiP Service SMC handler.
+ * @smc_fid: Function Identifier.
+ * @x1: SMC64 Arguments 1 from kernel.
+ * @x2: SMC64 Arguments 2 from kernel.
+ * @x3: SMC64 Arguments 3 from kernel(upper 32-bits).
+ * @x4: SMC64 Arguments 4 from kernel.
+ * @cookie: Unused
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * Handler for all SiP SMC calls. Handles standard SIP requests
  * and calls PM SMC handler if the call is for a PM-API function.
+ *
+ * Return: Unused.
  */
 uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 			     u_register_t x1,
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 0959c8e..197d047 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -1,17 +1,19 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_private.h>
-#include <platform_def.h>
-
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
+#include <plat_private.h>
+#include <platform_def.h>
+
+
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv3 driver is initialised and used.
@@ -60,8 +62,8 @@
 }
 
 static const gicv3_driver_data_t versal_gic_data __unused = {
-	.gicd_base = PLAT_VERSAL_GICD_BASE,
-	.gicr_base = PLAT_VERSAL_GICR_BASE,
+	.gicd_base = PLAT_GICD_BASE_VALUE,
+	.gicr_base = PLAT_GICR_BASE_VALUE,
 	.interrupt_props = versal_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(versal_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
diff --git a/plat/xilinx/versal/versal_ipi.c b/plat/xilinx/versal/versal_ipi.c
index 67915f4..cdee6b5 100644
--- a/plat/xilinx/versal/versal_ipi.c
+++ b/plat/xilinx/versal/versal_ipi.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,15 +9,10 @@
  * Versal IPI agent registers access management
  */
 
-#include <errno.h>
+#include <lib/utils_def.h>
+
 #include <ipi.h>
 #include <plat_ipi.h>
-#include <plat_private.h>
-#include <string.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
 
 /* versal ipi configuration table */
 static const struct ipi_config versal_ipi_table[] = {
@@ -70,10 +66,9 @@
 	},
 };
 
-/* versal_ipi_config_table_init() - Initialize versal IPI configuration data
- *
- * @ipi_config_table  - IPI configuration table
- * @ipi_total - Total number of IPI available
+/* versal_ipi_config_table_init() - Initialize versal IPI configuration data.
+ * @ipi_config_table: IPI configuration table.
+ * @ipi_total: Total number of IPI available.
  *
  */
 void versal_ipi_config_table_init(void)
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index c78b5d0..b2de411 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
+#include <plat_common.h>
 #include <plat_ipi.h>
 
 #include <plat_private.h>
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index 48082a6..bc62efc 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -1,14 +1,16 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <arch.h>
 #include <asm_macros.S>
+
+#include <arch.h>
 #include <drivers/arm/gicv3.h>
+
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index a7bae72..79205a3 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,9 @@
 
 #include <plat_private.h>
 #include <plat_startup.h>
+#include <pm_api_sys.h>
+#include <pm_client.h>
+#include <pm_ipi.h>
 #include <versal_net_def.h>
 
 static entry_point_info_t bl32_image_ep_info;
@@ -70,6 +73,11 @@
 {
 	uint32_t uart_clock;
 	int32_t rc;
+#if !(TFA_NO_PM)
+	uint64_t tfa_handoff_addr, buff[HANDOFF_PARAMS_MAX_SIZE] = {0};
+	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
+	enum pm_ret_status ret_status;
+#endif /* !(TFA_NO_PM) */
 
 	board_detection();
 
@@ -123,9 +131,6 @@
 
 	/* Initialize the platform config for future decision making */
 	versal_net_config_setup();
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
 
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
@@ -139,8 +144,32 @@
 	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if !(TFA_NO_PM)
+	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+			 (uintptr_t)buff >> 32U, (uintptr_t)buff, max_size);
 
+	ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	if (ret_status == PM_RET_SUCCESS) {
+		enum xbl_handoff xbl_ret;
+
+		tfa_handoff_addr = (uintptr_t)&buff;
+
+		xbl_ret = xbl_handover(&bl32_image_ep_info, &bl33_image_ep_info,
+				       tfa_handoff_addr);
+		if (xbl_ret != XBL_HANDOFF_SUCCESS) {
+			ERROR("BL31: PLM to TF-A handover failed %u\n", xbl_ret);
+			panic();
+		}
+
+		INFO("BL31: PLM to TF-A handover success\n");
+	} else {
+		INFO("BL31: setting up default configs\n");
+
+		bl31_set_default_config();
+	}
+#else
 	bl31_set_default_config();
+#endif /* !(TFA_NO_PM) */
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
 	NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
index 5ac611c..9f9947e 100644
--- a/plat/xilinx/versal_net/include/plat_ipi.h
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,16 +31,14 @@
  ********************************************************************/
 #define IPI_BUFFER_BASEADDR	(0xEB3F0000U)
 
-#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
-#define IPI_BUFFER_PMC_BASE	(IPI_BUFFER_BASEADDR + 0x200U)
+#define IPI_LOCAL_ID		IPI_ID_APU
+#define IPI_REMOTE_ID		IPI_ID_PMC
 
-#define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
-#define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
+#define IPI_BUFFER_LOCAL_BASE	(IPI_BUFFER_BASEADDR + (IPI_LOCAL_ID * 0x200U))
+#define IPI_BUFFER_REMOTE_BASE	(IPI_BUFFER_BASEADDR + (IPI_REMOTE_ID * 0x200U))
 
-#define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
-
-#define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
-#define IPI_BUFFER_TARGET_REMOTE_OFFSET	IPI_BUFFER_TARGET_PMC_OFFSET
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	(IPI_LOCAL_ID * 0x40U)
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	(IPI_REMOTE_ID * 0x40U)
 
 #define IPI_BUFFER_MAX_WORDS	8
 
@@ -54,4 +52,21 @@
 /* Configure IPI table for versal_net */
 void versal_net_ipi_config_table_init(void);
 
+/*******************************************************************************
+ * IPI registers and bitfields
+ ******************************************************************************/
+#define IPI0_REG_BASE		(0xEB330000U)
+#define IPI0_TRIG_BIT		(1 << 2)
+#define PMC_IPI_TRIG_BIT	(1 << 1)
+#define IPI1_REG_BASE		(0xEB340000U)
+#define IPI1_TRIG_BIT		(1 << 3)
+#define IPI2_REG_BASE		(0xEB350000U)
+#define IPI2_TRIG_BIT		(1 << 4)
+#define IPI3_REG_BASE		(0xEB360000U)
+#define IPI3_TRIG_BIT		(1 << 5)
+#define IPI4_REG_BASE		(0xEB370000U)
+#define IPI4_TRIG_BIT		(1 << 6)
+#define IPI5_REG_BASE		(0xEB380000U)
+#define IPI5_TRIG_BIT		(1 << 7)
+
 #endif /* PLAT_IPI_H */
diff --git a/plat/xilinx/versal_net/include/plat_macros.S b/plat/xilinx/versal_net/include/plat_macros.S
index fb108b6..db7e42b 100644
--- a/plat/xilinx/versal_net/include/plat_macros.S
+++ b/plat/xilinx/versal_net/include/plat_macros.S
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -109,8 +109,8 @@
 	 * Uncomment it when versions are stable
 	 */
 	/*
-	mov_imm	x17, PLAT_VERSAL_NET_GICD_BASE
-	mov_imm	x16, PLAT_VERSAL_NET_GICR_BASE
+	mov_imm	x17, PLAT_GICD_BASE_VALUE
+	mov_imm	x16, PLAT_GICR_BASE_VALUE
 	versal_net_print_gic_regs
 	*/
 	.endm
diff --git a/plat/xilinx/versal_net/include/plat_pm_common.h b/plat/xilinx/versal_net/include/plat_pm_common.h
index ad7b40f..6485df7 100644
--- a/plat/xilinx/versal_net/include/plat_pm_common.h
+++ b/plat/xilinx/versal_net/include/plat_pm_common.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h
index 6a3bc19..be75bfd 100644
--- a/plat/xilinx/versal_net/include/plat_private.h
+++ b/plat/xilinx/versal_net/include/plat_private.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,7 +43,4 @@
  */
 int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
 
-#define PM_GET_CHIPID			(24U)
-#define IOCTL_OSPI_MUX_SELECT		(21U)
-
 #endif /* PLAT_PRIVATE_H */
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index 9aa1441..b256b05 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,13 +38,13 @@
  */
 #ifndef VERSAL_NET_ATF_MEM_BASE
 # define BL31_BASE			U(0xBBF00000)
-# define BL31_LIMIT			U(0xBBFFFFFF)
+# define BL31_LIMIT			U(0xBC000000)
 #else
 # define BL31_BASE			U(VERSAL_NET_ATF_MEM_BASE)
-# define BL31_LIMIT			U(VERSAL_NET_ATF_MEM_BASE + VERSAL_NET_ATF_MEM_SIZE - 1)
+# define BL31_LIMIT			U(VERSAL_NET_ATF_MEM_BASE + VERSAL_NET_ATF_MEM_SIZE)
 # ifdef VERSAL_NET_ATF_MEM_PROGBITS_SIZE
 #  define BL31_PROGBITS_LIMIT		U(VERSAL_NET_ATF_MEM_BASE + \
-					  VERSAL_NET_ATF_MEM_PROGBITS_SIZE - 1)
+					  VERSAL_NET_ATF_MEM_PROGBITS_SIZE)
 # endif
 #endif
 
@@ -53,10 +53,10 @@
  ******************************************************************************/
 #ifndef VERSAL_NET_BL32_MEM_BASE
 # define BL32_BASE			U(0x60000000)
-# define BL32_LIMIT			U(0x7FFFFFFF)
+# define BL32_LIMIT			U(0x80000000)
 #else
 # define BL32_BASE			U(VERSAL_NET_BL32_MEM_BASE)
-# define BL32_LIMIT			U(VERSAL_NET_BL32_MEM_BASE + VERSAL_NET_BL32_MEM_SIZE - 1)
+# define BL32_LIMIT			U(VERSAL_NET_BL32_MEM_BASE + VERSAL_NET_BL32_MEM_SIZE)
 #endif
 
 /*******************************************************************************
@@ -72,7 +72,7 @@
  * TSP  specific defines.
  ******************************************************************************/
 #define TSP_SEC_MEM_BASE		BL32_BASE
-#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1U)
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
 
 /* ID of the secure physical generic timer interrupt used by the TSP */
 #define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
@@ -95,8 +95,8 @@
 #define CACHE_WRITEBACK_SHIFT	U(6)
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
 
-#define PLAT_VERSAL_NET_GICD_BASE	U(0xE2000000)
-#define PLAT_VERSAL_NET_GICR_BASE	U(0xE2060000)
+#define PLAT_GICD_BASE_VALUE	U(0xE2000000)
+#define PLAT_GICR_BASE_VALUE	U(0xE2060000)
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -114,4 +114,6 @@
 	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
 
+#define IRQ_MAX		200U
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 9d1b7c2..758882c 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,12 +13,6 @@
 #include <plat/common/common_def.h>
 
 #define MAX_INTR_EL3			2
-/* This part is taken from U-Boot project under GPL that's why dual license above */
-#define __bf_shf(x) (__builtin_ffsll(x) - 1U)
-#define FIELD_GET(_mask, _reg)						\
-	({								\
-		(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\
-	})
 
 /* List all consoles */
 #define VERSAL_NET_CONSOLE_ID_pl011	U(1)
@@ -154,23 +148,6 @@
 #define PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ	VERSAL_NET_UART_CLOCK
 #define VERSAL_NET_CONSOLE_BAUDRATE		VERSAL_NET_UART_BAUDRATE
 
-/*******************************************************************************
- * IPI registers and bitfields
- ******************************************************************************/
-#define IPI0_REG_BASE		(0xEB330000U)
-#define IPI0_TRIG_BIT		(1 << 2)
-#define PMC_IPI_TRIG_BIT	(1 << 1)
-#define IPI1_REG_BASE		(0xEB340000U)
-#define IPI1_TRIG_BIT		(1 << 3)
-#define IPI2_REG_BASE		(0xEB350000U)
-#define IPI2_TRIG_BIT		(1 << 4)
-#define IPI3_REG_BASE		(0xEB360000U)
-#define IPI3_TRIG_BIT		(1 << 5)
-#define IPI4_REG_BASE		(0xEB370000U)
-#define IPI4_TRIG_BIT		(1 << 6)
-#define IPI5_REG_BASE		(0xEB380000U)
-#define IPI5_TRIG_BIT		(1 << 7)
-
 /* Processor core device IDs */
 #define PM_DEV_CLUSTER0_ACPU_0	(0x1810C0AFU)
 #define PM_DEV_CLUSTER0_ACPU_1	(0x1810C0B0U)
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index c5833a9..6e556cd 100644
--- a/plat/xilinx/versal_net/plat_psci.c
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,11 +17,10 @@
 #include <plat_arm.h>
 
 #include <plat_private.h>
+#include <pm_defs.h>
 
 #define PM_RET_ERROR_NOFEATURE U(19)
 
-#define PM_IOCTL	34U
-
 static uintptr_t versal_net_sec_entry;
 
 static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index c713061..87e25bc 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,9 +50,10 @@
 }
 
 /**
- * versal_net_pwr_domain_off() - This function performs actions to turn off core
+ * versal_net_pwr_domain_off() - This function performs actions to turn off
+ *                               core.
+ * @target_state: Targeted state.
  *
- * @param target_state	Targeted state
  */
 static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 {
@@ -80,8 +81,10 @@
 }
 
 /**
- * versal_net_system_reset() - This function sends the reset request
- * to firmware for the system to reset.  This function does not return.
+ * versal_net_system_reset() - This function sends the reset request to firmware
+ *                             for the system to reset. This function does not
+ *                             return.
+ *
  */
 static void __dead2 versal_net_system_reset(void)
 {
@@ -96,9 +99,9 @@
 
 /**
  * versal_net_pwr_domain_suspend() - This function sends request to PMC to suspend
- * core.
+ *                                   core.
+ * @target_state: Targeted state.
  *
- * @param target_state	Targeted state
  */
 static void versal_net_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
@@ -140,9 +143,9 @@
 
 /**
  * versal_net_pwr_domain_suspend_finish() - This function performs actions to finish
- * suspend procedure.
+ *                                          suspend procedure.
+ * @target_state: Targeted state.
  *
- * @param target_state	Targeted state
  */
 static void versal_net_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
 {
@@ -168,7 +171,8 @@
 
 /**
  * versal_net_system_off() - This function sends the system off request
- * to firmware.  This function does not return.
+ *                           to firmware. This function does not return.
+ *
  */
 static void __dead2 versal_net_system_off(void)
 {
@@ -183,12 +187,12 @@
 
 /**
  * versal_net_validate_power_state() - This function ensures that the power state
- * parameter in request is valid.
+ *                                     parameter in request is valid.
+ * @power_state: Power state of core.
+ * @req_state: Requested state.
  *
- * @param power_state		Power state of core
- * @param req_state		Requested state
+ * Return: Returns status, either PSCI_E_SUCCESS or reason.
  *
- * @return Returns status, either PSCI_E_SUCCESS or reason
  */
 static int32_t versal_net_validate_power_state(unsigned int power_state,
 					       psci_power_state_t *req_state)
@@ -196,7 +200,6 @@
 	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
 
 	int32_t pstate = psci_get_pstate_type(power_state);
-	uint64_t i;
 
 	assert(req_state);
 
@@ -204,8 +207,7 @@
 	if (pstate == PSTATE_TYPE_STANDBY) {
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
 	} else {
-		for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
-			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
 	}
 
 	/* We expect the 'state id' to be zero */
@@ -217,9 +219,10 @@
 }
 
 /**
- * versal_net_get_sys_suspend_power_state() - Get power state for system suspend
+ * versal_net_get_sys_suspend_power_state() - Get power state for system
+ *                                            suspend.
+ * @req_state: Requested state.
  *
- * @param req_state	Requested state
  */
 static void versal_net_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
diff --git a/plat/xilinx/versal_net/plat_topology.c b/plat/xilinx/versal_net/plat_topology.c
index 7f985b0..ee756c4 100644
--- a/plat/xilinx/versal_net/plat_topology.c
+++ b/plat/xilinx/versal_net/plat_topology.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 28e3295..398ef85 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -1,6 +1,6 @@
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
-# Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -17,6 +17,7 @@
 SEPARATE_CODE_AND_RODATA := 1
 override RESET_TO_BL31 := 1
 PL011_GENERIC_UART := 1
+IPI_CRC_CHECK := 0
 GIC_ENABLE_V4_EXTN :=  0
 GICV3_SUPPORT_GIC600 := 1
 TFA_NO_PM := 0
@@ -49,6 +50,10 @@
     $(eval $(call add_define,VERSAL_NET_BL32_MEM_SIZE))
 endif
 
+ifdef IPI_CRC_CHECK
+    $(eval $(call add_define,IPI_CRC_CHECK))
+endif
+
 USE_COHERENT_MEM := 0
 HW_ASSISTED_COHERENCY := 1
 
@@ -87,10 +92,10 @@
 				lib/cpus/aarch64/cortex_a78.S			\
 				plat/common/plat_psci_common.c
 ifeq ($(TFA_NO_PM), 0)
-BL31_SOURCES		+=	plat/xilinx/versal/pm_service/pm_api_sys.c	\
+BL31_SOURCES		+=	plat/xilinx/common/pm_service/pm_api_sys.c	\
 				plat/xilinx/common/pm_service/pm_ipi.c		\
 				${PLAT_PATH}/plat_psci_pm.c			\
-				plat/xilinx/versal/pm_service/pm_svc_main.c	\
+				plat/xilinx/common/pm_service/pm_svc_main.c	\
 				${PLAT_PATH}/pm_service/pm_client.c		\
 				${PLAT_PATH}/versal_net_ipi.c
 else
@@ -99,6 +104,7 @@
 BL31_SOURCES		+=	plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
+				plat/xilinx/common/versal.c			\
 				${PLAT_PATH}/bl31_versal_net_setup.c		\
 				${PLAT_PATH}/plat_topology.c			\
 				common/fdt_fixup.c				\
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index f543193..626611c 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,7 +16,7 @@
 #include <drivers/arm/gicv3.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
-#include <lib/mmio.h>
+#include <lib/spinlock.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
@@ -29,12 +29,39 @@
 #define UNDEFINED_CPUID		(~0)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
+
+/*
+ * ARM v8.2, the cache will turn off automatically when cpu
+ * power down. Therefore, there is no doubt to use the spin_lock here.
+ */
+#if !HW_ASSISTED_COHERENCY
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
+static inline void pm_client_lock_get(void)
+{
+	bakery_lock_get(&pm_client_secure_lock);
+}
+
+static inline void pm_client_lock_release(void)
+{
+	bakery_lock_release(&pm_client_secure_lock);
+}
+#else
+spinlock_t pm_client_secure_lock;
+static inline void pm_client_lock_get(void)
+{
+	spin_lock(&pm_client_secure_lock);
+}
+
+static inline void pm_client_lock_release(void)
+{
+	spin_unlock(&pm_client_secure_lock);
+}
+#endif
 
 static const struct pm_ipi apu_ipi = {
-	.local_ipi_id = IPI_ID_APU,
-	.remote_ipi_id = IPI_ID_PMC,
-	.buffer_base = IPI_BUFFER_APU_BASE,
+	.local_ipi_id = IPI_LOCAL_ID,
+	.remote_ipi_id = IPI_REMOTE_ID,
+	.buffer_base = IPI_BUFFER_LOCAL_BASE,
 };
 
 /* Order in pm_procs_all array must match cpu ids */
@@ -124,10 +151,11 @@
 const struct pm_proc *primary_proc = &pm_procs_all[0];
 
 /**
- * pm_get_proc() - returns pointer to the proc structure
- * @param cpuid	id of the cpu whose proc struct pointer should be returned
+ * pm_get_proc() - returns pointer to the proc structure.
+ * @cpuid: id of the cpu whose proc struct pointer should be returned.
+ *
+ * Return: Pointer to a proc structure if proc is found, otherwise NULL.
  *
- * @return pointer to a proc structure if proc is found, otherwise NULL
  */
 const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
@@ -140,23 +168,152 @@
 }
 
 /**
- * pm_client_suspend() - Client-specific suspend actions
+ * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
+ * @irq: Interrupt number.
  *
- * This function should contain any PU-specific actions
- * required prior to sending suspend request to PMU
- * Actions taken depend on the state system is suspending to.
+ * Return: PM node index corresponding to the specified interrupt.
  *
- * @param proc	processor which need to suspend
- * @param state	desired suspend state
+ */
+enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
+{
+	enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
+
+	assert(irq <= IRQ_MAX);
+
+	switch (irq) {
+	case 20:
+		dev_idx = XPM_NODEIDX_DEV_GPIO;
+		break;
+	case 21:
+		dev_idx = XPM_NODEIDX_DEV_I2C_0;
+		break;
+	case 22:
+		dev_idx = XPM_NODEIDX_DEV_I2C_1;
+		break;
+	case 23:
+		dev_idx = XPM_NODEIDX_DEV_SPI_0;
+		break;
+	case 24:
+		dev_idx = XPM_NODEIDX_DEV_SPI_1;
+		break;
+	case 25:
+		dev_idx = XPM_NODEIDX_DEV_UART_0;
+		break;
+	case 26:
+		dev_idx = XPM_NODEIDX_DEV_UART_1;
+		break;
+	case 27:
+		dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
+		break;
+	case 28:
+		dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
+		break;
+	case 29:
+	case 30:
+	case 31:
+	case 32:
+	case 33:
+	case 98:
+		dev_idx = XPM_NODEIDX_DEV_USB_0;
+		break;
+	case 34:
+	case 35:
+	case 36:
+	case 37:
+	case 38:
+	case 99:
+		dev_idx = XPM_NODEIDX_DEV_USB_1;
+		break;
+	case 39:
+	case 40:
+		dev_idx = XPM_NODEIDX_DEV_GEM_0;
+		break;
+	case 41:
+	case 42:
+		dev_idx = XPM_NODEIDX_DEV_GEM_1;
+		break;
+	case 43:
+	case 44:
+	case 45:
+		dev_idx = XPM_NODEIDX_DEV_TTC_0;
+		break;
+	case 46:
+	case 47:
+	case 48:
+		dev_idx = XPM_NODEIDX_DEV_TTC_1;
+		break;
+	case 49:
+	case 50:
+	case 51:
+		dev_idx = XPM_NODEIDX_DEV_TTC_2;
+		break;
+	case 52:
+	case 53:
+	case 54:
+		dev_idx = XPM_NODEIDX_DEV_TTC_3;
+		break;
+	case 72:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_0;
+		break;
+	case 73:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_1;
+		break;
+	case 74:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_2;
+		break;
+	case 75:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_3;
+		break;
+	case 76:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_4;
+		break;
+	case 77:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_5;
+		break;
+	case 78:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_6;
+		break;
+	case 79:
+		dev_idx = XPM_NODEIDX_DEV_ADMA_7;
+		break;
+	case 184:
+	case 185:
+		dev_idx = XPM_NODEIDX_DEV_SDIO_0;
+		break;
+	case 186:
+	case 187:
+		dev_idx = XPM_NODEIDX_DEV_SDIO_1;
+		break;
+	case 200:
+		dev_idx = XPM_NODEIDX_DEV_RTC;
+		break;
+	default:
+		dev_idx = XPM_NODEIDX_DEV_MIN;
+		break;
+	}
+
+	return dev_idx;
+}
+
+/**
+ * pm_client_suspend() - Client-specific suspend actions. This function
+ *                       should contain any PU-specific actions required
+ *                       prior to sending suspend request to PMU. Actions
+ *                       taken depend on the state system is suspending to.
+ * @proc: processor which need to suspend.
+ * @state: desired suspend state.
+ *
  */
 void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
 	uint32_t cpu_id = plat_my_core_pos();
 	uintptr_t val;
 
-	bakery_lock_get(&pm_client_secure_lock);
+	pm_client_lock_get();
 
-	/* TODO: Set wakeup source */
+	if (state == PM_STATE_SUSPEND_TO_RAM) {
+		pm_client_set_wakeup_sources((uint32_t)proc->node_id);
+	}
 
 	val = read_cpu_pwrctrl_val();
 	val |= CORE_PWRDN_EN_BIT_MASK;
@@ -177,14 +334,15 @@
 	mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id),
 		      APU_PCIL_CORE_X_IEN_WAKE_MASK);
 
-	bakery_lock_release(&pm_client_secure_lock);
+	pm_client_lock_release();
 }
 
 /**
- * pm_get_cpuid() - get the local cpu ID for a global node ID
- * @param nid	node id of the processor
+ * pm_get_cpuid() - get the local cpu ID for a global node ID.
+ * @nid: node id of the processor.
  *
- * @return the cpu ID (starting from 0) for the subsystem
+ * Return: the cpu ID (starting from 0) for the subsystem.
+ *
  */
 static uint32_t pm_get_cpuid(uint32_t nid)
 {
@@ -197,12 +355,12 @@
 }
 
 /**
- * pm_client_wakeup() - Client-specific wakeup actions
+ * pm_client_wakeup() - Client-specific wakeup actions.
+ * @proc: Processor which need to wakeup.
  *
  * This function should contain any PU-specific actions
- * required for waking up another APU core
+ * required for waking up another APU core.
  *
- * @param proc	Processor which need to wakeup
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
@@ -213,7 +371,7 @@
 		return;
 	}
 
-	bakery_lock_get(&pm_client_secure_lock);
+	pm_client_lock_get();
 
 	/* Clear powerdown request */
 	val = read_cpu_pwrctrl_val();
@@ -232,14 +390,15 @@
 	mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid),
 		      APU_PCIL_CORE_X_IDS_WAKE_MASK);
 
-	bakery_lock_release(&pm_client_secure_lock);
+	pm_client_lock_release();
 }
 
 /**
- * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions.
  *
  * This function should contain any PU-specific actions
- * required for aborting a prior suspend request
+ * required for aborting a prior suspend request.
+ *
  */
 void pm_client_abort_suspend(void)
 {
@@ -249,7 +408,7 @@
 	/* Enable interrupts at processor level (for current cpu) */
 	gicv3_cpuif_enable(plat_my_core_pos());
 
-	bakery_lock_get(&pm_client_secure_lock);
+	pm_client_lock_get();
 
 	/* Clear powerdown request */
 	val = read_cpu_pwrctrl_val();
@@ -262,5 +421,5 @@
 	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id),
 			APU_PCIL_CORE_X_IDS_POWER_MASK);
 
-	bakery_lock_release(&pm_client_secure_lock);
+	pm_client_lock_release();
 }
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index c91497c..0c27dec 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,6 +43,9 @@
 
 /**
  * sip_svc_setup() - Setup SiP Service
+ *
+ * Return: 0 on success, negative error code on failure.
+ *
  */
 static int32_t sip_svc_setup(void)
 {
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
index 138d2c2..2fdef12 100644
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ b/plat/xilinx/versal_net/versal_net_gicv3.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -63,8 +63,8 @@
 }
 
 static const gicv3_driver_data_t versal_net_gic_data __unused = {
-	.gicd_base = PLAT_VERSAL_NET_GICD_BASE,
-	.gicr_base = PLAT_VERSAL_NET_GICR_BASE,
+	.gicd_base = PLAT_GICD_BASE_VALUE,
+	.gicr_base = PLAT_GICR_BASE_VALUE,
 	.interrupt_props = versal_net_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
diff --git a/plat/xilinx/versal_net/versal_net_ipi.c b/plat/xilinx/versal_net/versal_net_ipi.c
index 26ded89..0943c62 100644
--- a/plat/xilinx/versal_net/versal_net_ipi.c
+++ b/plat/xilinx/versal_net/versal_net_ipi.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,17 +9,9 @@
  * Versal NET IPI agent registers access management
  */
 
-#include <errno.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-
+#include <lib/utils_def.h>
 #include <ipi.h>
 #include <plat_ipi.h>
-#include <plat_private.h>
 
 /* versal_net ipi configuration table */
 static const struct ipi_config versal_net_ipi_table[IPI_ID_MAX] = {
@@ -73,10 +65,10 @@
 	},
 };
 
-/* versal_net_ipi_config_table_init() - Initialize versal_net IPI configuration data
- *
- * @ipi_config_table  - IPI configuration table
- * @ipi_total - Total number of IPI available
+/* versal_net_ipi_config_table_init() - Initialize versal_net IPI configuration
+ *                                      data.
+ * @ipi_config_table: IPI configuration table.
+ * @ipi_total: Total number of IPI available.
  *
  */
 void versal_net_ipi_config_table_init(void)
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 95a266e..a96c378 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,13 +13,14 @@
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
+
 #include <plat_ipi.h>
 #include <plat_private.h>
 #include <plat_startup.h>
-#include <plat/common/platform.h>
-#include <services/arm_arch_svc.h>
 
-#include "pm_api_sys.h"
+#include "zynqmp_pm_api_sys.h"
 
 /*
  * Table of regions to map using the MMU.
@@ -60,11 +61,11 @@
 
 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
 static const struct {
-	uint32_t id;
-	uint32_t ver;
-	char *name;
+	uint8_t id;
 	bool evexists;
-} zynqmp_devices[] = {
+	uint16_t ver;
+	char *name;
+} __packed zynqmp_devices[] = {
 	{
 		.id = 0x10,
 		.name = "XCZU3EG",
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
index d8439f7..65aab52 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 0ebd088..56d402f 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,20 +11,20 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/arm/dcc.h>
 #include <drivers/console.h>
+#include <lib/mmio.h>
+#include <libfdt.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <lib/mmio.h>
 
 #include <custom_svc.h>
-#include <plat_startup.h>
 #include <plat_private.h>
+#include <plat_startup.h>
 #include <zynqmp_def.h>
 
-#include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
-#include <libfdt.h>
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
@@ -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 */
@@ -94,10 +94,6 @@
 	/* Initialize the platform config for future decision making */
 	zynqmp_config_setup();
 
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
-
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
 	 * Base ZYNQMP only DRAM security is programmable (via TrustZone), but
@@ -111,24 +107,24 @@
 	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,
+		/* use parameters from XBL */
+		enum xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
 							  &bl33_image_ep_info,
-							  atf_handoff_addr);
-		if (ret != FSBL_HANDOFF_SUCCESS) {
+							  tfa_handoff_addr);
+		if (ret != XBL_HANDOFF_SUCCESS) {
 			panic();
 		}
 	}
 	if (bl32_image_ep_info.pc != 0) {
-		VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
+		NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
 	}
 	if (bl33_image_ep_info.pc != 0) {
-		VERBOSE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
+		NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
 	}
 
 	custom_early_setup();
@@ -136,21 +132,29 @@
 }
 
 #if ZYNQMP_WDT_RESTART
-static interrupt_type_handler_t type_el3_interrupt_table[MAX_INTR_EL3];
+static zynmp_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
 
 int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
 {
+	static uint32_t index;
+	uint32_t i;
+
 	/* Validate 'handler' and 'id' parameters */
-	if (!handler || id >= MAX_INTR_EL3) {
+	if (!handler || index >= MAX_INTR_EL3) {
 		return -EINVAL;
 	}
 
 	/* Check if a handler has already been registered */
-	if (type_el3_interrupt_table[id]) {
-		return -EALREADY;
+	for (i = 0; i < index; i++) {
+		if (id == type_el3_interrupt_table[i].id) {
+			return -EALREADY;
+		}
 	}
 
-	type_el3_interrupt_table[id] = handler;
+	type_el3_interrupt_table[index].id = id;
+	type_el3_interrupt_table[index].handler = handler;
+
+	index++;
 
 	return 0;
 }
@@ -159,12 +163,19 @@
 					  void *handle, void *cookie)
 {
 	uint32_t intr_id;
-	interrupt_type_handler_t handler;
+	uint32_t i;
+	interrupt_type_handler_t handler = NULL;
 
 	intr_id = plat_ic_get_pending_interrupt_id();
-	handler = type_el3_interrupt_table[intr_id];
+
+	for (i = 0; i < MAX_INTR_EL3; i++) {
+		if (intr_id == type_el3_interrupt_table[i].id) {
+			handler = type_el3_interrupt_table[i].handler;
+		}
+	}
+
 	if (handler != NULL) {
-		handler(intr_id, flags, handle, cookie);
+		return handler(intr_id, flags, handle, cookie);
 	}
 
 	return 0;
@@ -201,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");
 	}
 
@@ -239,6 +250,8 @@
 		panic();
 	}
 #endif
+
+	custom_runtime_setup();
 }
 
 /*
diff --git a/plat/xilinx/zynqmp/custom_sip_svc.c b/plat/xilinx/zynqmp/custom_sip_svc.c
index fbb0a33..b9664af 100644
--- a/plat/xilinx/zynqmp/custom_sip_svc.c
+++ b/plat/xilinx/zynqmp/custom_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,3 +23,7 @@
 void custom_mmap_add(void)
 {
 }
+
+void custom_runtime_setup(void)
+{
+}
diff --git a/plat/xilinx/zynqmp/include/custom_svc.h b/plat/xilinx/zynqmp/include/custom_svc.h
index ef0eb67..242f3eb 100644
--- a/plat/xilinx/zynqmp/include/custom_svc.h
+++ b/plat/xilinx/zynqmp/include/custom_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,5 +15,6 @@
 
 void custom_early_setup(void);
 void custom_mmap_add(void);
+void custom_runtime_setup(void);
 
 #endif /* CUSTOM_SVC_H */
diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h
index bf56d5e..4007b91 100644
--- a/plat/xilinx/zynqmp/include/plat_ipi.h
+++ b/plat/xilinx/zynqmp/include/plat_ipi.h
@@ -1,5 +1,7 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,10 +34,11 @@
  ********************************************************************/
 #define IPI_BUFFER_BASEADDR	0xFF990000U
 
-#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
-#define IPI_BUFFER_PMU_BASE	(IPI_BUFFER_BASEADDR + 0xE00U)
+#define IPI_LOCAL_ID		IPI_ID_APU
+#define IPI_REMOTE_ID		IPI_ID_PMU0
 
-#define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMU_BASE
+#define IPI_BUFFER_LOCAL_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
+#define IPI_BUFFER_REMOTE_BASE	(IPI_BUFFER_BASEADDR + 0xE00U)
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	0x80U
 #define IPI_BUFFER_TARGET_REMOTE_OFFSET	0x1C0U
diff --git a/plat/xilinx/zynqmp/include/plat_macros.S b/plat/xilinx/zynqmp/include/plat_macros.S
index bf1ff82..c4ab619 100644
--- a/plat/xilinx/zynqmp/include/plat_macros.S
+++ b/plat/xilinx/zynqmp/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h
index a57aebe..8731a20 100644
--- a/plat/xilinx/zynqmp/include/plat_pm_common.h
+++ b/plat/xilinx/zynqmp/include/plat_pm_common.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +15,7 @@
 
 #include <stdint.h>
 #include <common/debug.h>
-#include "pm_defs.h"
+#include "zynqmp_pm_defs.h"
 
 
 #define ZYNQMP_TZ_VERSION_MAJOR		1
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index 534777b..3526b94 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * 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
  */
@@ -21,8 +22,12 @@
 uint32_t zynqmp_get_uart_clk(void);
 uint32_t zynqmp_get_bootmode(void);
 
-
 #if ZYNQMP_WDT_RESTART
+typedef struct zynqmp_intr_info_type_el3 {
+	uint32_t id;
+	interrupt_type_handler_t handler;
+} zynmp_intr_info_type_el3_t;
+
 /*
  * Register handler to specific GIC entrance
  * for INTR_TYPE_EL3 type of interrupt
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index aebce30..0c83a56 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
  * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
@@ -21,10 +21,11 @@
  ******************************************************************************/
 
 /* Size of cacheable stacks */
+#ifndef PLATFORM_STACK_SIZE
 #define PLATFORM_STACK_SIZE 0x440
+#endif
 
 #define PLATFORM_CORE_COUNT		U(4)
-#define PLAT_NUM_POWER_DOMAINS		U(5)
 #define PLAT_MAX_PWR_LVL		U(1)
 #define PLAT_MAX_RET_STATE		U(1)
 #define PLAT_MAX_OFF_STATE		U(2)
@@ -43,13 +44,13 @@
 # define BL31_LIMIT			U(0x100000000)
 #else
 # define BL31_BASE			U(0x1000)
-# define BL31_LIMIT			U(0x7ffff)
+# 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 - 1)
+# 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 - 1)
+#  define BL31_PROGBITS_LIMIT		(UL(ZYNQMP_ATF_MEM_BASE) + U(ZYNQMP_ATF_MEM_PROGBITS_SIZE))
 # endif
 #endif
 
@@ -58,10 +59,10 @@
  ******************************************************************************/
 #ifndef ZYNQMP_BL32_MEM_BASE
 # define BL32_BASE			U(0x60000000)
-# define BL32_LIMIT			U(0x7fffffff)
+# define BL32_LIMIT			U(0x80000000)
 #else
-# define BL32_BASE			(ZYNQMP_BL32_MEM_BASE)
-# define BL32_LIMIT			(ZYNQMP_BL32_MEM_BASE + ZYNQMP_BL32_MEM_SIZE - 1)
+# define BL32_BASE			U(ZYNQMP_BL32_MEM_BASE)
+# define BL32_LIMIT			(UL(ZYNQMP_BL32_MEM_BASE) + U(ZYNQMP_BL32_MEM_SIZE))
 #endif
 
 /*******************************************************************************
@@ -70,14 +71,14 @@
 #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
 
 /*******************************************************************************
  * TSP  specific defines.
  ******************************************************************************/
 #define TSP_SEC_MEM_BASE		BL32_BASE
-#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1)
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
 
 /* ID of the secure physical generic timer interrupt used by the TSP */
 #define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 428bed5..c9f555a 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -135,7 +135,8 @@
 #define ARM_IRQ_SEC_SGI_6		14
 #define ARM_IRQ_SEC_SGI_7		15
 
-#define MAX_INTR_EL3			128
+/* number of interrupt handlers. increase as required */
+#define MAX_INTR_EL3			2
 
 /*******************************************************************************
  * UART related constants
diff --git a/plat/xilinx/zynqmp/libpm.mk b/plat/xilinx/zynqmp/libpm.mk
new file mode 100644
index 0000000..db3c742
--- /dev/null
+++ b/plat/xilinx/zynqmp/libpm.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LIBPM_SRCS	:=	$(addprefix plat/xilinx/common/pm_service/,	\
+			pm_ipi.c)
+
+LIBPM_SRCS      +=      $(addprefix plat/xilinx/zynqmp/pm_service/,  \
+                        zynqmp_pm_svc_main.c 				\
+			zynqmp_pm_api_sys.c				\
+			pm_api_pinctrl.c				\
+			pm_api_ioctl.c					\
+			pm_api_clock.c					\
+			pm_client.c)
+
+$(eval $(call MAKE_LIB,pm))
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index b7408b1..c6c6c4b 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +17,8 @@
 #include <plat/common/platform.h>
 
 #include <plat_private.h>
-#include "pm_api_sys.h"
 #include "pm_client.h"
+#include "zynqmp_pm_api_sys.h"
 
 static uintptr_t zynqmp_sec_entry;
 
diff --git a/plat/xilinx/zynqmp/plat_topology.c b/plat/xilinx/zynqmp/plat_topology.c
index 41add9f..2596650 100644
--- a/plat/xilinx/zynqmp/plat_topology.c
+++ b/plat/xilinx/zynqmp/plat_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index 25ebac6..e3a979e 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -1,12 +1,13 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_private.h>
 #include <plat/common/platform.h>
 
+#include <plat_private.h>
+
 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
 	if (mpidr & MPIDR_CLUSTER_MASK) {
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 4671f5f..36fa0f8 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
 # Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
 # Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
 # Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
@@ -116,6 +116,9 @@
 endif
 $(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
 
+# Build PM code as a Library
+include plat/xilinx/zynqmp/libpm.mk
+
 BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				lib/cpus/aarch64/aem_generic.S			\
 				lib/cpus/aarch64/cortex_a53.S			\
@@ -123,19 +126,12 @@
 				common/fdt_fixup.c				\
 				${LIBFDT_SRCS}					\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
-				plat/xilinx/common/pm_service/pm_ipi.c		\
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/zynqmp/bl31_zynqmp_setup.c		\
 				plat/xilinx/zynqmp/plat_psci.c			\
 				plat/xilinx/zynqmp/plat_zynqmp.c		\
 				plat/xilinx/zynqmp/plat_topology.c		\
-				plat/xilinx/zynqmp/sip_svc_setup.c		\
-				plat/xilinx/zynqmp/pm_service/pm_svc_main.c	\
-				plat/xilinx/zynqmp/pm_service/pm_api_sys.c	\
-				plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c	\
-				plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c	\
-				plat/xilinx/zynqmp/pm_service/pm_api_clock.c	\
-				plat/xilinx/zynqmp/pm_service/pm_client.c
+				plat/xilinx/zynqmp/sip_svc_setup.c
 
 ifeq (${SDEI_SUPPORT},1)
 BL31_SOURCES		+=	plat/xilinx/zynqmp/zynqmp_ehf.c			\
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index e61310a..2041541 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +17,10 @@
 #include <plat/common/platform.h>
 
 #include "pm_api_clock.h"
-#include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
+#include "zynqmp_pm_api_sys.h"
 
 #define CLK_NODE_MAX			(6U)
 
@@ -197,14 +198,15 @@
 	}
 
 /**
- * struct pm_clock_node - Clock topology node information
- * @type:	Topology type (mux/div1/div2/gate/pll/fixed factor)
- * @offset:	Offset in control register
- * @width:	Width of the specific type in control register
- * @clkflags:	Clk specific flags
- * @typeflags:	Type specific flags
- * @mult:	Multiplier for fixed factor
- * @div:	Divisor for fixed factor
+ * struct pm_clock_node - Clock topology node information.
+ * @type: Topology type (mux/div1/div2/gate/pll/fixed factor).
+ * @offset: Offset in control register.
+ * @width: Width of the specific type in control register.
+ * @clkflags: Clk specific flags.
+ * @typeflags: Type specific flags.
+ * @mult: Multiplier for fixed factor.
+ * @div: Divisor for fixed factor.
+ *
  */
 struct pm_clock_node {
 	uint16_t clkflags;
@@ -217,13 +219,15 @@
 };
 
 /**
- * struct pm_clock - Clock structure
- * @name:	Clock name
- * @control_reg:	Control register address
- * @status_reg:	Status register address
- * @parents:	Parents for first clock node. Lower byte indicates parent
- *		clock id and upper byte indicate flags for that id.
- * pm_clock_node:	Clock nodes
+ * struct pm_clock - Clock structure.
+ * @name: Clock name.
+ * @num_nodes: number of nodes.
+ * @control_reg: Control register address.
+ * @status_reg: Status register address.
+ * @parents: Parents for first clock node. Lower byte indicates parent
+ *           clock id and upper byte indicate flags for that id.
+ * @nodes: Clock nodes.
+ *
  */
 struct pm_clock {
 	char name[CLK_NAME_LEN];
@@ -235,8 +239,9 @@
 };
 
 /**
- * struct pm_clock - Clock structure
- * @name:		Clock name
+ * struct pm_ext_clock - Clock structure.
+ * @name: Clock name.
+ *
  */
 struct pm_ext_clock {
 	char name[CLK_NAME_LEN];
@@ -2385,8 +2390,8 @@
 };
 
 /**
- * pm_clock_valid - Check if clock is valid or not
- * @clock_id	Id of the clock to be queried
+ * pm_clock_valid - Check if clock is valid or not.
+ * @clock_id: Id of the clock to be queried.
  *
  * This function is used to check if given clock is valid
  * or not for the chip variant.
@@ -2395,6 +2400,7 @@
  * different variants.
  *
  * Return: Returns 1 if clock is valid else 0.
+ *
  */
 static bool pm_clock_valid(uint32_t clock_id)
 {
@@ -2408,12 +2414,13 @@
 }
 
 /**
- * pm_clock_type - Get clock's type
- * @clock_id	Id of the clock to be queried
+ * pm_clock_type - Get clock's type.
+ * @clock_id: Id of the clock to be queried.
  *
  * This function is used to check type of clock (OUTPUT/EXTERNAL).
  *
  * Return: Returns type of clock (OUTPUT/EXTERNAL).
+ *
  */
 static uint32_t pm_clock_type(uint32_t clock_id)
 {
@@ -2422,12 +2429,13 @@
 }
 
 /**
- * pm_api_clock_get_num_clocks() - PM call to request number of clocks
- * @nclocks	Number of clocks
+ * pm_api_clock_get_num_clocks() - PM call to request number of clocks.
+ * @nclocks: Number of clocks.
  *
  * This function is used by master to get number of clocks.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks)
 {
@@ -2437,12 +2445,13 @@
 }
 
 /**
- * pm_api_clock_get_name() - PM call to request a clock's name
- * @clock_id	Clock ID
- * @name	Name of clock (max 16 bytes)
+ * pm_api_clock_get_name() - PM call to request a clock's name.
+ * @clock_id: Clock ID.
+ * @name: Name of clock (max 16 bytes).
  *
  * This function is used by master to get nmae of clock specified
  * by given clock ID.
+ *
  */
 void pm_api_clock_get_name(uint32_t clock_id, char *name)
 {
@@ -2460,17 +2469,18 @@
 }
 
 /**
- * pm_api_clock_get_topology() - PM call to request a clock's topology
- * @clock_id	Clock ID
- * @index	Topology index for next toplogy node
- * @topology	Buffer to store nodes in topology and flags
+ * pm_api_clock_get_topology() - PM call to request a clock's topology.
+ * @clock_id: Clock ID.
+ * @index: Topology index for next toplogy node.
+ * @topology: Buffer to store nodes in topology and flags.
  *
  * This function is used by master to get topology information for the
  * clock specified by given clock ID. Each response would return 3
  * topology nodes. To get next nodes, caller needs to call this API with
  * index of next node. Index starts from 0.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
 					     uint32_t index,
@@ -2518,15 +2528,16 @@
 
 /**
  * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
- *					   factor parameters for fixed clock
- * @clock_id	Clock ID
- * @mul		Multiplication value
- * @div		Divisor value
+ *					   factor parameters for fixed clock.
+ * @clock_id: Clock ID.
+ * @mul: Multiplication value.
+ * @div: Divisor value.
  *
  * This function is used by master to get fixed factor parameers for the
  * fixed clock. This API is application only for the fixed clock.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
 						       uint32_t *mul,
@@ -2565,10 +2576,10 @@
 }
 
 /**
- * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
- * @clock_id	Clock ID
- * @index	Index of next parent
- * @parents	Parents of the given clock
+ * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents.
+ * @clock_id: Clock ID.
+ * @index: Index of next parent.
+ * @parents: Parents of the given clock.
  *
  * This function is used by master to get clock's parents information.
  * This API will return 3 parents with a single response. To get other
@@ -2579,7 +2590,8 @@
  * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
  * so on.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
 					    uint32_t index,
@@ -2621,14 +2633,15 @@
 }
 
 /**
- * pm_api_clock_get_attributes() - PM call to request a clock's attributes
- * @clock_id	Clock ID
- * @attr	Clock attributes
+ * pm_api_clock_get_attributes() - PM call to request a clock's attributes.
+ * @clock_id: Clock ID.
+ * @attr: Clock attributes.
  *
  * This function is used by master to get clock's attributes
  * (e.g. valid, clock type, etc).
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
 					       uint32_t *attr)
@@ -2647,14 +2660,15 @@
 }
 
 /**
- * pm_api_clock_get_max_divisor - PM call to get max divisor
- * @clock_id	Clock ID
- * @div_type	Divisor Type (TYPE_DIV1 or TYPE_DIV2)
- * @max_div	Maximum supported divisor
+ * pm_api_clock_get_max_divisor - PM call to get max divisor.
+ * @clock_id: Clock ID.
+ * @div_type: Divisor Type (TYPE_DIV1 or TYPE_DIV2).
+ * @max_div: Maximum supported divisor.
  *
  * This function is used by master to get maximum supported value.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
 						uint8_t div_type,
@@ -2684,15 +2698,16 @@
 }
 
 /**
- * struct pm_pll - PLL related data required to map IOCTL-based PLL control
- * implemented by linux to system-level EEMI APIs
- * @nid:	PLL node ID
- * @cid:	PLL clock ID
- * @pre_src:	Pre-source PLL clock ID
- * @post_src:	Post-source PLL clock ID
- * @div2:	DIV2 PLL clock ID
- * @bypass:	PLL output clock ID that maps to bypass select output
- * @mode:	PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE)
+ * struct pm_pll - PLL related data required to map IOCTL-based PLL control.
+ * implemented by linux to system-level EEMI APIs.
+ * @nid: PLL node ID.
+ * @cid: PLL clock ID.
+ * @pre_src: Pre-source PLL clock ID.
+ * @post_src: Post-source PLL clock ID.
+ * @div2: DIV2 PLL clock ID.
+ * @bypass: PLL output clock ID that maps to bypass select output.
+ * @mode: PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE).
+ *
  */
 struct pm_pll {
 	const enum pm_node_id nid;
@@ -2744,10 +2759,11 @@
 };
 
 /**
- * pm_clock_get_pll() - Get PLL structure by PLL clock ID
- * @clock_id	Clock ID of the target PLL
+ * pm_clock_get_pll() - Get PLL structure by PLL clock ID.
+ * @clock_id: Clock ID of the target PLL.
  *
- * @return	Pointer to PLL structure if found, NULL otherwise
+ * Return: Pointer to PLL structure if found, NULL otherwise.
+ *
  */
 struct pm_pll *pm_clock_get_pll(enum clock_id clock_id)
 {
@@ -2763,11 +2779,12 @@
 }
 
 /**
- * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID
- * @clock_id	Clock ID of the target PLL
- * @node_id	Location to store node ID of the target PLL
+ * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID.
+ * @clock_id: Clock ID of the target PLL.
+ * @node_id: Location to store node ID of the target PLL.
  *
- * @return	PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise
+ * Return: PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise.
+ *
  */
 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
 					    enum pm_node_id *node_id)
@@ -2783,10 +2800,12 @@
 }
 
 /**
- * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock ID
- * @clock_id	Clock ID
+ * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock
+ *                                     ID.
+ * @clock_id: Clock ID.
  *
- * @return	Pointer to PLL structure if found, NULL otherwise
+ * Return: Pointer to PLL structure if found, NULL otherwise.
+ *
  */
 struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id)
 {
@@ -2805,13 +2824,14 @@
 }
 
 /**
- * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL)
- * @pll: PLL to be locked
+ * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL).
+ * @pll: PLL to be locked.
  *
  * This function is used to map IOCTL/linux-based PLL handling to system-level
- * EEMI APIs
+ * EEMI APIs.
+ *
+ * Return: Error if the argument is not valid or status as returned by PMU.
  *
- * Return: Error if the argument is not valid or status as returned by PMU
  */
 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
 {
@@ -2828,13 +2848,14 @@
 }
 
 /**
- * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL)
- * @pll		PLL to be bypassed/reset
+ * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL).
+ * @pll: PLL to be bypassed/reset.
  *
  * This function is used to map IOCTL/linux-based PLL handling to system-level
- * EEMI APIs
+ * EEMI APIs.
  *
- * Return: Error if the argument is not valid or status as returned by PMU
+ * Return: Error if the argument is not valid or status as returned by PMU.
+ *
  */
 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
 {
@@ -2846,15 +2867,15 @@
 }
 
 /**
- * pm_clock_pll_get_state - Get state of the PLL
- * @pll		Pointer to the target PLL structure
- * @state	Location to store the state: 1/0 ("Enabled"/"Disabled")
+ * pm_clock_pll_get_state - Get state of the PLL.
+ * @pll: Pointer to the target PLL structure.
+ * @state: Location to store the state: 1/0 ("Enabled"/"Disabled").
  *
  * "Enable" actually means that the PLL is locked and its bypass is deasserted,
  * "Disable" means that it is bypassed.
  *
  * Return: PM_RET_ERROR_ARGS error if the argument is not valid, success if
- * returned state value is valid or an error if returned by PMU
+ *         returned state value is valid or an error if returned by PMU.
  */
 enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
 					  uint32_t *state)
@@ -2881,16 +2902,17 @@
 }
 
 /**
- * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id
- * @pll			Target PLL structure
- * @clock_id		Id of the clock
- * @parent_index	parent index (=mux select value)
+ * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id.
+ * @pll: Target PLL structure.
+ * @clock_id: Id of the clock.
+ * @parent_index: parent index (=mux select value).
  *
  * The whole clock-tree implementation relies on the fact that parent indexes
  * match to the multiplexer select values. This function has to rely on that
  * assumption as well => parent_index is actually the mux select value.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
 					   enum clock_id clock_id,
@@ -2916,14 +2938,15 @@
 }
 
 /**
- * pm_clock_pll_get_parent - Get mux select value of PLL-related clock parent
- * @pll			Target PLL structure
- * @clock_id		Id of the clock
- * @parent_index	parent index (=mux select value)
+ * pm_clock_pll_get_parent - Get mux select value of PLL-related clock parent.
+ * @pll: Target PLL structure.
+ * @clock_id: Id of the clock.
+ * @parent_index: parent index (=mux select value).
  *
  * This function is used by master to get parent index for PLL-related clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
 					   enum clock_id clock_id,
@@ -2953,13 +2976,14 @@
 }
 
 /**
- * pm_clock_set_pll_mode() -  Set PLL mode
- * @clock_id	PLL clock id
- * @mode	Mode fractional/integer
+ * pm_clock_set_pll_mode() -  Set PLL mode.
+ * @clock_id: PLL clock id.
+ * @mode: Mode fractional/integer.
  *
  * This function buffers/saves the PLL mode that is set.
  *
- * @return      Success if mode is buffered or error if an argument is invalid
+ * Return: Success if mode is buffered or error if an argument is invalid.
+ *
  */
 enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
 					 uint32_t mode)
@@ -2975,13 +2999,14 @@
 }
 
 /**
- * pm_clock_get_pll_mode() -  Get PLL mode
- * @clock_id	PLL clock id
- * @mode	Location to store the mode (fractional/integer)
+ * pm_clock_get_pll_mode() -  Get PLL mode.
+ * @clock_id: PLL clock id.
+ * @mode: Location to store the mode (fractional/integer).
  *
  * This function returns buffered PLL mode.
  *
- * @return      Success if mode is stored or error if an argument is invalid
+ * Return: Success if mode is stored or error if an argument is invalid.
+ *
  */
 enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
 					 uint32_t *mode)
@@ -2997,10 +3022,11 @@
 }
 
 /**
- * pm_clock_id_is_valid() -  Check if given clock ID is valid
- * @clock_id   ID of the clock to be checked
+ * pm_clock_id_is_valid() -  Check if given clock ID is valid.
+ * @clock_id: ID of the clock to be checked.
  *
- * @return     Returns success if clock_id is valid, otherwise an error
+ * Return: Returns success if clock_id is valid, otherwise an error.
+ *
  */
 enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
 {
@@ -3016,11 +3042,12 @@
 }
 
 /**
- * pm_clock_has_div() - Check if the clock has divider with given ID
- * @clock_id	Clock ID
- * @div_id	Divider ID
+ * pm_clock_has_div() - Check if the clock has divider with given ID.
+ * @clock_id: Clock ID.
+ * @div_id: Divider ID.
+ *
+ * Return: True(1)=clock has the divider, false(0)=otherwise.
  *
- * @return	True(1)=clock has the divider, false(0)=otherwise
  */
 uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
 {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index cc0dacc..3498f91 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index c0bfd51..e812ad6 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,22 +13,23 @@
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
-#include <zynqmp_def.h>
 
 #include "pm_api_clock.h"
 #include "pm_api_ioctl.h"
-#include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
+#include <zynqmp_def.h>
+#include "zynqmp_pm_api_sys.h"
 
 /**
- * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
- * @mode	Buffer to store value of oper mode(Split/Lock-step)
+ * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode.
+ * @mode: Buffer to store value of oper mode(Split/Lock-step)
  *
  * This function provides current configured RPU operational mode.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
 {
@@ -45,15 +47,16 @@
 }
 
 /**
- * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
- * @mode	Value to set for oper mode(Split/Lock-step)
+ * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode.
+ * @mode: Value to set for oper mode(Split/Lock-step).
  *
  * This function configures RPU operational mode(Split/Lock-step).
  * It also sets TCM combined mode in RPU lock-step and TCM non-combined
  * mode for RPU split mode. In case of Lock step mode, RPU1's output is
  * clamped.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
 {
@@ -83,13 +86,14 @@
 }
 
 /**
- * pm_ioctl_config_boot_addr() - Configure RPU boot address
- * @nid		Node ID of RPU
- * @value	Value to set for boot address (TCM/OCM)
+ * pm_ioctl_config_boot_addr() - Configure RPU boot address.
+ * @nid: Node ID of RPU.
+ * @value: Value to set for boot address (TCM/OCM).
  *
  * This function configures RPU boot address(memory).
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
 						    uint32_t value)
@@ -120,13 +124,14 @@
 }
 
 /**
- * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
- * @value	Value to set (Split/Combined)
+ * pm_ioctl_config_tcm_comb() - Configure TCM combined mode.
+ * @value: Value to set (Split/Combined).
  *
  * This function configures TCM to be in split mode or combined
  * mode.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
 {
@@ -148,13 +153,14 @@
 }
 
 /**
- * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass
- * @type	Type of tap delay to enable/disable (e.g. QSPI)
- * @value	Enable/Disable
+ * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass.
+ * @type: Type of tap delay to enable/disable (e.g. QSPI).
+ * @value: Enable/Disable.
  *
  * This function enable/disable tap delay bypass.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
 						       uint32_t value)
@@ -168,15 +174,16 @@
 }
 
 /**
- * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device
- * @nid		Node ID of the device
- * @value	Enable/Disable
+ * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device.
+ * @nid: Node ID of the device.
+ * @value: Enable/Disable.
  *
  * This function enable/disable SGMII mode for the GEM device.
  * While enabling SGMII mode, it also ties the GEM PCS Signal
  * Detect to 1 and selects EMIO for RX clock generation.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
 						  uint32_t value)
@@ -228,13 +235,14 @@
 }
 
 /**
- * pm_ioctl_sd_dll_reset() -  Reset DLL logic
- * @nid		Node ID of the device
- * @type	Reset type
+ * pm_ioctl_sd_dll_reset() -  Reset DLL logic.
+ * @nid: Node ID of the device.
+ * @type: Reset type.
  *
  * This function resets DLL logic for the SD device.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
 						uint32_t type)
@@ -277,14 +285,15 @@
 }
 
 /**
- * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device
- * @nid		Node ID of the device
- * @type	Type of tap delay to set (input/output)
- * @value	Value to set fot the tap delay
+ * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device.
+ * @nid: Node ID of the device.
+ * @type: Type of tap delay to set (input/output).
+ * @value: Value to set fot the tap delay.
  *
  * This function sets input/output tap delay for the SD device.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
 						   enum tap_delay_type type,
@@ -374,14 +383,14 @@
 }
 
 /**
- * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
- *				   setting pll mode
- * @pll     PLL clock id
- * @mode    Mode fraction/integar
+ * pm_ioctl_set_pll_frac_mode() -  Ioctl function for setting pll mode.
+ * @pll: PLL clock id.
+ * @mode: Mode fraction/integar.
  *
- * This function sets PLL mode
+ * This function sets PLL mode.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
 			(uint32_t pll, uint32_t mode)
@@ -390,14 +399,14 @@
 }
 
 /**
- * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
- *				   getting pll mode
- * @pll     PLL clock id
- * @mode    Mode fraction/integar
+ * pm_ioctl_get_pll_frac_mode() -  Ioctl function for getting pll mode.
+ * @pll: PLL clock id.
+ * @mode: Mode fraction/integar.
  *
- * This function return current PLL mode
+ * This function return current PLL mode.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
 			(uint32_t pll, uint32_t *mode)
@@ -406,15 +415,15 @@
 }
 
 /**
- * pm_ioctl_set_pll_frac_data() -  Ioctl function for
- *				   setting pll fraction data
- * @pll     PLL clock id
- * @data    fraction data
+ * pm_ioctl_set_pll_frac_data() -  Ioctl function for setting pll fraction data.
+ * @pll: PLL clock id.
+ * @data: fraction data.
  *
  * This function sets fraction data.
  * It is valid for fraction mode only.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_pll_frac_data
 			(uint32_t pll, uint32_t data)
@@ -432,14 +441,14 @@
 }
 
 /**
- * pm_ioctl_get_pll_frac_data() -  Ioctl function for
- *				   getting pll fraction data
- * @pll     PLL clock id
- * @data    fraction data
+ * pm_ioctl_get_pll_frac_data() -  Ioctl function for getting pll fraction data.
+ * @pll: PLL clock id.
+ * @data: fraction data.
  *
  * This function returns fraction data value.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_get_pll_frac_data
 			(uint32_t pll, uint32_t *data)
@@ -457,14 +466,15 @@
 }
 
 /**
- * pm_ioctl_write_ggs() - Ioctl function for writing
- *			  global general storage (ggs)
- * @index	GGS register index
- * @value	Register value to be written
+ * pm_ioctl_write_ggs() - Ioctl function for writing global general storage
+ *                        (ggs).
+ * @index: GGS register index.
+ * @value: Register value to be written.
  *
  * This function writes value to GGS register.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
 					     uint32_t value)
@@ -478,14 +488,15 @@
 }
 
 /**
- * pm_ioctl_read_ggs() - Ioctl function for reading
- *			 global general storage (ggs)
- * @index	GGS register index
- * @value	Register value
+ * pm_ioctl_read_ggs() - Ioctl function for reading global general storage
+ *                       (ggs).
+ * @index: GGS register index.
+ * @value: Register value.
  *
  * This function returns GGS register value.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
 					    uint32_t *value)
@@ -498,14 +509,15 @@
 }
 
 /**
- * pm_ioctl_write_pggs() - Ioctl function for writing persistent
- *			   global general storage (pggs)
- * @index	PGGS register index
- * @value	Register value to be written
+ * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general
+ *                         storage (pggs).
+ * @index: PGGS register index.
+ * @value: Register value to be written.
  *
  * This function writes value to PGGS register.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
 					      uint32_t value)
@@ -519,13 +531,12 @@
 }
 
 /**
- * pm_ioctl_afi() - Ioctl function for writing afi values
+ * pm_ioctl_afi() - Ioctl function for writing afi values.
+ * @index: AFI register index.
+ * @value: Register value to be written.
  *
- * @index 	AFI register index
- * @value	Register value to be written
+ * Return: Returns status, either success or error+reason.
  *
- *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_afi(uint32_t index,
 					      uint32_t value)
@@ -563,14 +574,15 @@
 }
 
 /**
- * pm_ioctl_read_pggs() - Ioctl function for reading persistent
- *			  global general storage (pggs)
- * @index	PGGS register index
- * @value	Register value
+ * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general
+ *                        storage (pggs).
+ * @index: PGGS register index.
+ * @value: Register value.
  *
  * This function returns PGGS register value.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
 					     uint32_t *value)
@@ -583,12 +595,12 @@
 }
 
 /**
- * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
+ * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset.
+ *
+ * Return: Returns status, either success or error+reason.
  *
  * This function peerforms the ULPI reset sequence for resetting
  * the ULPI transceiver.
- *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_ulpi_reset(void)
 {
@@ -619,12 +631,14 @@
 }
 
 /**
- * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
+ * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status.
+ * @value: Value to write.
  *
  * This function sets healthy bit value to indicate boot health status
  * to firmware.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
 {
@@ -633,16 +647,17 @@
 }
 
 /**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs
- * @node_id	Node ID of the device
- * @ioctl_id	ID of the requested IOCTL
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @value	Returned output value
+ * pm_api_ioctl() -  PM IOCTL API for device control and configs.
+ * @nid: Node ID of the device.
+ * @ioctl_id: ID of the requested IOCTL.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @value: Returned output value.
  *
  * This function calls IOCTL to firmware for device control and configuration.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
 				uint32_t ioctl_id,
@@ -723,10 +738,13 @@
 }
 
 /**
- * pm_update_ioctl_bitmask() -  API to get supported IOCTL ID mask
- * @bit_mask		Returned bit mask of supported IOCTL IDs
+ * tfa_ioctl_bitmask() -  API to get supported IOCTL ID mask.
+ * @bit_mask: Returned bit mask of supported IOCTL IDs.
+ *
+ * Return: 0 success, negative value for errors.
+ *
  */
-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 3b0d6ee..6b094db 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,44 +14,6 @@
 
 #include "pm_common.h"
 
-//ioctl id
-enum {
-	IOCTL_GET_RPU_OPER_MODE = 0,
-	IOCTL_SET_RPU_OPER_MODE = 1,
-	IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
-	IOCTL_TCM_COMB_CONFIG = 3,
-	IOCTL_SET_TAPDELAY_BYPASS = 4,
-	IOCTL_SET_SGMII_MODE = 5,
-	IOCTL_SD_DLL_RESET = 6,
-	IOCTL_SET_SD_TAPDELAY = 7,
-	 /* Ioctl for clock driver */
-	IOCTL_SET_PLL_FRAC_MODE = 8,
-	IOCTL_GET_PLL_FRAC_MODE = 9,
-	IOCTL_SET_PLL_FRAC_DATA = 10,
-	IOCTL_GET_PLL_FRAC_DATA = 11,
-	IOCTL_WRITE_GGS = 12,
-	IOCTL_READ_GGS = 13,
-	IOCTL_WRITE_PGGS = 14,
-	IOCTL_READ_PGGS = 15,
-	/* IOCTL for ULPI reset */
-	IOCTL_ULPI_RESET = 16,
-	/* Set healthy bit value */
-	IOCTL_SET_BOOT_HEALTH_STATUS = 17,
-	IOCTL_AFI = 18,
-	/* Probe counter read/write */
-	IOCTL_PROBE_COUNTER_READ = 19,
-	IOCTL_PROBE_COUNTER_WRITE = 20,
-	IOCTL_OSPI_MUX_SELECT = 21,
-	/* IOCTL for USB power request */
-	IOCTL_USB_SET_STATE = 22,
-	/* IOCTL to get last reset reason */
-	IOCTL_GET_LAST_RESET_REASON = 23,
-	/* AI engine NPI ISR clear */
-	IOCTL_AIE_ISR_CLEAR = 24,
-	/* Register SGI to ATF */
-	IOCTL_REGISTER_SGI = 25,
-};
-
 //RPU operation mode
 #define	PM_RPU_MODE_LOCKSTEP 0U
 #define	PM_RPU_MODE_SPLIT 1U
@@ -92,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/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 8f37341..2d8c23b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,10 +15,10 @@
 #include <plat/common/platform.h>
 
 #include "pm_api_pinctrl.h"
-#include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
+#include "zynqmp_pm_api_sys.h"
 
 struct pinctrl_function {
 	char name[FUNCTION_NAME_LEN];
@@ -1945,12 +1946,13 @@
 };
 
 /**
- * pm_api_pinctrl_get_num_pins() - PM call to request number of pins
- * @npins	Number of pins
+ * pm_api_pinctrl_get_num_pins() - PM call to request number of pins.
+ * @npins: Number of pins.
  *
- * This function is used by master to get number of pins
+ * This function is used by master to get number of pins.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_num_pins(uint32_t *npins)
 {
@@ -1960,12 +1962,13 @@
 }
 
 /**
- * pm_api_pinctrl_get_num_functions() - PM call to request number of functions
- * @nfuncs	Number of functions
+ * pm_api_pinctrl_get_num_functions() - PM call to request number of functions.
+ * @nfuncs: Number of functions.
  *
- * This function is used by master to get number of functions
+ * This function is used by master to get number of functions.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_num_functions(uint32_t *nfuncs)
 {
@@ -1976,13 +1979,14 @@
 
 /**
  * pm_api_pinctrl_get_num_func_groups() - PM call to request number of
- *					  function groups
- * @fid		Function Id
- * @ngroups	Number of function groups
+ *					  function groups.
+ * @fid: Function Id.
+ * @ngroups: Number of function groups.
+ *
+ * This function is used by master to get number of function groups.
  *
- * This function is used by master to get number of function groups
+ * Return: Returns success.
  *
- * @return	Returns success.
  */
 enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
 						      uint32_t *ngroups)
@@ -1997,12 +2001,13 @@
 }
 
 /**
- * pm_api_pinctrl_get_function_name() - PM call to request a function name
- * @fid		Function ID
- * @name	Name of function (max 16 bytes)
+ * pm_api_pinctrl_get_function_name() - PM call to request a function name.
+ * @fid: Function ID.
+ * @name: Name of function (max 16 bytes).
  *
  * This function is used by master to get name of function specified
  * by given function ID.
+ *
  */
 void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
 {
@@ -2015,10 +2020,10 @@
 
 /**
  * pm_api_pinctrl_get_function_groups() - PM call to request first 6 function
- *					  groups of function Id
- * @fid		Function ID
- * @index	Index of next function groups
- * @groups	Function groups
+ *					  groups of function Id.
+ * @fid: Function ID.
+ * @index: Index of next function groups.
+ * @groups: Function groups.
  *
  * This function is used by master to get function groups specified
  * by given function Id. This API will return 6 function groups with
@@ -2030,6 +2035,7 @@
  * function groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
 						      uint32_t index,
@@ -2060,10 +2066,10 @@
 
 /**
  * pm_api_pinctrl_get_pin_groups() - PM call to request first 6 pin
- *				     groups of pin
- * @pin		Pin
- * @index	Index of next pin groups
- * @groups	pin groups
+ *                                   groups of pin.
+ * @pin: Pin.
+ * @index: Index of next pin groups.
+ * @groups: pin groups.
  *
  * This function is used by master to get pin groups specified
  * by given pin Id. This API will return 6 pin groups with
@@ -2075,6 +2081,7 @@
  * pin groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
 						 uint32_t index,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index 5c4cb45..277af4b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 7217fa1..4afa01d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,10 +21,10 @@
 #include <lib/utils.h>
 
 #include <plat_ipi.h>
-#include <zynqmp_def.h>
-#include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
+#include <zynqmp_def.h>
+#include "zynqmp_pm_api_sys.h"
 
 #define IRQ_MAX		84U
 #define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
@@ -34,12 +35,10 @@
 
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
-extern const struct pm_ipi apu_ipi;
-
-const struct pm_ipi apu_ipi = {
-	.local_ipi_id = IPI_ID_APU,
-	.remote_ipi_id = IPI_ID_PMU0,
-	.buffer_base = IPI_BUFFER_APU_BASE,
+static const struct pm_ipi apu_ipi = {
+	.local_ipi_id = IPI_LOCAL_ID,
+	.remote_ipi_id = IPI_REMOTE_ID,
+	.buffer_base = IPI_BUFFER_LOCAL_BASE,
 };
 
 static uint32_t suspend_mode = PM_SUSPEND_MODE_STD;
@@ -158,10 +157,11 @@
 };
 
 /**
- * irq_to_pm_node - Get PM node ID corresponding to the interrupt number
- * @irq:	Interrupt number
+ * irq_to_pm_node - Get PM node ID corresponding to the interrupt number.
+ * @irq: Interrupt number.
  *
- * Return:	PM node ID corresponding to the specified interrupt
+ * Return: PM node ID corresponding to the specified interrupt.
+ *
  */
 static enum pm_node_id irq_to_pm_node(uint32_t irq)
 {
@@ -171,7 +171,8 @@
 
 /**
  * pm_client_set_wakeup_sources - Set all slaves with enabled interrupts as wake
- *				sources in the PMU firmware
+ *                                sources in the PMU firmware.
+ *
  */
 static void pm_client_set_wakeup_sources(void)
 {
@@ -228,10 +229,11 @@
 }
 
 /**
- * pm_get_proc() - returns pointer to the proc structure
- * @cpuid:	id of the cpu whose proc struct pointer should be returned
+ * pm_get_proc() - returns pointer to the proc structure.
+ * @cpuid: id of the cpu whose proc struct pointer should be returned.
  *
- * Return: pointer to a proc structure if proc is found, otherwise NULL
+ * Return: pointer to a proc structure if proc is found, otherwise NULL.
+ *
  */
 const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
@@ -243,10 +245,11 @@
 }
 
 /**
- * pm_get_proc_by_node() - returns pointer to the proc structure
- * @nid:	node id of the processor
+ * pm_get_proc_by_node() - returns pointer to the proc structure.
+ * @nid: node id of the processor.
  *
- * Return: pointer to a proc structure if proc is found, otherwise NULL
+ * Return: pointer to a proc structure if proc is found, otherwise NULL.
+ *
  */
 const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
 {
@@ -259,10 +262,11 @@
 }
 
 /**
- * pm_get_cpuid() - get the local cpu ID for a global node ID
- * @nid:	node id of the processor
+ * pm_get_cpuid() - get the local cpu ID for a global node ID.
+ * @nid: node id of the processor.
  *
- * Return: the cpu ID (starting from 0) for the subsystem
+ * Return: the cpu ID (starting from 0) for the subsystem.
+ *
  */
 static uint32_t pm_get_cpuid(enum pm_node_id nid)
 {
@@ -277,11 +281,14 @@
 const struct pm_proc *primary_proc = &pm_procs_all[0];
 
 /**
- * pm_client_suspend() - Client-specific suspend actions
+ * pm_client_suspend() - Client-specific suspend actions.
+ * @proc: processor which need to suspend.
+ * @state: desired suspend state.
  *
  * This function should contain any PU-specific actions
  * required prior to sending suspend request to PMU
  * Actions taken depend on the state system is suspending to.
+ *
  */
 void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
@@ -299,10 +306,11 @@
 
 
 /**
- * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions.
  *
  * This function should contain any PU-specific actions
- * required for aborting a prior suspend request
+ * required for aborting a prior suspend request.
+ *
  */
 void pm_client_abort_suspend(void)
 {
@@ -319,10 +327,12 @@
 }
 
 /**
- * pm_client_wakeup() - Client-specific wakeup actions
+ * pm_client_wakeup() - Client-specific wakeup actions.
+ * @proc: Processor which need to wakeup.
  *
  * This function should contain any PU-specific actions
- * required for waking up another APU core
+ * required for waking up another APU core.
+ *
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
deleted file mode 100644
index f00ab4b..0000000
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* ZynqMP power management enums and defines */
-
-#ifndef PM_DEFS_H
-#define PM_DEFS_H
-
-/*********************************************************************
- * Macro definitions
- ********************************************************************/
-
-/*
- * Version number is a 32bit value, like:
- * (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
- */
-#define PM_VERSION_MAJOR	1U
-#define PM_VERSION_MINOR	1U
-
-#define PM_VERSION	((PM_VERSION_MAJOR << 16U) | PM_VERSION_MINOR)
-
-/**
- * PM API versions
- */
-/* Expected version of firmware APIs */
-#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)
-/* Updating the QUERY_DATA API versioning as the bitmask functionality
- * support is added in the v2.*/
-#define TFA_API_QUERY_DATA_VERSION	(2U)
-
-/* Capabilities for RAM */
-#define PM_CAP_ACCESS	0x1U
-#define PM_CAP_CONTEXT	0x2U
-
-#define MAX_LATENCY	(~0U)
-#define MAX_QOS		100U
-
-/* State arguments of the self suspend */
-#define PM_STATE_CPU_IDLE		0x0U
-#define PM_STATE_SUSPEND_TO_RAM		0xFU
-
-/* APU processor states */
-#define PM_PROC_STATE_FORCEDOFF		0U
-#define PM_PROC_STATE_ACTIVE		1U
-#define PM_PROC_STATE_SLEEP		2U
-#define PM_PROC_STATE_SUSPENDING	3U
-
-#define PM_GET_CALLBACK_DATA		0xa01
-#define PM_SET_SUSPEND_MODE		0xa02
-#define PM_GET_TRUSTZONE_VERSION	0xa03
-
-/*********************************************************************
- * Enum definitions
- ********************************************************************/
-
-enum pm_api_id {
-	/* Miscellaneous API functions: */
-	PM_GET_API_VERSION = 1, /* Do not change or move */
-	PM_SET_CONFIGURATION,
-	PM_GET_NODE_STATUS,
-	PM_GET_OP_CHARACTERISTIC,
-	PM_REGISTER_NOTIFIER,
-	/* API for suspending of PUs: */
-	PM_REQ_SUSPEND,
-	PM_SELF_SUSPEND,
-	PM_FORCE_POWERDOWN,
-	PM_ABORT_SUSPEND,
-	PM_REQ_WAKEUP,
-	PM_SET_WAKEUP_SOURCE,
-	PM_SYSTEM_SHUTDOWN,
-	/* API for managing PM slaves: */
-	PM_REQ_NODE,
-	PM_RELEASE_NODE,
-	PM_SET_REQUIREMENT,
-	PM_SET_MAX_LATENCY,
-	/* Direct control API functions: */
-	PM_RESET_ASSERT,
-	PM_RESET_GET_STATUS,
-	PM_MMIO_WRITE,
-	PM_MMIO_READ,
-	PM_INIT_FINALIZE,
-	PM_FPGA_LOAD,
-	PM_FPGA_GET_STATUS,
-	PM_GET_CHIPID,
-	PM_SECURE_RSA_AES,
-	PM_SECURE_SHA,
-	PM_SECURE_RSA,
-	PM_PINCTRL_REQUEST,
-	PM_PINCTRL_RELEASE,
-	PM_PINCTRL_GET_FUNCTION,
-	PM_PINCTRL_SET_FUNCTION,
-	PM_PINCTRL_CONFIG_PARAM_GET,
-	PM_PINCTRL_CONFIG_PARAM_SET,
-	PM_IOCTL,
-	/* API to query information from firmware */
-	PM_QUERY_DATA,
-	/* Clock control API functions */
-	PM_CLOCK_ENABLE,
-	PM_CLOCK_DISABLE,
-	PM_CLOCK_GETSTATE,
-	PM_CLOCK_SETDIVIDER,
-	PM_CLOCK_GETDIVIDER,
-	PM_CLOCK_SETRATE,
-	PM_CLOCK_GETRATE,
-	PM_CLOCK_SETPARENT,
-	PM_CLOCK_GETPARENT,
-	PM_SECURE_IMAGE,
-	/* FPGA PL Readback */
-	PM_FPGA_READ,
-	PM_SECURE_AES,
-	/* PLL control API functions */
-	PM_PLL_SET_PARAMETER,
-	PM_PLL_GET_PARAMETER,
-	PM_PLL_SET_MODE,
-	PM_PLL_GET_MODE,
-	/* PM Register Access API */
-	PM_REGISTER_ACCESS,
-	PM_EFUSE_ACCESS,
-	PM_FEATURE_CHECK = 63,
-	PM_FPGA_GET_VERSION = 72,
-	PM_FPGA_GET_FEATURE_LIST,
-	PM_API_MAX
-};
-
-enum pm_node_id {
-	NODE_UNKNOWN = 0,
-	NODE_APU,
-	NODE_APU_0,
-	NODE_APU_1,
-	NODE_APU_2,
-	NODE_APU_3,
-	NODE_RPU,
-	NODE_RPU_0,
-	NODE_RPU_1,
-	NODE_PLD,
-	NODE_FPD,
-	NODE_OCM_BANK_0,
-	NODE_OCM_BANK_1,
-	NODE_OCM_BANK_2,
-	NODE_OCM_BANK_3,
-	NODE_TCM_0_A,
-	NODE_TCM_0_B,
-	NODE_TCM_1_A,
-	NODE_TCM_1_B,
-	NODE_L2,
-	NODE_GPU_PP_0,
-	NODE_GPU_PP_1,
-	NODE_USB_0,
-	NODE_USB_1,
-	NODE_TTC_0,
-	NODE_TTC_1,
-	NODE_TTC_2,
-	NODE_TTC_3,
-	NODE_SATA,
-	NODE_ETH_0,
-	NODE_ETH_1,
-	NODE_ETH_2,
-	NODE_ETH_3,
-	NODE_UART_0,
-	NODE_UART_1,
-	NODE_SPI_0,
-	NODE_SPI_1,
-	NODE_I2C_0,
-	NODE_I2C_1,
-	NODE_SD_0,
-	NODE_SD_1,
-	NODE_DP,
-	NODE_GDMA,
-	NODE_ADMA,
-	NODE_NAND,
-	NODE_QSPI,
-	NODE_GPIO,
-	NODE_CAN_0,
-	NODE_CAN_1,
-	NODE_EXTERN,
-	NODE_APLL,
-	NODE_VPLL,
-	NODE_DPLL,
-	NODE_RPLL,
-	NODE_IOPLL,
-	NODE_DDR,
-	NODE_IPI_APU,
-	NODE_IPI_RPU_0,
-	NODE_GPU,
-	NODE_PCIE,
-	NODE_PCAP,
-	NODE_RTC,
-	NODE_LPD,
-	NODE_VCU,
-	NODE_IPI_RPU_1,
-	NODE_IPI_PL_0,
-	NODE_IPI_PL_1,
-	NODE_IPI_PL_2,
-	NODE_IPI_PL_3,
-	NODE_PL,
-	NODE_GEM_TSU,
-	NODE_SWDT_0,
-	NODE_SWDT_1,
-	NODE_CSU,
-	NODE_PJTAG,
-	NODE_TRACE,
-	NODE_TESTSCAN,
-	NODE_PMU,
-	NODE_MAX,
-};
-
-enum pm_request_ack {
-	REQ_ACK_NO = 1,
-	REQ_ACK_BLOCKING,
-	REQ_ACK_NON_BLOCKING,
-};
-
-enum pm_abort_reason {
-	ABORT_REASON_WKUP_EVENT = 100,
-	ABORT_REASON_PU_BUSY,
-	ABORT_REASON_NO_PWRDN,
-	ABORT_REASON_UNKNOWN,
-};
-
-enum pm_suspend_reason {
-	SUSPEND_REASON_PU_REQ = 201,
-	SUSPEND_REASON_ALERT,
-	SUSPEND_REASON_SYS_SHUTDOWN,
-};
-
-enum pm_ram_state {
-	PM_RAM_STATE_OFF = 1,
-	PM_RAM_STATE_RETENTION,
-	PM_RAM_STATE_ON,
-};
-
-enum pm_opchar_type {
-	PM_OPCHAR_TYPE_POWER = 1,
-	PM_OPCHAR_TYPE_TEMP,
-	PM_OPCHAR_TYPE_LATENCY,
-};
-
-/* TODO: move pm_ret_status from device specific location to common location */
-/**
- * @PM_RET_SUCCESS:		success
- * @PM_RET_ERROR_ARGS:		illegal arguments provided (deprecated)
- * @PM_RET_ERROR_NOTSUPPORTED:	feature not supported  (deprecated)
- * @PM_RET_ERROR_NOT_ENABLED:	feature is not enabled
- * @PM_RET_ERROR_INVALID_CRC:	invalid crc in IPI communication
- * @PM_RET_ERROR_INTERNAL:	internal error
- * @PM_RET_ERROR_CONFLICT:	conflict
- * @PM_RET_ERROR_ACCESS:	access rights violation
- * @PM_RET_ERROR_INVALID_NODE:	invalid node
- * @PM_RET_ERROR_DOUBLE_REQ:	duplicate request for same node
- * @PM_RET_ERROR_ABORT_SUSPEND:	suspend procedure has been aborted
- * @PM_RET_ERROR_TIMEOUT:	timeout in communication with PMU
- * @PM_RET_ERROR_NODE_USED:	node is already in use
- */
-enum pm_ret_status {
-	PM_RET_SUCCESS = (0U),
-	PM_RET_ERROR_ARGS = (1U),
-	PM_RET_ERROR_NOTSUPPORTED = (4U),
-	PM_RET_ERROR_NOT_ENABLED = (29U),
-	PM_RET_ERROR_INVALID_CRC = (301U),
-	PM_RET_ERROR_INTERNAL = (2000U),
-	PM_RET_ERROR_CONFLICT = (2001U),
-	PM_RET_ERROR_ACCESS = (2002U),
-	PM_RET_ERROR_INVALID_NODE = (2003U),
-	PM_RET_ERROR_DOUBLE_REQ = (2004U),
-	PM_RET_ERROR_ABORT_SUSPEND = (2005U),
-	PM_RET_ERROR_TIMEOUT = (2006U),
-	PM_RET_ERROR_NODE_USED = (2007U),
-	PM_RET_ERROR_NO_FEATURE = (2008U)
-};
-
-/**
- * @PM_INITIAL_BOOT:	boot is a fresh system startup
- * @PM_RESUME:		boot is a resume
- * @PM_BOOT_ERROR:	error, boot cause cannot be identified
- */
-enum pm_boot_status {
-	PM_INITIAL_BOOT,
-	PM_RESUME,
-	PM_BOOT_ERROR,
-};
-
-/**
- * @PMF_SHUTDOWN_TYPE_SHUTDOWN:		shutdown
- * @PMF_SHUTDOWN_TYPE_RESET:		reset/reboot
- * @PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY:	set the shutdown/reboot scope
- */
-enum pm_shutdown_type {
-	PMF_SHUTDOWN_TYPE_SHUTDOWN,
-	PMF_SHUTDOWN_TYPE_RESET,
-	PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY,
-};
-
-/**
- * @PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM:	shutdown/reboot APU subsystem only
- * @PMF_SHUTDOWN_SUBTYPE_PS_ONLY:	shutdown/reboot entire PS (but not PL)
- * @PMF_SHUTDOWN_SUBTYPE_SYSTEM:	shutdown/reboot entire system
- */
-enum pm_shutdown_subtype {
-	PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM,
-	PMF_SHUTDOWN_SUBTYPE_PS_ONLY,
-	PMF_SHUTDOWN_SUBTYPE_SYSTEM,
-};
-
-/**
- * @PM_PLL_PARAM_DIV2:		Enable for divide by 2 function inside the PLL
- * @PM_PLL_PARAM_FBDIV:		Feedback divisor integer portion for the PLL
- * @PM_PLL_PARAM_DATA:		Feedback divisor fractional portion for the PLL
- * @PM_PLL_PARAM_PRE_SRC:	Clock source for PLL input
- * @PM_PLL_PARAM_POST_SRC:	Clock source for PLL Bypass mode
- * @PM_PLL_PARAM_LOCK_DLY:	Lock circuit config settings for lock windowsize
- * @PM_PLL_PARAM_LOCK_CNT:	Lock circuit counter setting
- * @PM_PLL_PARAM_LFHF:		PLL loop filter high frequency capacitor control
- * @PM_PLL_PARAM_CP:		PLL charge pump control
- * @PM_PLL_PARAM_RES:		PLL loop filter resistor control
- */
-enum pm_pll_param {
-	PM_PLL_PARAM_DIV2,
-	PM_PLL_PARAM_FBDIV,
-	PM_PLL_PARAM_DATA,
-	PM_PLL_PARAM_PRE_SRC,
-	PM_PLL_PARAM_POST_SRC,
-	PM_PLL_PARAM_LOCK_DLY,
-	PM_PLL_PARAM_LOCK_CNT,
-	PM_PLL_PARAM_LFHF,
-	PM_PLL_PARAM_CP,
-	PM_PLL_PARAM_RES,
-	PM_PLL_PARAM_MAX,
-};
-
-/**
- * @PM_PLL_MODE_RESET:		PLL is in reset (not locked)
- * @PM_PLL_MODE_INTEGER:	PLL is locked in integer mode
- * @PM_PLL_MODE_FRACTIONAL:	PLL is locked in fractional mode
- */
-enum pm_pll_mode {
-	PM_PLL_MODE_RESET,
-	PM_PLL_MODE_INTEGER,
-	PM_PLL_MODE_FRACTIONAL,
-	PM_PLL_MODE_MAX,
-};
-
-/**
- * @PM_CLOCK_DIV0_ID:		Clock divider 0
- * @PM_CLOCK_DIV1_ID:		Clock divider 1
- */
-enum pm_clock_div_id {
-	PM_CLOCK_DIV0_ID,
-	PM_CLOCK_DIV1_ID,
-};
-
-#endif /* PM_DEFS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
deleted file mode 100644
index 3c3082f..0000000
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PM_SVC_MAIN_H
-#define PM_SVC_MAIN_H
-
-#include "pm_common.h"
-
-int32_t pm_setup(void);
-uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, const void *cookie, void *handle,
-			uint64_t flags);
-#endif /* PM_SVC_MAIN_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
similarity index 73%
rename from plat/xilinx/zynqmp/pm_service/pm_api_sys.c
rename to plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 58491a0..ece5954 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +16,10 @@
 #include "pm_api_clock.h"
 #include "pm_api_ioctl.h"
 #include "pm_api_pinctrl.h"
-#include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
+#include "zynqmp_pm_api_sys.h"
 
 #define PM_QUERY_FEATURE_BITMASK ( \
 	(1ULL << (uint64_t)PM_QID_CLOCK_GET_NAME) | \
@@ -37,18 +37,18 @@
 	(1ULL << (uint64_t)PM_QID_CLOCK_GET_MAX_DIVISOR))
 
 /**
- * struct eemi_api_dependency - Dependent EEMI APIs which are implemented
- * on both the ATF and firmware
+ * typedef eemi_api_dependency - Dependent EEMI APIs which are implemented
+ *                               on both the TF-A and firmware.
+ * @id: EEMI API id or IOCTL id to be checked.
+ * @api_id: Dependent EEMI API.
  *
- * @id:		EEMI API id or IOCTL id to be checked
- * @api_id:	Dependent EEMI API
  */
 typedef struct __attribute__((packed)) {
 	uint8_t id;
 	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,
@@ -244,9 +244,10 @@
 static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
 
 /**
- * pm_get_shutdown_scope() - Get the currently set shutdown scope
+ * pm_get_shutdown_scope() - Get the currently set shutdown scope.
  *
- * @return	Shutdown scope value
+ * Return: Shutdown scope value.
+ *
  */
 uint32_t pm_get_shutdown_scope(void)
 {
@@ -254,16 +255,17 @@
 }
 
 /**
- * pm_self_suspend() - PM call for processor to suspend itself
- * @nid		Node id of the processor or subsystem
- * @latency	Requested maximum wakeup latency (not supported)
- * @state	Requested state
- * @address	Resume address
+ * pm_self_suspend() - PM call for processor to suspend itself.
+ * @nid: Node id of the processor or subsystem.
+ * @latency: Requested maximum wakeup latency (not supported).
+ * @state: Requested state.
+ * @address: Resume address.
  *
  * This is a blocking call, it will return only once PMU has responded.
  * On a wakeup, resume address will be automatically set by PMU.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
 				   uint32_t latency,
@@ -287,13 +289,14 @@
 
 /**
  * pm_req_suspend() - PM call to request for another PU or subsystem to
- *		      be suspended gracefully.
- * @target	Node id of the targeted PU or subsystem
- * @ack		Flag to specify whether acknowledge is requested
- * @latency	Requested wakeup latency (not supported)
- * @state	Requested state (not supported)
+ *                    be suspended gracefully.
+ * @target: Node id of the targeted PU or subsystem.
+ * @ack: Flag to specify whether acknowledge is requested.
+ * @latency: Requested wakeup latency (not supported).
+ * @state: Requested state (not supported).
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_req_suspend(enum pm_node_id target,
 				  enum pm_request_ack ack,
@@ -312,19 +315,20 @@
 
 /**
  * pm_req_wakeup() - PM call for processor to wake up selected processor
- *		     or subsystem
- * @target	Node id of the processor or subsystem to wake up
- * @ack		Flag to specify whether acknowledge requested
- * @set_address	Resume address presence indicator
- *				1 resume address specified, 0 otherwise
- * @address	Resume address
+ *		     or subsystem.
+ * @target: Node id of the processor or subsystem to wake up.
+ * @ack: Flag to specify whether acknowledge requested.
+ * @set_address: Resume address presence indicator.
+ *               1 resume address specified, 0 otherwise.
+ * @address: Resume address.
  *
  * This API function is either used to power up another APU core for SMP
  * (by PSCI) or to power up an entirely different PU or subsystem, such
  * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
  * automatically set by PMU.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
 				 uint32_t set_address,
@@ -352,11 +356,12 @@
 
 /**
  * pm_force_powerdown() - PM call to request for another PU or subsystem to
- *			  be powered down forcefully
- * @target	Node id of the targeted PU or subsystem
- * @ack		Flag to specify whether acknowledge is requested
+ *                        be powered down forcefully.
+ * @target: Node id of the targeted PU or subsystem.
+ * @ack: Flag to specify whether acknowledge is requested.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
 				      enum pm_request_ack ack)
@@ -375,13 +380,14 @@
 
 /**
  * pm_abort_suspend() - PM call to announce that a prior suspend request
- *			is to be aborted.
- * @reason	Reason for the abort
+ *                      is to be aborted.
+ * @reason: Reason for the abort.
  *
  * Calling PU expects the PMU to abort the initiated suspend procedure.
  * This is a non-blocking call without any acknowledge.
  *
+ * Return: Returns status, either success or error+reason
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
 {
@@ -400,12 +406,14 @@
 }
 
 /**
- * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
- * @target	Node id of the targeted PU or subsystem
- * @wkup_node	Node id of the wakeup peripheral
- * @enable	Enable or disable the specified peripheral as wake source
+ * pm_set_wakeup_source() - PM call to specify the wakeup source while
+ *                          suspended.
+ * @target: Node id of the targeted PU or subsystem.
+ * @wkup_node: Node id of the wakeup peripheral.
+ * @enable: Enable or disable the specified peripheral as wake source.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
 					enum pm_node_id wkup_node,
@@ -419,11 +427,12 @@
 }
 
 /**
- * pm_system_shutdown() - PM call to request a system shutdown or restart
- * @type	Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
- * @subtype	Scope: 0=APU-subsystem, 1=PS, 2=system
+ * pm_system_shutdown() - PM call to request a system shutdown or restart.
+ * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
+ * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
 {
@@ -442,13 +451,14 @@
 /* APIs for managing PM slaves: */
 
 /**
- * pm_req_node() - PM call to request a node with specific capabilities
- * @nid		Node id of the slave
- * @capabilities Requested capabilities of the slave
- * @qos		Quality of service (not supported)
- * @ack		Flag to specify whether acknowledge is requested
+ * pm_req_node() - PM call to request a node with specific capabilities.
+ * @nid: Node id of the slave.
+ * @capabilities: Requested capabilities of the slave.
+ * @qos: Quality of service (not supported).
+ * @ack: Flag to specify whether acknowledge is requested.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_req_node(enum pm_node_id nid,
 			       uint32_t capabilities,
@@ -467,15 +477,16 @@
 }
 
 /**
- * pm_set_requirement() - PM call to set requirement for PM slaves
- * @nid		Node id of the slave
- * @capabilities Requested capabilities of the slave
- * @qos		Quality of service (not supported)
- * @ack		Flag to specify whether acknowledge is requested
+ * pm_set_requirement() - PM call to set requirement for PM slaves.
+ * @nid: Node id of the slave.
+ * @capabilities: Requested capabilities of the slave.
+ * @qos: Quality of service (not supported).
+ * @ack: Flag to specify whether acknowledge is requested.
  *
- * This API function is to be used for slaves a PU already has requested
+ * This API function is to be used for slaves a PU already has requested.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
 				      uint32_t capabilities,
@@ -497,10 +508,11 @@
 /* Miscellaneous API functions */
 
 /**
- * pm_get_api_version() - Get version number of PMU PM firmware
- * @version	Returns 32-bit version number of PMU Power Management Firmware
+ * pm_get_api_version() - Get version number of PMU PM firmware.
+ * @version: Returns 32-bit version number of PMU Power Management Firmware.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_get_api_version(uint32_t *version)
 {
@@ -512,14 +524,15 @@
 }
 
 /**
- * pm_get_node_status() - PM call to request a node's current status
- * @nid		Node id
- * @ret_buff	Buffer for the return values:
- *		[0] - Current power state of the node
- *		[1] - Current requirements for the node (slave nodes only)
- *		[2] - Current usage status for the node (slave nodes only)
+ * pm_get_node_status() - PM call to request a node's current status.
+ * @nid: Node id.
+ * @ret_buff: Buffer for the return values
+ *            [0] - Current power state of the node
+ *            [1] - Current requirements for the node (slave nodes only)
+ *            [2] - Current usage status for the node (slave nodes only)
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
 				      uint32_t *ret_buff)
@@ -531,15 +544,16 @@
 }
 
 /**
- * pm_mmio_write() - Perform write to protected mmio
- * @address	Address to write to
- * @mask	Mask to apply
- * @value	Value to write
+ * pm_mmio_write() - Perform write to protected mmio.
+ * @address: Address to write to.
+ * @mask: Mask to apply.
+ * @value: Value to write.
  *
  * This function provides access to PM-related control registers
  * that may not be directly accessible by a particular PU.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_mmio_write(uintptr_t address,
 				 uint32_t mask,
@@ -553,14 +567,15 @@
 }
 
 /**
- * pm_mmio_read() - Read value from protected mmio
- * @address	Address to write to
- * @value	Value to write
+ * pm_mmio_read() - Read value from protected mmio.
+ * @address: Address to write to.
+ * @value: Value to write.
  *
  * This function provides access to PM-related control registers
  * that may not be directly accessible by a particular PU.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
 {
@@ -572,18 +587,16 @@
 }
 
 /**
- * pm_fpga_load() - Load the bitstream into the PL.
+ * pm_fpga_load() - Load the bitstream into the PL. This function provides
+ *                  access to the xilfpga library to load the Bit-stream
+ *                  into PL.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @size: Number of 32bit words.
+ * @flags: Additional flags or settings for the fpga operation.
  *
- * This function provides access to the xilfpga library to load
- * the Bit-stream into PL.
- *
- * address_low: lower 32-bit Linear memory space address
- *
- * address_high: higher 32-bit Linear memory space address
- *
- * size:	Number of 32bit words
+ * Return: Returns status, either success or error+reason.
  *
- * @return      Returns status, either success or error+reason
  */
 enum pm_ret_status pm_fpga_load(uint32_t address_low,
 				uint32_t address_high,
@@ -599,12 +612,14 @@
 }
 
 /**
- * pm_fpga_get_status() - Read value from fpga status register
- * @value       Value to read
+ * pm_fpga_get_status() - Read value from fpga status register.
+ * @value: Value to read.
  *
  * This function provides access to the xilfpga library to get
- * the fpga status
- * @return      Returns status, either success or error+reason
+ * the fpga status.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_fpga_get_status(uint32_t *value)
 {
@@ -616,11 +631,11 @@
 }
 
 /**
- * pm_get_chipid() - Read silicon ID registers
- * @value       Buffer for return values. Must be large enough
- *		to hold 8 bytes.
+ * pm_get_chipid() - Read silicon ID registers.
+ * @value: Buffer for return values. Must be large enough to hold 8 bytes.
  *
- * @return      Returns silicon ID registers
+ * Return: Returns silicon ID registers.
+ *
  */
 enum pm_ret_status pm_get_chipid(uint32_t *value)
 {
@@ -633,17 +648,16 @@
 
 /**
  * pm_secure_rsaaes() - Load the secure images.
- *
- * This function provides access to the xilsecure library to load
- * the authenticated, encrypted, and authenicated/encrypted images.
- *
- * address_low: lower 32-bit Linear memory space address
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @size: Number of 32bit words.
+ * @flags: Additional flags or settings for the fpga operation.
  *
- * address_high: higher 32-bit Linear memory space address
+ * This function provides access to the xilsecure library to load the
+ * authenticated, encrypted, and authenticated/encrypted images.
  *
- * size:	Number of 32bit words
+ * Return: Returns status, either success or error+reason.
  *
- * @return      Returns status, either success or error+reason
  */
 enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
 				uint32_t address_high,
@@ -659,17 +673,16 @@
 }
 
 /**
- * pm_aes_engine() - Aes data blob encryption/decryption
+ * pm_aes_engine() - Aes data blob encryption/decryption.
+ * @address_low: lower 32-bit address of the AesParams structure.
+ * @address_high: higher 32-bit address of the AesParams structure.
+ * @value: Returned output value.
+ *
  * This function provides access to the xilsecure library to
  * encrypt/decrypt data blobs.
  *
- * address_low: lower 32-bit address of the AesParams structure
- *
- * address_high: higher 32-bit address of the AesParams structure
- *
- * value:        Returned output value
+ * Return: Returns status, either success or error+reason.
  *
- * @return       Returns status, either success or error+reason
  */
 enum pm_ret_status pm_aes_engine(uint32_t address_high,
 				 uint32_t address_low,
@@ -683,11 +696,13 @@
 }
 
 /**
- * pm_get_callbackdata() - Read from IPI response buffer
- * @data - array of PAYLOAD_ARG_CNT elements
+ * pm_get_callbackdata() - Read from IPI response buffer.
+ * @data: array of PAYLOAD_ARG_CNT elements.
+ * @count: Number of values to return.
  *
  * Read value from ipi buffer response buffer.
- * @return      Returns status, either success or error
+ * Return: Returns status, either success or error.
+ *
  */
 enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
 {
@@ -703,16 +718,17 @@
 }
 
 /**
- * pm_ioctl() -  PM IOCTL API for device control and configs
- * @node_id	Node ID of the device
- * @ioctl_id	ID of the requested IOCTL
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @out		Returned output value
+ * pm_ioctl() - PM IOCTL API for device control and configs.
+ * @nid: Node ID of the device.
+ * @ioctl_id: ID of the requested IOCTL.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @value: Returned output value.
  *
  * This function calls IOCTL to firmware for device control and configuration.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
 			    uint32_t ioctl_id,
@@ -724,12 +740,13 @@
 }
 
 /**
- * fw_api_version() - Returns API version implemented in firmware
- * @api_id	API ID to check
- * @version	Returned supported API version
- * @len		Number of words to be returned
+ * fw_api_version() - Returns API version implemented in firmware.
+ * @id: API ID to check.
+ * @version: Returned supported API version.
+ * @len: Number of words to be returned.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version,
 					 uint32_t len)
@@ -741,10 +758,11 @@
 }
 
 /**
- * check_api_dependency() -  API to check dependent EEMI API version
- * @id		EEMI API ID to check
+ * check_api_dependency() -  API to check dependent EEMI API version.
+ * @id: EEMI API ID to check.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status check_api_dependency(uint8_t id)
 {
@@ -764,8 +782,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 +793,15 @@
 }
 
 /**
- * feature_check_atf() - These are API's completely implemented in ATF
- * @api_id	API ID to check
- * @version	Returned supported API version
+ * feature_check_tfa() - These are API's completely implemented in TF-A.
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
+ * @bit_mask: Returned supported IOCTL id version.
  *
- * @return	Returns status, either success or error+reason
+ * 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 +813,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 +821,15 @@
 }
 
 /**
- * get_atf_version_for_partial_apis() - Return ATF version for partially
- * implemented APIs
- * @api_id	API ID to check
- * @version	Returned supported API version
+ * 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
+ * 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 +851,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,11 +863,12 @@
 
 /**
  * feature_check_partial() - These are API's partially implemented in
- * ATF and firmware both
- * @api_id	API ID to check
- * @version	Returned supported API version
+ *                           TF-A and firmware both.
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
+ *
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 static enum pm_ret_status feature_check_partial(uint32_t api_id,
 						uint32_t *version)
@@ -877,20 +899,21 @@
 		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;
 	}
 }
 
 /**
- * pm_feature_check() - Returns the supported API version if supported
- * @api_id	API ID to check
- * @version	Returned supported API version
- * @bit_mask	Returned supported IOCTL id version
- * @len		Number of bytes to be returned in bit_mask variable
+ * pm_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
+ * @bit_mask: Returned supported IOCTL id version.
+ * @len: Number of bytes to be returned in bit_mask variable.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
 				    uint32_t *bit_mask, uint8_t len)
@@ -898,13 +921,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 +936,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 +944,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 +952,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 */
@@ -940,14 +963,15 @@
 }
 
 /**
- * pm_clock_get_max_divisor - PM call to get max divisor
- * @clock_id	Clock ID
- * @div_type	Divisor ID (TYPE_DIV1 or TYPE_DIV2)
- * @max_div	Maximum supported divisor
+ * pm_clock_get_max_divisor - PM call to get max divisor.
+ * @clock_id: Clock ID.
+ * @div_type: Divisor ID (TYPE_DIV1 or TYPE_DIV2).
+ * @max_div: Maximum supported divisor.
  *
  * This function is used by master to get maximum supported value.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
 						   uint8_t div_type,
@@ -957,12 +981,13 @@
 }
 
 /**
- * pm_clock_get_num_clocks - PM call to request number of clocks
- * @nclockss: Number of clocks
+ * pm_clock_get_num_clocks - PM call to request number of clocks.
+ * @nclocks: Number of clocks.
  *
  * This function is used by master to get number of clocks.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
 {
@@ -970,12 +995,13 @@
 }
 
 /**
- * pm_clock_get_name() - PM call to request a clock's name
- * @clock_id	Clock ID
- * @name	Name of clock (max 16 bytes)
+ * pm_clock_get_name() - PM call to request a clock's name.
+ * @clock_id: Clock ID.
+ * @name: Name of clock (max 16 bytes).
  *
  * This function is used by master to get nmae of clock specified
  * by given clock ID.
+ *
  */
 static void pm_clock_get_name(uint32_t clock_id, char *name)
 {
@@ -983,17 +1009,18 @@
 }
 
 /**
- * pm_clock_get_topology() - PM call to request a clock's topology
- * @clock_id	Clock ID
- * @index	Topology index for next toplogy node
- * @topology	Buffer to store nodes in topology and flags
+ * pm_clock_get_topology() - PM call to request a clock's topology.
+ * @clock_id: Clock ID.
+ * @index: Topology index for next toplogy node.
+ * @topology: Buffer to store nodes in topology and flags.
  *
  * This function is used by master to get topology information for the
  * clock specified by given clock ID. Each response would return 3
  * topology nodes. To get next nodes, caller needs to call this API with
  * index of next node. Index starts from 0.
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
 						uint32_t index,
@@ -1004,15 +1031,16 @@
 
 /**
  * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
- *				 parameters for fixed clock
- * @clock_id	Clock ID
- * @mul		Multiplication value
- * @div		Divisor value
+ *                                     parameters for fixed clock.
+ * @clock_id: Clock ID.
+ * @mul: Multiplication value.
+ * @div: Divisor value.
  *
  * This function is used by master to get fixed factor parameers for the
  * fixed clock. This API is application only for the fixed clock.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
 							  uint32_t *mul,
@@ -1022,10 +1050,10 @@
 }
 
 /**
- * pm_clock_get_parents() - PM call to request a clock's first 3 parents
- * @clock_id	Clock ID
- * @index	Index of next parent
- * @parents	Parents of the given clock
+ * pm_clock_get_parents() - PM call to request a clock's first 3 parents.
+ * @clock_id: Clock ID.
+ * @index: Index of next parent.
+ * @parents: Parents of the given clock.
  *
  * This function is used by master to get clock's parents information.
  * This API will return 3 parents with a single response. To get other
@@ -1036,7 +1064,8 @@
  * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
  * so on.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
 					       uint32_t index,
@@ -1046,14 +1075,15 @@
 }
 
 /**
- * pm_clock_get_attributes() - PM call to request a clock's attributes
- * @clock_id	Clock ID
- * @attr	Clock attributes
+ * pm_clock_get_attributes() - PM call to request a clock's attributes.
+ * @clock_id: Clock ID.
+ * @attr: Clock attributes.
  *
  * This function is used by master to get clock's attributes
  * (e.g. valid, clock type, etc).
  *
+ * Return: Returns status, either success or error+reason.
+ *
- * @return	Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
 						  uint32_t *attr)
@@ -1062,12 +1092,13 @@
 }
 
 /**
- * pm_clock_gate() - Configure clock gate
- * @clock_id	Id of the clock to be configured
- * @enable	Flag 0=disable (gate the clock), !0=enable (activate the clock)
+ * pm_clock_gate() - Configure clock gate.
+ * @clock_id: Id of the clock to be configured.
+ * @enable: Flag 0=disable (gate the clock), !0=enable (activate the clock).
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
 					uint8_t enable)
@@ -1101,14 +1132,15 @@
 }
 
 /**
- * pm_clock_enable() - Enable the clock for given id
- * @clock_id: Id of the clock to be enabled
+ * pm_clock_enable() - Enable the clock for given id.
+ * @clock_id: Id of the clock to be enabled.
  *
  * This function is used by master to enable the clock
  * including peripherals and PLL clocks.
  *
- * @return:	Error if an argument is not valid or status as returned by the
- *		pm_clock_gate
+ * Return: Error if an argument is not valid or status as returned by the
+ *         pm_clock_gate.
+ *
  */
 enum pm_ret_status pm_clock_enable(uint32_t clock_id)
 {
@@ -1125,14 +1157,15 @@
 }
 
 /**
- * pm_clock_disable - Disable the clock for given id
- * @clock_id: Id of the clock to be disable
+ * pm_clock_disable - Disable the clock for given id.
+ * @clock_id: Id of the clock to be disable.
  *
  * This function is used by master to disable the clock
  * including peripherals and PLL clocks.
  *
+ * Return: Error if an argument is not valid or status as returned by the
+ *         pm_clock_gate
+ *
- * @return:	Error if an argument is not valid or status as returned by the
- *		pm_clock_gate
  */
 enum pm_ret_status pm_clock_disable(uint32_t clock_id)
 {
@@ -1149,14 +1182,15 @@
 }
 
 /**
- * pm_clock_getstate - Get the clock state for given id
- * @clock_id: Id of the clock to be queried
- * @state: 1/0 (Enabled/Disabled)
+ * pm_clock_getstate - Get the clock state for given id.
+ * @clock_id: Id of the clock to be queried.
+ * @state: 1/0 (Enabled/Disabled).
  *
  * This function is used by master to get the state of clock
  * including peripherals and PLL clocks.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
 				     uint32_t *state)
@@ -1182,14 +1216,15 @@
 }
 
 /**
- * pm_clock_setdivider - Set the clock divider for given id
- * @clock_id: Id of the clock
- * @divider: divider value
+ * pm_clock_setdivider - Set the clock divider for given id.
+ * @clock_id: Id of the clock.
+ * @divider: divider value.
  *
  * This function is used by master to set divider for any clock
  * to achieve desired rate.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
 				       uint32_t divider)
@@ -1230,14 +1265,15 @@
 }
 
 /**
- * pm_clock_getdivider - Get the clock divider for given id
- * @clock_id: Id of the clock
- * @divider: divider value
+ * pm_clock_getdivider - Get the clock divider for given id.
+ * @clock_id: Id of the clock.
+ * @divider: divider value.
  *
  * This function is used by master to get divider values
  * for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
 				       uint32_t *divider)
@@ -1285,13 +1321,14 @@
 }
 
 /**
- * pm_clock_setrate - Set the clock rate for given id
- * @clock_id: Id of the clock
- * @rate: rate value in hz
+ * pm_clock_setrate - Set the clock rate for given id.
+ * @clock_id: Id of the clock.
+ * @rate: rate value in hz.
  *
  * This function is used by master to set rate for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
 				    uint64_t rate)
@@ -1300,14 +1337,15 @@
 }
 
 /**
- * pm_clock_getrate - Get the clock rate for given id
- * @clock_id: Id of the clock
- * @rate: rate value in hz
+ * pm_clock_getrate - Get the clock rate for given id.
+ * @clock_id: Id of the clock.
+ * @rate: rate value in hz.
  *
  * This function is used by master to get rate
  * for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
 				    uint64_t *rate)
@@ -1316,13 +1354,14 @@
 }
 
 /**
- * pm_clock_setparent - Set the clock parent for given id
- * @clock_id: Id of the clock
- * @parent_index: Index of the parent clock into clock's parents array
+ * pm_clock_setparent - Set the clock parent for given id.
+ * @clock_id: Id of the clock.
+ * @parent_index: Index of the parent clock into clock's parents array.
  *
  * This function is used by master to set parent for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
 				      uint32_t parent_index)
@@ -1349,14 +1388,15 @@
 }
 
 /**
- * pm_clock_getparent - Get the clock parent for given id
- * @clock_id: Id of the clock
- * @parent_index: parent index
+ * pm_clock_getparent - Get the clock parent for given id.
+ * @clock_id: Id of the clock.
+ * @parent_index: parent index.
  *
  * This function is used by master to get parent index
  * for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
 				      uint32_t *parent_index)
@@ -1383,12 +1423,13 @@
 }
 
 /**
- * pm_pinctrl_get_num_pins - PM call to request number of pins
- * @npins: Number of pins
+ * pm_pinctrl_get_num_pins - PM call to request number of pins.
+ * @npins: Number of pins.
  *
- * This function is used by master to get number of pins
+ * This function is used by master to get number of pins.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
 {
@@ -1396,12 +1437,13 @@
 }
 
 /**
- * pm_pinctrl_get_num_functions - PM call to request number of functions
- * @nfuncs: Number of functions
+ * pm_pinctrl_get_num_functions - PM call to request number of functions.
+ * @nfuncs: Number of functions.
  *
- * This function is used by master to get number of functions
+ * This function is used by master to get number of functions.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
 {
@@ -1410,14 +1452,15 @@
 
 /**
  * pm_pinctrl_get_num_function_groups - PM call to request number of
- *					function groups
- * @fid: Id of function
- * @ngroups: Number of function groups
+ *                                      function groups.
+ * @fid: Id of function.
+ * @ngroups: Number of function groups.
  *
  * This function is used by master to get number of function groups specified
- * by given function Id
+ * by given function Id.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
 							     uint32_t *ngroups)
@@ -1426,12 +1469,13 @@
 }
 
 /**
- * pm_pinctrl_get_function_name - PM call to request function name
- * @fid: Id of function
- * @name: Name of function
+ * pm_pinctrl_get_function_name - PM call to request function name.
+ * @fid: Id of function.
+ * @name: Name of function.
  *
  * This function is used by master to get name of function specified
- * by given function Id
+ * by given function Id.
+ *
  */
 static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
 {
@@ -1439,10 +1483,10 @@
 }
 
 /**
- * pm_pinctrl_get_function_groups - PM call to request function groups
- * @fid: Id of function
- * @index: Index of next function groups
- * @groups: Function groups
+ * pm_pinctrl_get_function_groups - PM call to request function groups.
+ * @fid: Id of function.
+ * @index: Index of next function groups.
+ * @groups: Function groups.
  *
  * This function is used by master to get function groups specified
  * by given function Id. This API will return 6 function groups with
@@ -1454,6 +1498,7 @@
  * function groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
 							 uint32_t index,
@@ -1463,10 +1508,10 @@
 }
 
 /**
- * pm_pinctrl_get_pin_groups - PM call to request pin groups
- * @pin_id: Id of pin
- * @index: Index of next pin groups
- * @groups: pin groups
+ * pm_pinctrl_get_pin_groups - PM call to request pin groups.
+ * @pin_id: Id of pin.
+ * @index: Index of next pin groups.
+ * @groups: pin groups.
  *
  * This function is used by master to get pin groups specified
  * by given pin Id. This API will return 6 pin groups with
@@ -1478,6 +1523,7 @@
  * pin groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
 						    uint32_t index,
@@ -1487,16 +1533,17 @@
 }
 
 /**
- * pm_query_data() -  PM API for querying firmware data
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @arg3	Argument 3 to requested IOCTL call
- * @arg4	Argument 4 to requested IOCTL call
- * @data	Returned output data
+ * pm_query_data() - PM API for querying firmware data.
+ * @qid:  represents the query identifiers for PM.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @arg3: Argument 3 to requested IOCTL call.
+ * @data: Returned output data.
  *
  * This function returns requested data.
+ *
  */
-void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
+void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
 		   uint32_t arg3, uint32_t *data)
 {
 	switch (qid) {
@@ -1591,20 +1638,20 @@
 }
 
 /**
- * pm_fpga_read - Perform the fpga configuration readback
- *
- * @reg_numframes: Configuration register offset (or) Number of frames to read
- * @address_low: lower 32-bit Linear memory space address
- * @address_high: higher 32-bit Linear memory space address
- * @readback_type: Type of fpga readback operation
- *		   0 -- Configuration Register readback
- *		   1 -- Configuration Data readback
- * @value:	Value to read
+ * pm_fpga_read - Perform the fpga configuration readback.
+ * @reg_numframes: Configuration register offset (or) Number of frames to read.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @readback_type: Type of fpga readback operation.
+ *		   0 -- Configuration Register readback.
+ *		   1 -- Configuration Data readback.
+ * @value: Value to read.
  *
  * This function provides access to the xilfpga library to read
  * the PL configuration.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
 				uint32_t address_low,
@@ -1621,16 +1668,17 @@
 }
 
 /*
- * pm_pll_set_parameter() - Set the PLL parameter value
- * @nid		Node id of the target PLL
- * @param_id	ID of the PLL parameter
- * @value	Parameter value to be set
+ * pm_pll_set_parameter() - Set the PLL parameter value.
+ * @nid: Node id of the target PLL.
+ * @param_id: ID of the PLL parameter.
+ * @value: Parameter value to be set.
  *
  * Setting the parameter will have physical effect once the PLL mode is set to
  * integer or fractional.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
 					enum pm_pll_param param_id,
@@ -1654,13 +1702,14 @@
 }
 
 /**
- * pm_pll_get_parameter() - Get the PLL parameter value
- * @nid		Node id of the target PLL
- * @param_id	ID of the PLL parameter
- * @value	Location to store the parameter value
+ * pm_pll_get_parameter() - Get the PLL parameter value.
+ * @nid: Node id of the target PLL.
+ * @param_id: ID of the PLL parameter.
+ * @value: Location to store the parameter value.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
 					enum pm_pll_param param_id,
@@ -1684,17 +1733,18 @@
 }
 
 /**
- * pm_pll_set_mode() - Set the PLL mode
- * @nid		Node id of the target PLL
- * @mode	PLL mode to be set
+ * pm_pll_set_mode() - Set the PLL mode.
+ * @nid: Node id of the target PLL.
+ * @mode: PLL mode to be set.
  *
  * If reset mode is set the PM controller will first bypass the PLL and then
  * assert the reset. If integer or fractional mode is set the PM controller will
  * ensure that the complete PLL programming sequence is satisfied. After this
  * function returns success the PLL is locked and its bypass is deasserted.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
 {
@@ -1716,12 +1766,13 @@
 }
 
 /**
- * pm_pll_get_mode() - Get the PLL mode
- * @nid		Node id of the target PLL
- * @mode	Location to store the mode of the PLL
+ * pm_pll_get_mode() - Get the PLL mode.
+ * @nid: Node id of the target PLL.
+ * @mode: Location to store the mode of the PLL.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
 {
@@ -1738,21 +1789,17 @@
 }
 
 /**
- * pm_register_access() -  PM API for register read/write access data
- *
- * @register_access_id	Register_access_id which says register read/write
- *
- * @address		Address of the register to be accessed
- *
- * @mask		Mask value to be used while writing value
- *
- * @value		Value to be written to register
- *
- * @out			Returned output data
+ * pm_register_access() -  PM API for register read/write access data.
+ * @register_access_id: Register_access_id which says register read/write.
+ * @address: Address of the register to be accessed.
+ * @mask: Mask value to be used while writing value.
+ * @value: Value to be written to register.
+ * @out: Returned output data.
  *
  * This function returns requested data.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_register_access(uint32_t register_access_id,
 				      uint32_t address,
@@ -1785,17 +1832,14 @@
 }
 
 /**
- * pm_efuse_access() - To program or read efuse bits.
- *
- * This function provides access to the xilskey library to program/read
- * efuse bits.
+ * pm_efuse_access() - To program or read efuse bits. This function provides
+ *                     access to the xilskey library to program/read
+ *                     efuse bits.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @value: Returned output value.
  *
- * address_low: lower 32-bit Linear memory space address
- * address_high: higher 32-bit Linear memory space address
- *
- * value: Returned output value
- *
- * @return  Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
  *
  */
 enum pm_ret_status pm_efuse_access(uint32_t address_high,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
similarity index 94%
rename from plat/xilinx/zynqmp/pm_service/pm_api_sys.h
rename to plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
index 1341e7b..a2597bc 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
@@ -1,18 +1,19 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef PM_API_SYS_H
-#define PM_API_SYS_H
+#ifndef ZYNQMP_PM_API_SYS_H
+#define ZYNQMP_PM_API_SYS_H
 
 #include <stdint.h>
 
 #include "pm_defs.h"
+#include "zynqmp_pm_defs.h"
 
-enum pm_query_id {
+enum pm_query_ids {
 	PM_QID_INVALID,
 	PM_QID_CLOCK_GET_NAME,
 	PM_QID_CLOCK_GET_TOPOLOGY,
@@ -34,7 +35,7 @@
 	CONFIG_REG_READ,
 };
 
-/**
+/*
  * Assigning of argument values into array elements.
  */
 #define PM_PACK_PAYLOAD1(pl, arg0) {	\
@@ -150,7 +151,7 @@
 				      uint32_t parent_index);
 enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
 				      uint32_t *parent_index);
-void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
+void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
 		   uint32_t arg3, uint32_t *data);
 enum pm_ret_status pm_sha_hash(uint32_t address_high,
 				    uint32_t address_low,
@@ -192,4 +193,4 @@
 				    uint32_t *bit_mask, uint8_t len);
 enum pm_ret_status check_api_dependency(uint8_t id);
 
-#endif /* PM_API_SYS_H */
+#endif /* ZYNQMP_PM_API_SYS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
new file mode 100644
index 0000000..af75c5c
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* ZynqMP power management enums and defines */
+
+#ifndef ZYNQMP_PM_DEFS_H
+#define ZYNQMP_PM_DEFS_H
+
+/*********************************************************************
+ * Macro definitions
+ ********************************************************************/
+
+/*
+ * Version number is a 32bit value, like:
+ * (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
+ */
+#define PM_VERSION_MAJOR	1U
+#define PM_VERSION_MINOR	1U
+
+#define PM_VERSION	((PM_VERSION_MAJOR << 16U) | PM_VERSION_MINOR)
+
+/*
+ * PM API versions
+ */
+
+/* Expected version of firmware APIs */
+#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 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)
+
+/* Capabilities for RAM */
+#define PM_CAP_ACCESS	0x1U
+#define PM_CAP_CONTEXT	0x2U
+
+/* APU processor states */
+#define PM_PROC_STATE_FORCEDOFF		0U
+#define PM_PROC_STATE_ACTIVE		1U
+#define PM_PROC_STATE_SLEEP		2U
+#define PM_PROC_STATE_SUSPENDING	3U
+
+#define PM_SET_SUSPEND_MODE		0xa02
+
+/*********************************************************************
+ * Enum definitions
+ ********************************************************************/
+
+enum pm_node_id {
+	NODE_UNKNOWN = 0,
+	NODE_APU,
+	NODE_APU_0,
+	NODE_APU_1,
+	NODE_APU_2,
+	NODE_APU_3,
+	NODE_RPU,
+	NODE_RPU_0,
+	NODE_RPU_1,
+	NODE_PLD,
+	NODE_FPD,
+	NODE_OCM_BANK_0,
+	NODE_OCM_BANK_1,
+	NODE_OCM_BANK_2,
+	NODE_OCM_BANK_3,
+	NODE_TCM_0_A,
+	NODE_TCM_0_B,
+	NODE_TCM_1_A,
+	NODE_TCM_1_B,
+	NODE_L2,
+	NODE_GPU_PP_0,
+	NODE_GPU_PP_1,
+	NODE_USB_0,
+	NODE_USB_1,
+	NODE_TTC_0,
+	NODE_TTC_1,
+	NODE_TTC_2,
+	NODE_TTC_3,
+	NODE_SATA,
+	NODE_ETH_0,
+	NODE_ETH_1,
+	NODE_ETH_2,
+	NODE_ETH_3,
+	NODE_UART_0,
+	NODE_UART_1,
+	NODE_SPI_0,
+	NODE_SPI_1,
+	NODE_I2C_0,
+	NODE_I2C_1,
+	NODE_SD_0,
+	NODE_SD_1,
+	NODE_DP,
+	NODE_GDMA,
+	NODE_ADMA,
+	NODE_NAND,
+	NODE_QSPI,
+	NODE_GPIO,
+	NODE_CAN_0,
+	NODE_CAN_1,
+	NODE_EXTERN,
+	NODE_APLL,
+	NODE_VPLL,
+	NODE_DPLL,
+	NODE_RPLL,
+	NODE_IOPLL,
+	NODE_DDR,
+	NODE_IPI_APU,
+	NODE_IPI_RPU_0,
+	NODE_GPU,
+	NODE_PCIE,
+	NODE_PCAP,
+	NODE_RTC,
+	NODE_LPD,
+	NODE_VCU,
+	NODE_IPI_RPU_1,
+	NODE_IPI_PL_0,
+	NODE_IPI_PL_1,
+	NODE_IPI_PL_2,
+	NODE_IPI_PL_3,
+	NODE_PL,
+	NODE_GEM_TSU,
+	NODE_SWDT_0,
+	NODE_SWDT_1,
+	NODE_CSU,
+	NODE_PJTAG,
+	NODE_TRACE,
+	NODE_TESTSCAN,
+	NODE_PMU,
+	NODE_MAX,
+};
+
+enum pm_request_ack {
+	REQ_ACK_NO = 1,
+	REQ_ACK_BLOCKING,
+	REQ_ACK_NON_BLOCKING,
+};
+
+enum pm_suspend_reason {
+	SUSPEND_REASON_PU_REQ = 201,
+	SUSPEND_REASON_ALERT,
+	SUSPEND_REASON_SYS_SHUTDOWN,
+};
+
+enum pm_ram_state {
+	PM_RAM_STATE_OFF = 1,
+	PM_RAM_STATE_RETENTION,
+	PM_RAM_STATE_ON,
+};
+
+/**
+ * enum pm_boot_status - enum represents the boot status of the PM.
+ * @PM_INITIAL_BOOT: boot is a fresh system startup.
+ * @PM_RESUME: boot is a resume.
+ * @PM_BOOT_ERROR: error, boot cause cannot be identified.
+ *
+ */
+enum pm_boot_status {
+	PM_INITIAL_BOOT,
+	PM_RESUME,
+	PM_BOOT_ERROR,
+};
+
+/**
+ * enum pm_shutdown_type - enum represents the shutdown type of the PM.
+ * @PMF_SHUTDOWN_TYPE_SHUTDOWN: shutdown.
+ * @PMF_SHUTDOWN_TYPE_RESET: reset/reboot.
+ * @PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY: set the shutdown/reboot scope.
+ *
+ */
+enum pm_shutdown_type {
+	PMF_SHUTDOWN_TYPE_SHUTDOWN,
+	PMF_SHUTDOWN_TYPE_RESET,
+	PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY,
+};
+
+/**
+ * enum pm_shutdown_subtype - enum represents the shutdown subtype of the PM.
+ * @PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM: shutdown/reboot APU subsystem only.
+ * @PMF_SHUTDOWN_SUBTYPE_PS_ONLY: shutdown/reboot entire PS (but not PL).
+ * @PMF_SHUTDOWN_SUBTYPE_SYSTEM: shutdown/reboot entire system.
+ *
+ */
+enum pm_shutdown_subtype {
+	PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM,
+	PMF_SHUTDOWN_SUBTYPE_PS_ONLY,
+	PMF_SHUTDOWN_SUBTYPE_SYSTEM,
+};
+
+/**
+ * enum pm_pll_mode - enum represents the mode of the PLL.
+ * @PM_PLL_MODE_RESET: PLL is in reset (not locked).
+ * @PM_PLL_MODE_INTEGER: PLL is locked in integer mode.
+ * @PM_PLL_MODE_FRACTIONAL: PLL is locked in fractional mode.
+ * @PM_PLL_MODE_MAX: Represents the maximum mode value for the PLL.
+ */
+enum pm_pll_mode {
+	PM_PLL_MODE_RESET,
+	PM_PLL_MODE_INTEGER,
+	PM_PLL_MODE_FRACTIONAL,
+	PM_PLL_MODE_MAX,
+};
+
+/**
+ * enum pm_clock_div_id - enum represents the clock division identifiers in the
+ *                        PM.
+ * @PM_CLOCK_DIV0_ID: Clock divider 0.
+ * @PM_CLOCK_DIV1_ID: Clock divider 1.
+ */
+enum pm_clock_div_id {
+	PM_CLOCK_DIV0_ID,
+	PM_CLOCK_DIV1_ID,
+};
+
+#endif /* ZYNQMP_PM_DEFS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
similarity index 85%
rename from plat/xilinx/zynqmp/pm_service/pm_svc_main.c
rename to plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index b35859d..e297ecb 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,20 +12,18 @@
 
 #include <errno.h>
 
-#include <common/runtime_svc.h>
-#if ZYNQMP_WDT_RESTART
 #include <arch_helpers.h>
+#include <common/runtime_svc.h>
 #include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/spinlock.h>
 #include <plat/common/platform.h>
-#endif
 
 #include <plat_private.h>
-#include "pm_api_sys.h"
 #include "pm_client.h"
-#include "pm_defs.h"
 #include "pm_ipi.h"
+#include "zynqmp_pm_api_sys.h"
+#include "zynqmp_pm_defs.h"
 
 /* pm_up = !0 - UP, pm_up = 0 - DOWN */
 static int32_t pm_up, ipi_irq_flag;
@@ -36,22 +34,26 @@
 #endif
 
 /**
- * pm_context - Structure which contains data for power management
- * @api_version		version of PM API, must match with one on PMU side
- * @payload		payload array used to store received
- *			data from ipi buffer registers
+ * typedef pm_ctx_t - Structure which contains data for power management.
+ * @api_version: version of PM API, must match with one on PMU side.
+ * @payload: payload array used to store received.
+ *           data from ipi buffer registers.
+ *
  */
-static struct {
+typedef struct {
 	uint32_t api_version;
 	uint32_t payload[PAYLOAD_ARG_CNT];
-} pm_ctx;
+} pm_ctx_t;
+
+static pm_ctx_t pm_ctx;
 
 #if ZYNQMP_WDT_RESTART
 /**
- * trigger_wdt_restart() - Trigger warm restart event to APU cores
+ * trigger_wdt_restart() - Trigger warm restart event to APU cores.
  *
  * This function triggers SGI for all active APU CPUs. SGI handler then
  * power down CPU and call system reset.
+ *
  */
 static void trigger_wdt_restart(void)
 {
@@ -83,24 +85,27 @@
 }
 
 /**
- * ttc_fiq_handler() - TTC Handler for timer event
- * @id         number of the highest priority pending interrupt of the type
- *             that this handler was registered for
- * @flags      security state, bit[0]
- * @handler    pointer to 'cpu_context' structure of the current CPU for the
- *             security state specified in the 'flags' parameter
- * @cookie     unused
+ * ttc_fiq_handler() - TTC Handler for timer event.
+ * @id: number of the highest priority pending interrupt of the type
+ *      that this handler was registered for.
+ * @flags: security state, bit[0].
+ * @handle: pointer to 'cpu_context' structure of the current CPU for the
+ *           security state specified in the 'flags' parameter.
+ * @cookie: unused.
  *
- * Function registered as INTR_TYPE_EL3 interrupt handler
+ * Function registered as INTR_TYPE_EL3 interrupt handler.
  *
  * 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
- * at registered entrance in GIC and informs that PMU responsed or demands
+ * at registered entrance in GIC and informs that PMU responded or demands
  * action.
+ *
+ * Return: 0 on success.
+ *
  */
 static uint64_t ttc_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 				void *cookie)
@@ -121,19 +126,21 @@
 }
 
 /**
- * zynqmp_sgi7_irq() - Handler for SGI7 IRQ
- * @id         number of the highest priority pending interrupt of the type
- *             that this handler was registered for
- * @flags      security state, bit[0]
- * @handler    pointer to 'cpu_context' structure of the current CPU for the
- *             security state specified in the 'flags' parameter
- * @cookie     unused
+ * zynqmp_sgi7_irq() - Handler for SGI7 IRQ.
+ * @id: number of the highest priority pending interrupt of the type
+ *      that this handler was registered for.
+ * @flags: security state, bit[0].
+ * @handle: pointer to 'cpu_context' structure of the current CPU for the
+ *           security state specified in the 'flags' parameter.
+ * @cookie: unused.
  *
  * 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.
+ *
+ * Return: This function does not return a value and it enters into wfi.
  */
 static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags,
 						 void *handle, void *cookie)
@@ -168,7 +175,9 @@
 }
 
 /**
- * pm_wdt_restart_setup() - Setup warm restart interrupts
+ * pm_wdt_restart_setup() - Setup warm restart interrupts.
+ *
+ * Return: Returns status, 0 on success or error+reason.
  *
  * This function sets up handler for SGI7 and TTC interrupts
  * used for warm restart.
@@ -194,17 +203,18 @@
 #endif
 
 /**
- * pm_setup() - PM service setup
+ * pm_setup() - PM service setup.
  *
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
  * Initialization functions for ZynqMP power management for
  * communicaton with PMU.
  *
  * Called from sip_svc_setup initialization function with the
  * rt_svc_init signature.
+ *
  */
 int32_t pm_setup(void)
 {
@@ -249,19 +259,24 @@
 
 /**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - Arguments
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
- *
- * @return  - Unused
+ * @smc_fid: Function Identifier.
+ * @x1: Arguments.
+ * @x2: Arguments.
+ * @x3: Arguments.
+ * @x4: Arguments.
+ * @cookie: Unused.
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * Determines that smc_fid is valid and supported PM SMC Function ID from the
  * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * the unknown SMC Function ID.
  *
  * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * function with rt_svc_handle signature.
+ *
+ * Return: Unused.
+ *
  */
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.h
new file mode 100644
index 0000000..bef72b6
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ZYNQMP_PM_SVC_MAIN_H
+#define ZYNQMP_PM_SVC_MAIN_H
+
+#include "pm_common.h"
+
+int32_t pm_setup(void);
+uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+			uint64_t x4, const void *cookie, void *handle,
+			uint64_t flags);
+#endif /* ZYNQMP_PM_SVC_MAIN_H */
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index c55784e..6a8555e 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices Inc. All rights reserved.
+ * Copyright (c) 2013-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 +14,8 @@
 
 #include <custom_svc.h>
 #include "ipi_mailbox_svc.h"
-#include "pm_svc_main.h"
+#include "pm_defs.h"
+#include "zynqmp_pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
 #define ZYNQMP_SIP_SVC_CALL_COUNT	U(0x8200ff00)
@@ -39,9 +40,13 @@
 	0xb9, 0x25, 0x82, 0x2d, 0xe3, 0xa5);
 
 /**
- * sip_svc_setup() - Setup SiP Service
+ * sip_svc_setup() - Setup SiP Service.
  *
- * Invokes PM setup
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
+ *
+ * Invokes PM setup.
  */
 static int32_t sip_svc_setup(void)
 {
@@ -51,9 +56,19 @@
 
 /**
  * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ * @smc_fid: Function Identifier.
+ * @x1: SMC64 Arguments 1 from kernel.
+ * @x2: SMC64 Arguments 2 from kernel.
+ * @x3: SMC64 Arguments 3 from kernel(upper 32-bits).
+ * @x4: SMC64 Arguments 4 from kernel.
+ * @cookie: Unused
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * Handler for all SiP SMC calls. Handles standard SIP requests
  * and calls PM SMC handler if the call is for a PM-API function.
+ *
+ * Return: Unused.
  */
 static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 			      u_register_t x1,
diff --git a/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk b/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
index 318b01d..f91a04c 100644
--- a/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
+++ b/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 352ba82..ed3300b 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,9 +8,10 @@
 #include <common/debug.h>
 #include <drivers/console.h>
 #include <plat/arm/common/plat_arm.h>
-#include <plat_private.h>
 #include <platform_tsp.h>
 
+#include <plat_private.h>
+
 /*******************************************************************************
  * Initialize the UART
  ******************************************************************************/
@@ -43,7 +44,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the MMU
+ * moment this is only initializes the MMU
  ******************************************************************************/
 void tsp_plat_arch_setup(void)
 {
diff --git a/plat/xilinx/zynqmp/zynqmp_ehf.c b/plat/xilinx/zynqmp/zynqmp_ehf.c
index fbf1ed0..18c3749 100644
--- a/plat/xilinx/zynqmp/zynqmp_ehf.c
+++ b/plat/xilinx/zynqmp/zynqmp_ehf.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) Siemens AG, 2020-2021
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
-
 #include <bl31/ehf.h>
 
+#include <platform_def.h>
+
 /*
  * Enumeration of priority levels on ARM platforms.
  */
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index acd31df..439bd6f 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -1,5 +1,7 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,17 +10,9 @@
  * Zynq UltraScale+ MPSoC IPI agent registers access management
  */
 
-#include <errno.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-
+#include <lib/utils_def.h>
 #include <ipi.h>
 #include <plat_ipi.h>
-#include <plat_private.h>
 
 /* Zynqmp ipi configuration table */
 static const struct ipi_config zynqmp_ipi_table[] = {
@@ -91,7 +85,7 @@
 };
 
 /**
- * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data
+ * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data.
  *
  */
 void zynqmp_ipi_config_table_init(void)
diff --git a/plat/xilinx/zynqmp/zynqmp_sdei.c b/plat/xilinx/zynqmp/zynqmp_sdei.c
index 7e92b58..ce68e6a 100644
--- a/plat/xilinx/zynqmp/zynqmp_sdei.c
+++ b/plat/xilinx/zynqmp/zynqmp_sdei.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) Siemens AG, 2020-2021
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -9,14 +9,17 @@
 
 #include <bl31/ehf.h>
 #include <common/debug.h>
+#include <plat/common/platform.h>
 #include <services/sdei.h>
 
-#include <plat/common/platform.h>
 #include <platform_def.h>
 
 int arm_validate_ns_entrypoint(uintptr_t entrypoint)
 {
-	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
new file mode 100644
index 0000000..07cd572
--- /dev/null
+++ b/poetry.lock
@@ -0,0 +1,888 @@
+# 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"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
+    {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
+]
+
+[[package]]
+name = "anytree"
+version = "2.8.0"
+description = "Powerful and Lightweight Python Tree Data Structure.."
+optional = false
+python-versions = "*"
+files = [
+    {file = "anytree-2.8.0-py2.py3-none-any.whl", hash = "sha256:14c55ac77492b11532395049a03b773d14c7e30b22aa012e337b1e983de31521"},
+    {file = "anytree-2.8.0.tar.gz", hash = "sha256:3f0f93f355a91bc3e6245319bf4c1d50e3416cc7a35cc1133c1ff38306bbccab"},
+]
+
+[package.dependencies]
+six = ">=1.9.0"
+
+[package.extras]
+dev = ["check-manifest"]
+test = ["coverage"]
+
+[[package]]
+name = "babel"
+version = "2.12.1"
+description = "Internationalization utilities"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
+    {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+]
+
+[package.dependencies]
+pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
+
+[[package]]
+name = "build"
+version = "0.10.0"
+description = "A simple, correct Python build frontend"
+optional = false
+python-versions = ">= 3.7"
+files = [
+    {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"},
+    {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "os_name == \"nt\""}
+packaging = ">=19.0"
+pyproject_hooks = "*"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+
+[package.extras]
+docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"]
+test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"]
+typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"]
+virtualenv = ["virtualenv (>=20.0.35)"]
+
+[[package]]
+name = "certifi"
+version = "2022.12.7"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
+    {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.1.0"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+    {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
+    {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+]
+
+[[package]]
+name = "click"
+version = "8.1.3"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
+    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "docutils"
+version = "0.18.1"
+description = "Docutils -- Python Documentation Utilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+    {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
+    {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
+]
+
+[[package]]
+name = "idna"
+version = "3.4"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
+
+[[package]]
+name = "imagesize"
+version = "1.4.1"
+description = "Getting image size from png/jpeg/jpeg2000/gif file"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
+    {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
+]
+
+[[package]]
+name = "importlib-metadata"
+version = "6.6.0"
+description = "Read metadata from Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"},
+    {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"},
+]
+
+[package.dependencies]
+zipp = ">=0.5"
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+perf = ["ipython"]
+testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
+
+[[package]]
+name = "jinja2"
+version = "3.1.2"
+description = "A very fast and expressive template engine."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
+    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[[package]]
+name = "markdown-it-py"
+version = "2.2.0"
+description = "Python port of markdown-it. Markdown parsing, done right!"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"},
+    {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"},
+]
+
+[package.dependencies]
+mdurl = ">=0.1,<1.0"
+
+[package.extras]
+benchmarking = ["psutil", "pytest", "pytest-benchmark"]
+code-style = ["pre-commit (>=3.0,<4.0)"]
+compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
+linkify = ["linkify-it-py (>=1,<3)"]
+plugins = ["mdit-py-plugins"]
+profiling = ["gprof2dot"]
+rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
+testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.2"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
+    {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
+]
+
+[[package]]
+name = "mdit-py-plugins"
+version = "0.3.5"
+description = "Collection of plugins for markdown-it-py"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"},
+    {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"},
+]
+
+[package.dependencies]
+markdown-it-py = ">=1.0.0,<3.0.0"
+
+[package.extras]
+code-style = ["pre-commit"]
+rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"]
+testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
+
+[[package]]
+name = "mdurl"
+version = "0.1.2"
+description = "Markdown URL utilities"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
+    {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
+]
+
+[[package]]
+name = "myst-parser"
+version = "0.18.1"
+description = "An extended commonmark compliant parser, with bridges to docutils & sphinx."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"},
+    {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"},
+]
+
+[package.dependencies]
+docutils = ">=0.15,<0.20"
+jinja2 = "*"
+markdown-it-py = ">=1.0.0,<3.0.0"
+mdit-py-plugins = ">=0.3.1,<0.4.0"
+pyyaml = "*"
+sphinx = ">=4,<6"
+typing-extensions = "*"
+
+[package.extras]
+code-style = ["pre-commit (>=2.12,<3.0)"]
+linkify = ["linkify-it-py (>=1.0,<2.0)"]
+rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"]
+testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx (<5.2)", "sphinx-pytest"]
+
+[[package]]
+name = "packaging"
+version = "23.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+    {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
+]
+
+[[package]]
+name = "pip"
+version = "23.1.2"
+description = "The PyPA recommended tool for installing Python packages."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pip-23.1.2-py3-none-any.whl", hash = "sha256:3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18"},
+    {file = "pip-23.1.2.tar.gz", hash = "sha256:0e7c86f486935893c708287b30bd050a36ac827ec7fe5e43fe7cb198dd835fba"},
+]
+
+[[package]]
+name = "pip-tools"
+version = "6.13.0"
+description = "pip-tools keeps your pinned dependencies fresh."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pip-tools-6.13.0.tar.gz", hash = "sha256:61d46bd2eb8016ed4a924e196e6e5b0a268cd3babd79e593048720db23522bb1"},
+    {file = "pip_tools-6.13.0-py3-none-any.whl", hash = "sha256:50943f151d87e752abddec8158622c34ad7f292e193836e90e30d87da60b19d9"},
+]
+
+[package.dependencies]
+build = "*"
+click = ">=8"
+pip = ">=22.2"
+setuptools = "*"
+wheel = "*"
+
+[package.extras]
+coverage = ["pytest-cov"]
+testing = ["flit-core (>=2,<4)", "poetry-core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist"]
+
+[[package]]
+name = "prettytable"
+version = "3.7.0"
+description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "prettytable-3.7.0-py3-none-any.whl", hash = "sha256:f4aaf2ed6e6062a82fd2e6e5289bbbe705ec2788fe401a3a1f62a1cea55526d2"},
+    {file = "prettytable-3.7.0.tar.gz", hash = "sha256:ef8334ee40b7ec721651fc4d37ecc7bb2ef55fde5098d994438f0dfdaa385c0c"},
+]
+
+[package.dependencies]
+wcwidth = "*"
+
+[package.extras]
+tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"]
+
+[[package]]
+name = "pyelftools"
+version = "0.29"
+description = "Library for analyzing ELF files and DWARF debugging information"
+optional = false
+python-versions = "*"
+files = [
+    {file = "pyelftools-0.29-py2.py3-none-any.whl", hash = "sha256:519f38cf412f073b2d7393aa4682b0190fa901f7c3fa0bff2b82d537690c7fc1"},
+    {file = "pyelftools-0.29.tar.gz", hash = "sha256:ec761596aafa16e282a31de188737e5485552469ac63b60cfcccf22263fd24ff"},
+]
+
+[[package]]
+name = "pygments"
+version = "2.15.1"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
+    {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+]
+
+[package.extras]
+plugins = ["importlib-metadata"]
+
+[[package]]
+name = "pyproject-hooks"
+version = "1.0.0"
+description = "Wrappers to call pyproject.toml-based build backend hooks."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
+    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
+]
+
+[package.dependencies]
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+
+[[package]]
+name = "pytz"
+version = "2023.3"
+description = "World timezone definitions, modern and historical"
+optional = false
+python-versions = "*"
+files = [
+    {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
+    {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
+]
+
+[[package]]
+name = "pyyaml"
+version = "6.0"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
+    {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
+    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
+    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
+    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
+    {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
+    {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
+    {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
+    {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
+    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
+    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
+    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
+    {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
+    {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
+    {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
+    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
+    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
+    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
+    {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
+    {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
+    {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
+    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
+    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
+    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
+    {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
+    {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
+    {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
+    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
+    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
+    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
+    {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
+    {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
+    {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
+    {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
+    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
+    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
+    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
+    {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
+    {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
+    {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
+]
+
+[[package]]
+name = "requests"
+version = "2.30.0"
+description = "Python HTTP for Humans."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"},
+    {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<3"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "setuptools"
+version = "67.7.2"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"},
+    {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+optional = false
+python-versions = "*"
+files = [
+    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "sphinx"
+version = "5.3.0"
+description = "Python documentation generator"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"},
+    {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7,<0.8"
+babel = ">=2.9"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
+docutils = ">=0.14,<0.20"
+imagesize = ">=1.3"
+importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""}
+Jinja2 = ">=3.0"
+packaging = ">=21.0"
+Pygments = ">=2.12"
+requests = ">=2.5.0"
+snowballstemmer = ">=2.0"
+sphinxcontrib-applehelp = "*"
+sphinxcontrib-devhelp = "*"
+sphinxcontrib-htmlhelp = ">=2.0.0"
+sphinxcontrib-jsmath = "*"
+sphinxcontrib-qthelp = "*"
+sphinxcontrib-serializinghtml = ">=1.1.5"
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"]
+test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
+
+[[package]]
+name = "sphinx-rtd-theme"
+version = "1.2.0"
+description = "Read the Docs theme for Sphinx"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
+files = [
+    {file = "sphinx_rtd_theme-1.2.0-py2.py3-none-any.whl", hash = "sha256:f823f7e71890abe0ac6aaa6013361ea2696fc8d3e1fa798f463e82bdb77eeff2"},
+    {file = "sphinx_rtd_theme-1.2.0.tar.gz", hash = "sha256:a0d8bd1a2ed52e0b338cbe19c4b2eef3c5e7a048769753dac6a9f059c7b641b8"},
+]
+
+[package.dependencies]
+docutils = "<0.19"
+sphinx = ">=1.6,<7"
+sphinxcontrib-jquery = {version = ">=2.0.0,<3.0.0 || >3.0.0", markers = "python_version > \"3\""}
+
+[package.extras]
+dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"]
+
+[[package]]
+name = "sphinxcontrib-applehelp"
+version = "1.0.4"
+description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"},
+    {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-devhelp"
+version = "1.0.2"
+description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
+    {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-htmlhelp"
+version = "2.0.1"
+description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"},
+    {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["html5lib", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-jquery"
+version = "4.1"
+description = "Extension to include jQuery on newer Sphinx releases"
+optional = false
+python-versions = ">=2.7"
+files = [
+    {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
+    {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
+]
+
+[package.dependencies]
+Sphinx = ">=1.8"
+
+[[package]]
+name = "sphinxcontrib-jsmath"
+version = "1.0.1"
+description = "A sphinx extension which renders display math in HTML via JavaScript"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
+    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
+]
+
+[package.extras]
+test = ["flake8", "mypy", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-plantuml"
+version = "0.24.1"
+description = "Sphinx \"plantuml\" extension"
+optional = false
+python-versions = "*"
+files = [
+    {file = "sphinxcontrib-plantuml-0.24.1.tar.gz", hash = "sha256:39d2e4bc40d5e093126129a144f56b6ee15f58cfa5048b5948e63a11aff3b586"},
+]
+
+[package.dependencies]
+Sphinx = ">=1.6"
+
+[package.extras]
+test = ["Pillow", "flake8", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-qthelp"
+version = "1.0.3"
+description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
+    {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-serializinghtml"
+version = "1.1.5"
+description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
+    {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+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"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.5.0"
+description = "Backported and Experimental Type Hints for Python 3.7+"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"},
+    {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
+]
+
+[[package]]
+name = "urllib3"
+version = "2.0.2"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"},
+    {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
+socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
+zstd = ["zstandard (>=0.18.0)"]
+
+[[package]]
+name = "wcwidth"
+version = "0.2.6"
+description = "Measures the displayed width of unicode strings in a terminal"
+optional = false
+python-versions = "*"
+files = [
+    {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"},
+    {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"},
+]
+
+[[package]]
+name = "wheel"
+version = "0.40.0"
+description = "A built-package format for Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"},
+    {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"},
+]
+
+[package.extras]
+test = ["pytest (>=6.0.0)"]
+
+[[package]]
+name = "zipp"
+version = "3.15.0"
+description = "Backport of pathlib-compatible object wrapper for zip files"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
+    {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.8"
+content-hash = "62d9ce9ca1c9f4669c7b40724acfc93968cde31c0460d1d7515d289739dc9464"
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..19ba4d8
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,33 @@
+[tool.poetry]
+name = "trusted-firmware-a"
+version = "2.9.0"
+description = "Trusted Firmware-A (TF-A) Python dependencies."
+authors = ["Arm Ltd."]
+license = "BSD-3-Clause"
+readme = "readme.rst"
+packages = [
+	{ include = "memory", from = "tools/memory"}
+]
+
+[tool.poetry.scripts]
+memory = "memory.memmap:main"
+
+[tool.poetry.dependencies]
+python = "^3.8"
+
+[tool.poetry.group.doc.dependencies]
+sphinx = "^5.3.0"
+myst-parser = "^0.18.1"
+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"
+
+[tool.poetry.group.memory.dependencies]
+pyelftools = "^0.29"
+anytree = "^2.8.0"
+click = "^8.1.3"
+prettytable = "^3.5.0"
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 46ccd9e..bb042c7 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -6,7 +6,7 @@
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
-#include <lib/cpus/errata_report.h>
+#include <lib/cpus/errata.h>
 #include <lib/cpus/wa_cve_2017_5715.h>
 #include <lib/cpus/wa_cve_2018_3639.h>
 #include <lib/cpus/wa_cve_2022_23960.h>
diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk
index 477b45d..f394744 100644
--- a/services/spd/opteed/opteed.mk
+++ b/services/spd/opteed/opteed.mk
@@ -31,4 +31,5 @@
 	platform")
 $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
 $(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
+include lib/libfdt/libfdt.mk
 endif
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index ff09e7e..4d055db 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -24,9 +24,13 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <lib/coreboot.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/optee_utils.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#if OPTEE_ALLOW_SMC_LOAD
+#include <libfdt.h>
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 #include <plat/common/platform.h>
 #include <tools_share/uuid.h>
 
@@ -47,6 +51,14 @@
 
 #if OPTEE_ALLOW_SMC_LOAD
 static bool opteed_allow_load;
+/* OP-TEE image loading service UUID */
+DEFINE_SVC_UUID2(optee_image_load_uuid,
+	0xb1eafba3, 0x5d31, 0x4612, 0xb9, 0x06,
+	0xc4, 0xc7, 0xa4, 0xbe, 0x3c, 0xc0);
+
+#define OPTEED_FDT_SIZE 256
+static uint8_t fdt_buf[OPTEED_FDT_SIZE] __aligned(CACHE_WRITEBACK_GRANULE);
+
 #else
 static int32_t opteed_init(void);
 #endif
@@ -205,6 +217,91 @@
 #endif  /* !OPTEE_ALLOW_SMC_LOAD */
 
 #if OPTEE_ALLOW_SMC_LOAD
+#if COREBOOT
+/*
+ * Adds a firmware/coreboot node with the coreboot table information to a device
+ * tree. Returns zero on success or if there is no coreboot table information;
+ * failure code otherwise.
+ */
+static int add_coreboot_node(void *fdt)
+{
+	int ret;
+	uint64_t coreboot_table_addr;
+	uint32_t coreboot_table_size;
+	struct {
+		uint64_t addr;
+		uint32_t size;
+	} reg_node;
+	coreboot_get_table_location(&coreboot_table_addr, &coreboot_table_size);
+	if (!coreboot_table_addr || !coreboot_table_size) {
+		WARN("Unable to get coreboot table location for device tree");
+		return 0;
+	}
+	ret = fdt_begin_node(fdt, "firmware");
+	if (ret)
+		return ret;
+
+	ret = fdt_property(fdt, "ranges", NULL, 0);
+	if (ret)
+		return ret;
+
+	ret = fdt_begin_node(fdt, "coreboot");
+	if (ret)
+		return ret;
+
+	ret = fdt_property_string(fdt, "compatible", "coreboot");
+	if (ret)
+		return ret;
+
+	reg_node.addr = cpu_to_fdt64(coreboot_table_addr);
+	reg_node.size = cpu_to_fdt32(coreboot_table_size);
+	ret = fdt_property(fdt, "reg", &reg_node,
+				sizeof(uint64_t) + sizeof(uint32_t));
+	if (ret)
+		return ret;
+
+	ret = fdt_end_node(fdt);
+	if (ret)
+		return ret;
+
+	return fdt_end_node(fdt);
+}
+#endif /* COREBOOT */
+
+/*
+ * Creates a device tree for passing into OP-TEE. Currently is populated with
+ * the coreboot table address.
+ * Returns 0 on success, error code otherwise.
+ */
+static int create_opteed_dt(void)
+{
+	int ret;
+
+	ret = fdt_create(fdt_buf, OPTEED_FDT_SIZE);
+	if (ret)
+		return ret;
+
+	ret = fdt_finish_reservemap(fdt_buf);
+	if (ret)
+		return ret;
+
+	ret = fdt_begin_node(fdt_buf, "");
+	if (ret)
+		return ret;
+
+#if COREBOOT
+	ret = add_coreboot_node(fdt_buf);
+	if (ret)
+		return ret;
+#endif /* COREBOOT */
+
+	ret = fdt_end_node(fdt_buf);
+	if (ret)
+		return ret;
+
+	return fdt_finish(fdt_buf);
+}
+
 /*******************************************************************************
  * This function is responsible for handling the SMC that loads the OP-TEE
  * binary image via a non-secure SMC call. It takes the size and physical
@@ -228,6 +325,7 @@
 	uint64_t target_size;
 	entry_point_info_t optee_ep_info;
 	uint32_t linear_id = plat_my_core_pos();
+	uint64_t dt_addr = 0;
 
 	mapped_data_pa = page_align(data_pa, DOWN);
 	mapped_data_va = mapped_data_pa;
@@ -288,12 +386,20 @@
 	/* Save the non-secure state */
 	cm_el1_sysregs_context_save(NON_SECURE);
 
+	rc = create_opteed_dt();
+	if (rc) {
+		ERROR("Failed device tree creation %d\n", rc);
+		return rc;
+	}
+	dt_addr = (uint64_t)fdt_buf;
+	flush_dcache_range(dt_addr, OPTEED_FDT_SIZE);
+
 	opteed_init_optee_ep_state(&optee_ep_info,
 				   opteed_rw,
 				   image_pa,
 				   0,
 				   0,
-				   0,
+				   dt_addr,
 				   &opteed_sp_context[linear_id]);
 	if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
 		rc = -EFAULT;
@@ -335,6 +441,10 @@
 
 	if (is_caller_non_secure(flags)) {
 #if OPTEE_ALLOW_SMC_LOAD
+		if (opteed_allow_load && smc_fid == NSSMC_OPTEED_CALL_UID) {
+			/* Provide the UUID of the image loading service. */
+			SMC_UUID_RET(handle, optee_image_load_uuid);
+		}
 		if (smc_fid == NSSMC_OPTEED_CALL_LOAD_IMAGE) {
 			/*
 			 * TODO: Consider wiping the code for SMC loading from
diff --git a/services/spd/opteed/teesmc_opteed.h b/services/spd/opteed/teesmc_opteed.h
index eae3ed2..4026fa4 100644
--- a/services/spd/opteed/teesmc_opteed.h
+++ b/services/spd/opteed/teesmc_opteed.h
@@ -157,4 +157,13 @@
 #define NSSMC_OPTEED_CALL_LOAD_IMAGE \
 	NSSMC_OPTEED_CALL(NSSMC_OPTEED_FUNCID_LOAD_IMAGE)
 
+/*
+ * Returns the UID of the OP-TEE image loading service if image loading is
+ * enabled and the image had not been loaded yet. Otherwise this call will be
+ * passed through to OP-TEE where it will return the OP-TEE UID.
+ */
+#define NSSMC_OPTEED_FUNCID_CALLS_UID 0xFF01
+#define NSSMC_OPTEED_CALL_UID \
+	NSSMC_OPTEED_CALL(NSSMC_OPTEED_FUNCID_CALLS_UID)
+
 #endif /*TEESMC_OPTEED_H*/
diff --git a/services/spd/opteed/teesmc_opteed_macros.h b/services/spd/opteed/teesmc_opteed_macros.h
index ad3ed75..7219140 100644
--- a/services/spd/opteed/teesmc_opteed_macros.h
+++ b/services/spd/opteed/teesmc_opteed_macros.h
@@ -17,7 +17,7 @@
 #define NSSMC_OPTEED_CALL(func_num) \
 		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
 		((SMC_32) << FUNCID_CC_SHIFT) | \
-		(50 << FUNCID_OEN_SHIFT) | \
+		(63 << FUNCID_OEN_SHIFT) | \
 		((func_num) & FUNCID_NUM_MASK))
 
 #endif /* TEESMC_OPTEED_MACROS_H */
diff --git a/services/std_svc/drtm/drtm_measurements.c b/services/std_svc/drtm/drtm_measurements.c
index a8f2b32..8d514b7 100644
--- a/services/std_svc/drtm/drtm_measurements.c
+++ b/services/std_svc/drtm/drtm_measurements.c
@@ -47,7 +47,7 @@
 	metadata.pcr = pcr;
 
 	/*
-	 * Measure the payloads requested by D-CRTM and DCE commponents
+	 * Measure the payloads requested by D-CRTM and DCE components
 	 * Hash algorithm decided by the Event Log driver at build-time
 	 */
 	rc = event_log_measure(data_base, data_size, hash_data);
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
new file mode 100644
index 0000000..00a3b73
--- /dev/null
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ERRATA_CPUSPEC_H
+#define ERRATA_CPUSPEC_H
+
+#include <stdint.h>
+#include <arch_helpers.h>
+
+#if __aarch64__
+#include <cortex_a35.h>
+#include <cortex_a510.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a55.h>
+#include <cortex_a710.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a75.h>
+#include <cortex_a76.h>
+#include <cortex_a77.h>
+#include <cortex_a78.h>
+#include <cortex_a78_ae.h>
+#include <cortex_a78c.h>
+#include <cortex_a715.h>
+#include <cortex_x1.h>
+#include <cortex_x2.h>
+#include <neoverse_n1.h>
+#include <neoverse_n2.h>
+#include <neoverse_v1.h>
+#include <neoverse_v2.h>
+#else
+#include <cortex_a15.h>
+#include <cortex_a17.h>
+#include <cortex_a57.h>
+#include <cortex_a9.h>
+#endif
+
+#define MAX_ERRATA_ENTRIES	16
+
+#define ERRATA_LIST_END		(MAX_ERRATA_ENTRIES - 1)
+
+/* Default values for unused memory in the array */
+#define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX, false, false}
+
+#define EXTRACT_PARTNUM(x)	((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+
+#define RXPX_RANGE(x, y, z)	(((x >= y) && (x <= z)) ? true : false)
+
+/*
+ * CPU specific values for errata handling
+ */
+struct em_cpu{
+	unsigned int em_errata_id;
+	unsigned char em_rxpx_lo;	/* lowest revision of errata applicable for the cpu */
+	unsigned char em_rxpx_hi;	/* highest revision of errata applicable for the cpu */
+	bool errata_enabled;		/* indicate if errata enabled */
+	/* flag to indicate if errata query is based out of non-arm interconnect */
+	bool non_arm_interconnect;
+};
+
+struct em_cpu_list{
+	/* field to hold cpu specific part number defined in midr reg */
+	unsigned long cpu_partnumber;
+	struct   em_cpu cpu_errata_list[MAX_ERRATA_ENTRIES];
+};
+
+int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag);
+#endif /* ERRATA_CPUSPEC_H */
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
new file mode 100644
index 0000000..bc176c6
--- /dev/null
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include "cpu_errata_info.h"
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <services/errata_abi_svc.h>
+#include <smccc_helpers.h>
+
+/*
+ * Global pointer that points to the specific
+ * structure based on the MIDR part number
+ */
+struct em_cpu_list *cpu_ptr;
+
+extern uint8_t cpu_get_rev_var(void);
+
+/* Structure array that holds CPU specific errata information */
+struct em_cpu_list cpu_list[] = {
+#if CORTEX_A9_H_INC
+{
+	.cpu_partnumber = CORTEX_A9_MIDR,
+	.cpu_errata_list = {
+		[0] = {794073, 0x00, 0xFF, ERRATA_A9_794073},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A9_H_INC */
+
+#if CORTEX_A15_H_INC
+{
+	.cpu_partnumber = CORTEX_A15_MIDR,
+	.cpu_errata_list = {
+		[0] = {816470, 0x30, 0xFF, ERRATA_A15_816470},
+		[1] = {827671, 0x30, 0xFF, ERRATA_A15_827671},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A15_H_INC */
+
+#if CORTEX_A17_H_INC
+{
+	.cpu_partnumber = CORTEX_A17_MIDR,
+	.cpu_errata_list = {
+		[0] = {852421, 0x00, 0x12, ERRATA_A17_852421},
+		[1] = {852423, 0x00, 0x12, ERRATA_A17_852423},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A17_H_INC */
+
+#if CORTEX_A35_H_INC
+{
+	.cpu_partnumber = CORTEX_A35_MIDR,
+	.cpu_errata_list = {
+		[0] = {855472, 0x00, 0x00, ERRATA_A35_855472},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A35_H_INC */
+
+#if CORTEX_A53_H_INC
+{
+	.cpu_partnumber = CORTEX_A53_MIDR,
+	.cpu_errata_list = {
+		[0] = {819472, 0x00, 0x01, ERRATA_A53_819472},
+		[1] = {824069, 0x00, 0x02, ERRATA_A53_824069},
+		[2] = {826319, 0x00, 0x02, ERRATA_A53_826319},
+		[3] = {827319, 0x00, 0x02, ERRATA_A53_827319},
+		[4] = {835769, 0x00, 0x04, ERRATA_A53_835769},
+		[5] = {836870, 0x00, 0x03, ERRATA_A53_836870},
+		[6] = {843419, 0x00, 0x04, ERRATA_A53_843419},
+		[7] = {855873, 0x03, 0xFF, ERRATA_A53_855873},
+		[8] = {1530924, 0x00, 0xFF, ERRATA_A53_1530924},
+		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A53_H_INC */
+
+#if CORTEX_A55_H_INC
+{
+	.cpu_partnumber = CORTEX_A55_MIDR,
+	.cpu_errata_list = {
+		[0] = {768277, 0x00, 0x00, ERRATA_A55_768277},
+		[1] = {778703, 0x00, 0x00, ERRATA_A55_778703},
+		[2] = {798797, 0x00, 0x00, ERRATA_A55_798797},
+		[3] = {846532, 0x00, 0x01, ERRATA_A55_846532},
+		[4] = {903758, 0x00, 0x01, ERRATA_A55_903758},
+		[5] = {1221012, 0x00, 0x10, ERRATA_A55_1221012},
+		[6] = {1530923, 0x00, 0xFF, ERRATA_A55_1530923},
+		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A55_H_INC */
+
+#if CORTEX_A57_H_INC
+{
+	.cpu_partnumber = CORTEX_A57_MIDR,
+	.cpu_errata_list = {
+		[0] = {806969, 0x00, 0x00, ERRATA_A57_806969},
+		[1] = {813419, 0x00, 0x00, ERRATA_A57_813419},
+		[2] = {813420, 0x00, 0x00, ERRATA_A57_813420},
+		[3] = {814670, 0x00, 0x00, ERRATA_A57_814670},
+		[4] = {817169, 0x00, 0x01, ERRATA_A57_817169},
+		[5] = {826974, 0x00, 0x11, ERRATA_A57_826974},
+		[6] = {826977, 0x00, 0x11, ERRATA_A57_826977},
+		[7] = {828024, 0x00, 0x11, ERRATA_A57_828024},
+		[8] = {829520, 0x00, 0x12, ERRATA_A57_829520},
+		[9] = {833471, 0x00, 0x12, ERRATA_A57_833471},
+		[10] = {859972, 0x00, 0x13, ERRATA_A57_859972},
+		[11] = {1319537, 0x00, 0xFF, ERRATA_A57_1319537},
+		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A57_H_INC */
+
+#if CORTEX_A72_H_INC
+{
+	.cpu_partnumber = CORTEX_A72_MIDR,
+	.cpu_errata_list = {
+		[0] = {859971, 0x00, 0x03, ERRATA_A72_859971},
+		[1] = {1319367, 0x00, 0xFF, ERRATA_A72_1319367},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A72_H_INC */
+
+#if CORTEX_A73_H_INC
+{
+	.cpu_partnumber = CORTEX_A73_MIDR,
+	.cpu_errata_list = {
+		[0] = {852427, 0x00, 0x00, ERRATA_A73_852427},
+		[1] = {855423, 0x00, 0x01, ERRATA_A73_855423},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A73_H_INC */
+
+#if CORTEX_A75_H_INC
+{
+	.cpu_partnumber = CORTEX_A75_MIDR,
+	.cpu_errata_list = {
+		[0] = {764081, 0x00, 0x00, ERRATA_A75_764081},
+		[1] = {790748, 0x00, 0x00, ERRATA_A75_790748},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A75_H_INC */
+
+#if CORTEX_A76_H_INC
+{
+	.cpu_partnumber = CORTEX_A76_MIDR,
+	.cpu_errata_list = {
+		[0] = {1073348, 0x00, 0x10, ERRATA_A76_1073348},
+		[1] = {1130799, 0x00, 0x20, ERRATA_A76_1130799},
+		[2] = {1165522, 0x00, 0xFF, ERRATA_A76_1165522},
+		[3] = {1220197, 0x00, 0x20, ERRATA_A76_1220197},
+		[4] = {1257314, 0x00, 0x30, ERRATA_A76_1257314},
+		[5] = {1262606, 0x00, 0x30, ERRATA_A76_1262606},
+		[6] = {1262888, 0x00, 0x30, ERRATA_A76_1262888},
+		[7] = {1275112, 0x00, 0x30, ERRATA_A76_1275112},
+		[8] = {1791580, 0x00, 0x40, ERRATA_A76_1791580},
+		[9] = {1868343, 0x00, 0x40, ERRATA_A76_1868343},
+		[10] = {1946160, 0x30, 0x41, ERRATA_A76_1946160},
+		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A76_H_INC */
+
+#if CORTEX_A77_H_INC
+{
+	.cpu_partnumber = CORTEX_A77_MIDR,
+	.cpu_errata_list = {
+		[0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412},
+		[1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578},
+		[2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714},
+		[3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769},
+		[4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167},
+		[5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587},
+		[6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100},
+		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A77_H_INC */
+
+#if CORTEX_A78_H_INC
+{
+	.cpu_partnumber = CORTEX_A78_MIDR,
+	.cpu_errata_list = {
+		[0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305},
+		[1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534},
+		[2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498},
+		[3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500},
+		[4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683},
+		[5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060},
+		[6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635},
+		[7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745},
+		[8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406},
+		[9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426},
+		[11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019},
+		[12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479},
+		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A78_H_INC */
+
+#if CORTEX_A78_AE_H_INC
+{
+	.cpu_partnumber = CORTEX_A78_AE_MIDR,
+	.cpu_errata_list = {
+		[0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500},
+		[1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502},
+		[2] = {2376748, 0x00, 0x01, ERRATA_A78_AE_2376748},
+		[3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408},
+		[4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[5 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A78_AE_H_INC */
+
+#if CORTEX_A78C_H_INC
+{
+	.cpu_partnumber = CORTEX_A78C_MIDR,
+	.cpu_errata_list = {
+		[0] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064},
+		[1] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
+		[2] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
+		[3] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
+		[4] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[5] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
+		[6] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
+		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A78C_H_INC */
+
+#if CORTEX_X1_H_INC
+{
+	.cpu_partnumber = CORTEX_X1_MIDR,
+	.cpu_errata_list = {
+		[0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305},
+		[1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534},
+		[2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429},
+		[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_X1_H_INC */
+
+#if NEOVERSE_N1_H_INC
+{
+	.cpu_partnumber = NEOVERSE_N1_MIDR,
+	.cpu_errata_list = {
+		[0] = {1073348, 0x00, 0x10, ERRATA_N1_1073348},
+		[1] = {1130799, 0x00, 0x20, ERRATA_N1_1130799},
+		[2] = {1165347, 0x00, 0x20, ERRATA_N1_1165347},
+		[3] = {1207823, 0x00, 0x20, ERRATA_N1_1207823},
+		[4] = {1220197, 0x00, 0x20, ERRATA_N1_1220197},
+		[5] = {1257314, 0x00, 0x30, ERRATA_N1_1257314},
+		[6] = {1262606, 0x00, 0x30, ERRATA_N1_1262606},
+		[7] = {1262888, 0x00, 0x30, ERRATA_N1_1262888},
+		[8] = {1275112, 0x00, 0x30, ERRATA_N1_1275112},
+		[9] = {1315703, 0x00, 0x30, ERRATA_N1_1315703},
+		[10] = {1542419, 0x30, 0x40, ERRATA_N1_1542419},
+		[11] = {1868343, 0x00, 0x40, ERRATA_N1_1868343},
+		[12] = {1946160, 0x30, 0x41, ERRATA_N1_1946160},
+		[13] = {2743102, 0x00, 0x41, ERRATA_N1_2743102},
+		[14 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* NEOVERSE_N1_H_INC */
+
+#if NEOVERSE_V1_H_INC
+{
+	.cpu_partnumber = NEOVERSE_V1_MIDR,
+	.cpu_errata_list = {
+		[0] = {1618635, 0x00, 0x0F, ERRATA_V1_1618635},
+		[1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420},
+		[2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573},
+		[3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267},
+		[4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756},
+		[5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577},
+		[6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096},
+		[7] = {2108267, 0x00, 0x11, ERRATA_V1_2108267},
+		[8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242},
+		[9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392},
+		[10] = {2294912, 0x00, 0x11, ERRATA_V1_2294912},
+		[11] = {2372203, 0x00, 0x11, ERRATA_V1_2372203},
+		[12] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[13] = {2743093, 0x00, 0x12, ERRATA_V1_2743093},
+		[14] = {2779461, 0x00, 0x12, ERRATA_V1_2779461},
+		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* NEOVERSE_V1_H_INC */
+
+#if CORTEX_A710_H_INC
+{
+	.cpu_partnumber = CORTEX_A710_MIDR,
+	.cpu_errata_list = {
+		[0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031},
+		[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
+		[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
+		[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
+		[4] = {2058056, 0x00, 0x10, ERRATA_A710_2058056},
+		[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
+		[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
+		[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
+		[8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715},
+		[9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384},
+		[10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065},
+		[11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622},
+		[12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219},
+		[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
+		[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515}
+	}
+},
+#endif /* CORTEX_A710_H_INC */
+
+#if NEOVERSE_N2_H_INC
+{
+	.cpu_partnumber = NEOVERSE_N2_MIDR,
+	.cpu_errata_list = {
+		[0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655},
+		[1] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
+		[2] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
+		[3] = {2138953, 0x00, 0x00, ERRATA_N2_2138953},
+		[4] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
+		[5] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
+		[6] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
+		[7] = {2242400, 0x00, 0x00, ERRATA_N2_2242400},
+		[8] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
+		[9] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
+		[10] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
+		[11] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
+		[12] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
+		[13] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[14] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
+		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* NEOVERSE_N2_H_INC */
+
+#if CORTEX_X2_H_INC
+{
+	.cpu_partnumber = CORTEX_X2_MIDR,
+	.cpu_errata_list = {
+		[0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765},
+		[1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096},
+		[2] = {2058056, 0x00, 0x20, ERRATA_X2_2058056},
+		[3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180},
+		[4] = {2083908, 0x00, 0x20, ERRATA_X2_2083908},
+		[5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715},
+		[6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384},
+		[7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622},
+		[8] = {2371105, 0x00, 0x21, ERRATA_X2_2371105},
+		[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[10] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
+		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_X2_H_INC */
+
+#if CORTEX_A510_H_INC
+{
+	.cpu_partnumber = CORTEX_A510_MIDR,
+	.cpu_errata_list = {
+		[0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240},
+		[1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909},
+		[2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739},
+		[3] = {2172148, 0x00, 0x10, ERRATA_A510_2172148},
+		[4] = {2218950, 0x00, 0x10, ERRATA_A510_2218950},
+		[5] = {2250311, 0x00, 0x10, ERRATA_A510_2250311},
+		[6] = {2288014, 0x00, 0x10, ERRATA_A510_2288014},
+		[7] = {2347730, 0x00, 0x11, ERRATA_A510_2347730},
+		[8] = {2371937, 0x00, 0x11, ERRATA_A510_2371937},
+		[9] = {2666669, 0x00, 0x11, ERRATA_A510_2666669},
+		[10] = {2684597, 0x00, 0x12, ERRATA_A510_2684597},
+		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A510_H_INC */
+
+#if NEOVERSE_V2_H_INC
+{
+	.cpu_partnumber = NEOVERSE_V2_MIDR,
+	.cpu_errata_list = {
+		[0] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* NEOVERSE_V2_H_INC */
+
+#if CORTEX_A715_H_INC
+{
+	.cpu_partnumber = CORTEX_A715_MIDR,
+	.cpu_errata_list = {
+		[0] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A715_H_INC */
+};
+
+/*
+ * Function to do binary search and check for the specific errata ID
+ * in the array of structures specific to the cpu identified.
+ */
+int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val)
+{
+	int low_index = 0U, mid_index = 0U;
+
+	int high_index = MAX_ERRATA_ENTRIES - 1;
+
+	assert(ptr != NULL);
+
+	/*
+	 * Pointer to the errata list of the cpu that matches
+	 * extracted partnumber in the cpu list
+	 */
+	struct em_cpu *erratum_ptr = NULL;
+
+	while (low_index <= high_index) {
+		mid_index = (low_index + high_index) / 2;
+
+		erratum_ptr = &ptr->cpu_errata_list[mid_index];
+		assert(erratum_ptr != NULL);
+
+		if (erratum_id < erratum_ptr->em_errata_id) {
+			high_index = mid_index - 1;
+		} else if (erratum_id > erratum_ptr->em_errata_id) {
+			low_index = mid_index + 1;
+		} else if (erratum_id == erratum_ptr->em_errata_id) {
+			if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \
+				erratum_ptr->em_rxpx_hi)) {
+				if ((erratum_ptr->errata_enabled) && \
+				(!(erratum_ptr->non_arm_interconnect))) {
+					return EM_HIGHER_EL_MITIGATION;
+				}
+				return EM_AFFECTED;
+			}
+			return EM_NOT_AFFECTED;
+		}
+	}
+	/* no matching errata ID */
+	return EM_UNKNOWN_ERRATUM;
+}
+
+/* Function to check if the errata exists for the specific CPU and rxpx */
+int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
+{
+	/*
+	 * Read MIDR value and extract the revision, variant and partnumber
+	 */
+	static uint32_t midr_val, cpu_partnum;
+	static uint8_t  cpu_rxpx_val;
+	int32_t ret_val = EM_UNKNOWN_ERRATUM;
+
+	/* Determine the number of cpu listed in the cpu list */
+	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
+
+	/* Read the midr reg to extract cpu, revision and variant info */
+	midr_val = read_midr();
+
+	/* Extract revision and variant from the MIDR register */
+	cpu_rxpx_val = cpu_get_rev_var();
+
+	/* Extract the cpu partnumber and check if the cpu is in the cpu list */
+	cpu_partnum = EXTRACT_PARTNUM(midr_val);
+
+	for (uint8_t i = 0; i < size_cpulist; i++) {
+		cpu_ptr = &cpu_list[i];
+		uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber);
+
+		if (partnum_extracted == cpu_partnum) {
+			/*
+			 * If the midr value is in the cpu list, binary search
+			 * for the errata ID and specific revision in the list.
+			 */
+			ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val);
+			break;
+		}
+	}
+	return ret_val;
+}
+
+/* Predicate indicating that a function id is part of EM_ABI */
+bool is_errata_fid(uint32_t smc_fid)
+{
+	return ((smc_fid == ARM_EM_VERSION) ||
+		(smc_fid == ARM_EM_FEATURES) ||
+		(smc_fid == ARM_EM_CPU_ERRATUM_FEATURES));
+
+}
+
+bool validate_spsr_mode(void)
+{
+	/* In AArch64, if the caller is EL1, return true */
+
+	#if __aarch64__
+		if (GET_EL(read_spsr_el3()) == MODE_EL1) {
+			return true;
+		}
+		return false;
+	#else
+
+	/* In AArch32, if in system/svc mode, return true */
+		uint8_t read_el_state = GET_M32(read_spsr());
+
+		if ((read_el_state == (MODE32_svc)) || (read_el_state == MODE32_sys)) {
+			return true;
+		}
+		return false;
+	#endif /* __aarch64__ */
+}
+
+uintptr_t errata_abi_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)
+{
+	int32_t ret_id = EM_UNKNOWN_ERRATUM;
+
+	switch (smc_fid) {
+	case ARM_EM_VERSION:
+		SMC_RET1(handle, MAKE_SMCCC_VERSION(
+			EM_VERSION_MAJOR, EM_VERSION_MINOR
+		));
+		break; /* unreachable */
+	case ARM_EM_FEATURES:
+		if (is_errata_fid((uint32_t)x1)) {
+			SMC_RET1(handle, EM_SUCCESS);
+		}
+
+		SMC_RET1(handle, EM_NOT_SUPPORTED);
+		break; /* unreachable */
+	case ARM_EM_CPU_ERRATUM_FEATURES:
+
+		/*
+		 * If the forward flag is greater than zero and the calling EL
+		 * is EL1 in AArch64 or in system mode or svc mode in case of AArch32,
+		 * return Invalid Parameters.
+		 */
+		if (((uint32_t)x2 != 0) && (validate_spsr_mode())) {
+			SMC_RET1(handle, EM_INVALID_PARAMETERS);
+		}
+		ret_id = verify_errata_implemented((uint32_t)x1, (uint32_t)x2);
+		SMC_RET1(handle, ret_id);
+		break; /* unreachable */
+	default:
+		{
+		   WARN("Unimplemented Errata ABI Service Call: 0x%x\n", smc_fid);
+		   SMC_RET1(handle, EM_UNKNOWN_ERRATUM);
+		   break; /* unreachable */
+		}
+	}
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index e12eae7..c80b524 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,8 @@
 #include <context.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/pubsub.h>
+#include <lib/extensions/pmuv3.h>
+#include <lib/extensions/sys_reg_trace.h>
 #include <lib/gpt_rme/gpt_rme.h>
 
 #include <lib/spinlock.h>
@@ -117,19 +119,16 @@
  ******************************************************************************/
 static void manage_extensions_realm(cpu_context_t *ctx)
 {
-#if ENABLE_SVE_FOR_NS
+	if (is_feat_sve_supported()) {
 	/*
 	 * Enable SVE and FPU in realm context when it is enabled for NS.
 	 * Realm manager must ensure that the SVE and FPU register
 	 * contexts are properly managed.
 	 */
-	sve_enable(ctx);
-#else
-	/*
-	 * Disable SVE and FPU in realm context when it is disabled for NS.
-	 */
-	sve_disable(ctx);
-#endif /* ENABLE_SVE_FOR_NS */
+		sve_enable(ctx);
+	}
+
+	pmuv3_enable(ctx);
 }
 
 /*******************************************************************************
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index e511bf5..b7bd317 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -10,6 +10,12 @@
 
 RMM_DEFAULT_LINKER_SCRIPT_SOURCE := services/std_svc/rmmd/trp/linker.ld.S
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        RMM_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        RMM_LDFLAGS	+=	--sort-section=alignment
+endif
+
 # Include the platform-specific TRP Makefile
 # If no platform-specific TRP Makefile exists, it means TRP is not supported
 # on this platform.
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 87a1fb7..3bdf4a2 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -270,11 +270,11 @@
 	 * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1
 	 */
 	u_register_t hcr_el2 = read_hcr();
-	bool el_is_in_host = is_armv8_1_vhe_present() &&
+	bool el_is_in_host = (read_feat_vhe_id_field() != 0U) &&
 			     (hcr_el2 & HCR_TGE_BIT) &&
 			     (hcr_el2 & HCR_E2H_BIT);
 
-	if (is_armv8_1_pan_present() &&
+	if (is_feat_pan_supported() &&
 	    ((client_el == MODE_EL1) ||
 		(client_el == MODE_EL2 && el_is_in_host)) &&
 	    ((client_el_sctlr & SCTLR_SPAN_BIT) == 0U)) {
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index 61afee3..13875b9 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -131,6 +131,9 @@
 
 	/* Track the current runtime model of the SP. */
 	enum sp_runtime_model rt_model;
+
+	/* Track the source partition ID to validate a direct response. */
+	uint16_t dir_req_origin_id;
 };
 
 /*
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 08e7218..ada6f45 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -260,6 +260,65 @@
 }
 
 /*******************************************************************************
+ * Helper function to validate the destination ID of a direct response.
+ ******************************************************************************/
+static bool direct_msg_validate_dst_id(uint16_t dst_id)
+{
+	struct secure_partition_desc *sp;
+
+	/* Check if we're targeting a normal world partition. */
+	if (ffa_is_normal_world_id(dst_id)) {
+		return true;
+	}
+
+	/* Or directed to the SPMC itself.*/
+	if (dst_id == FFA_SPMC_ID) {
+		return true;
+	}
+
+	/* Otherwise ensure the SP exists. */
+	sp = spmc_get_sp_ctx(dst_id);
+	if (sp != NULL) {
+		return true;
+	}
+
+	return false;
+}
+
+/*******************************************************************************
+ * Helper function to validate the response from a Logical Partition.
+ ******************************************************************************/
+static bool direct_msg_validate_lp_resp(uint16_t origin_id, uint16_t lp_id,
+					void *handle)
+{
+	/* Retrieve populated Direct Response Arguments. */
+	uint64_t x1 = SMC_GET_GP(handle, CTX_GPREG_X1);
+	uint64_t x2 = SMC_GET_GP(handle, CTX_GPREG_X2);
+	uint16_t src_id = ffa_endpoint_source(x1);
+	uint16_t dst_id = ffa_endpoint_destination(x1);
+
+	if (src_id != lp_id) {
+		ERROR("Invalid EL3 LP source ID (0x%x).\n", src_id);
+		return false;
+	}
+
+	/*
+	 * Check the destination ID is valid and ensure the LP is responding to
+	 * the original request.
+	 */
+	if ((!direct_msg_validate_dst_id(dst_id)) || (dst_id != origin_id)) {
+		ERROR("Invalid EL3 LP destination ID (0x%x).\n", dst_id);
+		return false;
+	}
+
+	if (!direct_msg_validate_arg2(x2)) {
+		ERROR("Invalid EL3 LP message encoding.\n");
+		return false;
+	}
+	return true;
+}
+
+/*******************************************************************************
  * Handle direct request messages and route to the appropriate destination.
  ******************************************************************************/
 static uint64_t direct_req_smc_handler(uint32_t smc_fid,
@@ -272,6 +331,7 @@
 				       void *handle,
 				       uint64_t flags)
 {
+	uint16_t src_id = ffa_endpoint_source(x1);
 	uint16_t dst_id = ffa_endpoint_destination(x1);
 	struct el3_lp_desc *el3_lp_descs;
 	struct secure_partition_desc *sp;
@@ -283,14 +343,29 @@
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
 
+	/* Validate Sender is either the current SP or from the normal world. */
+	if ((secure_origin && src_id != spmc_get_current_sp_ctx()->sp_id) ||
+		(!secure_origin && !ffa_is_normal_world_id(src_id))) {
+		ERROR("Invalid direct request source ID (0x%x).\n", src_id);
+		return spmc_ffa_error_return(handle,
+					FFA_ERROR_INVALID_PARAMETER);
+	}
+
 	el3_lp_descs = get_el3_lp_array();
 
 	/* Check if the request is destined for a Logical Partition. */
 	for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) {
 		if (el3_lp_descs[i].sp_id == dst_id) {
-			return el3_lp_descs[i].direct_req(
-					smc_fid, secure_origin, x1, x2, x3, x4,
-					cookie, handle, flags);
+			uint64_t ret = el3_lp_descs[i].direct_req(
+						smc_fid, secure_origin, x1, x2,
+						x3, x4, cookie, handle, flags);
+			if (!direct_msg_validate_lp_resp(src_id, dst_id,
+							 handle)) {
+				panic();
+			}
+
+			/* Message checks out. */
+			return ret;
 		}
 	}
 
@@ -332,6 +407,7 @@
 	 */
 	sp->ec[idx].rt_state = RT_STATE_RUNNING;
 	sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
+	sp->ec[idx].dir_req_origin_id = src_id;
 	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
 			       handle, cookie, flags, dst_id);
 }
@@ -370,7 +446,7 @@
 	 * Check that the response is either targeted to the Normal world or the
 	 * SPMC e.g. a PM response.
 	 */
-	if ((dst_id != FFA_SPMC_ID) && ffa_is_secure_world_id(dst_id)) {
+	if (!direct_msg_validate_dst_id(dst_id)) {
 		VERBOSE("Direct response to invalid partition ID (0x%x).\n",
 			dst_id);
 		return spmc_ffa_error_return(handle,
@@ -397,9 +473,18 @@
 		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
 	}
 
+	if (sp->ec[idx].dir_req_origin_id != dst_id) {
+		WARN("Invalid direct resp partition ID 0x%x != 0x%x on core%u.\n",
+		     dst_id, sp->ec[idx].dir_req_origin_id, idx);
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
 	/* Update the state of the SP execution context. */
 	sp->ec[idx].rt_state = RT_STATE_WAITING;
 
+	/* Clear the ongoing direct request ID. */
+	sp->ec[idx].dir_req_origin_id = INV_SP_ID;
+
 	/*
 	 * If the receiver is not the SPMC then forward the response to the
 	 * Normal world.
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
index d25344c..c7e864f 100644
--- a/services/std_svc/spm/el3_spmc/spmc_pm.c
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -83,6 +83,7 @@
 	/* Update the runtime model and state of the partition. */
 	ec->rt_model = RT_MODEL_INIT;
 	ec->rt_state = RT_STATE_RUNNING;
+	ec->dir_req_origin_id = INV_SP_ID;
 
 	INFO("SP (0x%x) init start on core%u.\n", sp->sp_id, linear_id);
 
@@ -132,6 +133,7 @@
 	/* Update the runtime model and state of the partition. */
 	ec->rt_model = RT_MODEL_DIR_REQ;
 	ec->rt_state = RT_STATE_RUNNING;
+	ec->dir_req_origin_id = FFA_SPMC_ID;
 
 	rc = spmc_sp_synchronous_entry(ec);
 	if (rc != 0ULL) {
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
index 8ebae28..6de25f6 100644
--- a/services/std_svc/spm/el3_spmc/spmc_setup.c
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -90,7 +90,7 @@
 			   boot_header->offset_boot_info_desc);
 
 	/*
-	 * We must use the FF-A version coresponding to the version implemented
+	 * We must use the FF-A version corresponding to the version implemented
 	 * by the SP. Currently this can only be v1.1.
 	 */
 	boot_header->version = sp->ffa_version;
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 c039350..5c3d580 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -1,10 +1,11 @@
 /*
- * 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
  */
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -79,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. */
@@ -195,24 +203,23 @@
 			uint32_t ffa_version, size_t *emad_size)
 {
 	uint8_t *emad;
+
+	assert(index < desc->emad_count);
+
 	/*
 	 * If the caller is using FF-A v1.0 interpret the descriptor as a v1.0
 	 * format, otherwise assume it is a v1.1 format.
 	 */
 	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
-		/* Cast our descriptor to the v1.0 format. */
-		struct ffa_mtd_v1_0 *mtd_v1_0 =
-					(struct ffa_mtd_v1_0 *) desc;
-		emad = (uint8_t *)  &(mtd_v1_0->emad);
+		emad = (uint8_t *)desc + offsetof(struct ffa_mtd_v1_0, emad);
 		*emad_size = sizeof(struct ffa_emad_v1_0);
 	} else {
-		if (!is_aligned(desc->emad_offset, 16)) {
-			WARN("Emad offset is not aligned.\n");
-			return NULL;
-		}
+		assert(is_aligned(desc->emad_offset, 16));
 		emad = ((uint8_t *) desc + desc->emad_offset);
 		*emad_size = desc->emad_size;
 	}
+
+	assert(((uint64_t)index * (uint64_t)*emad_size) <= UINT32_MAX);
 	return (emad + (*emad_size * index));
 }
 
@@ -236,10 +243,6 @@
 	struct ffa_emad_v1_0 *emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
 							     ffa_version,
 							     &emad_size);
-	/* Ensure the emad array was found. */
-	if (emad == NULL) {
-		return NULL;
-	}
 
 	/* Ensure the composite descriptor offset is aligned. */
 	if (!is_aligned(emad->comp_mrd_offset, 8)) {
@@ -252,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.
@@ -375,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;
 
@@ -395,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;
@@ -699,148 +679,269 @@
 		return 0;
 }
 
+static int
+spmc_validate_mtd_start(struct ffa_mtd *desc, uint32_t ffa_version,
+			size_t fragment_length, size_t total_length)
+{
+	unsigned long long emad_end;
+	unsigned long long emad_size;
+	unsigned long long emad_offset;
+	unsigned int min_desc_size;
+
+	/* Determine the appropriate minimum descriptor size. */
+	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+		min_desc_size = sizeof(struct ffa_mtd_v1_0);
+	} else if (ffa_version == MAKE_FFA_VERSION(1, 1)) {
+		min_desc_size = sizeof(struct ffa_mtd);
+	} else {
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+	if (fragment_length < min_desc_size) {
+		WARN("%s: invalid length %zu < %u\n", __func__, fragment_length,
+		     min_desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+
+	if (desc->emad_count == 0U) {
+		WARN("%s: unsupported attribute desc count %u.\n",
+		     __func__, desc->emad_count);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+
+	/*
+	 * If the caller is using FF-A v1.0 interpret the descriptor as a v1.0
+	 * format, otherwise assume it is a v1.1 format.
+	 */
+	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+		emad_offset = emad_size = sizeof(struct ffa_emad_v1_0);
+	} else {
+		if (!is_aligned(desc->emad_offset, 16)) {
+			WARN("%s: Emad offset %" PRIx32 " is not 16-byte aligned.\n",
+			     __func__, desc->emad_offset);
+			return FFA_ERROR_INVALID_PARAMETER;
+		}
+		if (desc->emad_offset < sizeof(struct ffa_mtd)) {
+			WARN("%s: Emad offset too small: 0x%" PRIx32 " < 0x%zx.\n",
+			     __func__, desc->emad_offset,
+			     sizeof(struct ffa_mtd));
+			return FFA_ERROR_INVALID_PARAMETER;
+		}
+		emad_offset = desc->emad_offset;
+		if (desc->emad_size < sizeof(struct ffa_emad_v1_0)) {
+			WARN("%s: Bad emad size (%" PRIu32 " < %zu).\n", __func__,
+			     desc->emad_size, sizeof(struct ffa_emad_v1_0));
+			return FFA_ERROR_INVALID_PARAMETER;
+		}
+		if (!is_aligned(desc->emad_size, 16)) {
+			WARN("%s: Emad size 0x%" PRIx32 " is not 16-byte aligned.\n",
+			     __func__, desc->emad_size);
+			return FFA_ERROR_INVALID_PARAMETER;
+		}
+		emad_size = desc->emad_size;
+	}
+
+	/*
+	 * Overflow is impossible: the arithmetic happens in at least 64-bit
+	 * precision, but all of the operands are bounded by UINT32_MAX, and
+	 * ((2^32 - 1)^2 + (2^32 - 1) + (2^32 - 1)) = ((2^32 - 1) * (2^32 + 1))
+	 * = (2^64 - 1).
+	 */
+	CASSERT(sizeof(desc->emad_count == 4), assert_emad_count_max_too_large);
+	emad_end = (desc->emad_count * (unsigned long long)emad_size) +
+		   (unsigned long long)sizeof(struct ffa_comp_mrd) +
+		   (unsigned long long)emad_offset;
+
+	if (emad_end > total_length) {
+		WARN("%s: Composite memory region extends beyond descriptor: 0x%llx > 0x%zx\n",
+		     __func__, emad_end, total_length);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+
+	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)
 {
-	uint32_t comp_mrd_offset = 0;
+	unsigned long long 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;
+	size_t header_emad_size;
+	size_t size;
+	size_t count;
+	size_t expected_size;
+	const 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 desc_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();
+	}
 
-		emad = spmc_shmem_obj_get_emad(&obj->desc, emad_num,
-					       ffa_version, &emad_size);
-		if (emad == NULL) {
-			WARN("%s: invalid emad structure.\n", __func__);
-			return -EINVAL;
+	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;
+
+	/* Loop through the endpoint descriptors, validating each of them. */
+	for (const struct ffa_emad_v1_0 *emad = first_emad; emad < end_emad;) {
+		ffa_endpoint_id16_t ep_id;
+
+		/*
+		 * 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.
+		 */
+		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;
+			}
 		}
 
 		/*
-		 * Validate the calculated emad address resides within the
-		 * descriptor.
+		 * The offset provided to the composite memory region descriptor
+		 * should be consistent across endpoint descriptors.
 		 */
-		if ((uintptr_t) emad >=
-		    (uintptr_t)((uint8_t *) &obj->desc + obj->desc_size)) {
-			WARN("Invalid emad access.\n");
-			return -EINVAL;
+		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;
 		}
 
-		offset = emad->comp_mrd_offset;
+		/* Advance to the next endpoint descriptor */
+		emad = emad_advance(emad, emad_size);
 
-		if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
-			desc_size =  sizeof(struct ffa_mtd_v1_0);
-		} else {
-			desc_size =  sizeof(struct ffa_mtd);
+		/*
+		 * Ensure neither this emad nor any subsequent emads have
+		 * the same partition ID as the previous emad.
+		 */
+		for (const struct ffa_emad_v1_0 *other_emad = emad;
+		     other_emad < end_emad;
+		     other_emad = emad_advance(other_emad, emad_size)) {
+			if (ep_id == other_emad->mapd.endpoint_id) {
+				WARN("%s: Duplicated endpoint id 0x%x\n",
+				     __func__, emad->mapd.endpoint_id);
+				return FFA_ERROR_INVALID_PARAMETER;
+			}
 		}
+	}
 
-		header_emad_size = desc_size +
-			(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);
+	/* Check that there is enough space for the composite descriptor. */
+	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(*comp);
 
-		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 = (const struct ffa_comp_mrd *)
+	       ((const uint8_t *)(&obj->desc) + comp_mrd_offset);
 
-		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);
+	/* Ensure that the expected and actual sizes are equal. */
+	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;
+	}
 
-		if (obj->desc_filled < obj->desc_size) {
-			/*
-			 * The whole descriptor has not yet been received.
-			 * Skip final checks.
-			 */
-			return 0;
+	total_page_count = 0;
+
+	/*
+	 * comp->address_range_count is 32-bit, so 'count' must fit in a
+	 * uint32_t at this point.
+	 */
+	for (size_t i = 0; i < count; i++) {
+		const struct ffa_cons_mrd *mrd = comp->address_range_array + i;
+
+		if (!is_aligned(mrd->address, PAGE_SIZE)) {
+			WARN("%s: invalid object, address in region descriptor "
+			     "%zu not 4K aligned (got 0x%016llx)",
+			     __func__, i, (unsigned long long)mrd->address);
 		}
 
 		/*
-		 * The offset provided to the composite memory region descriptor
-		 * should be consistent across endpoint descriptors. Store the
-		 * first entry and compare against subsequent entries.
+		 * No overflow possible: total_page_count can hold at
+		 * least 2^64 - 1, but will be have at most 2^32 - 1.
+		 * values added to it, each of which cannot exceed 2^32 - 1.
 		 */
-		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;
-			}
-		}
-
-		total_page_count = 0;
+		total_page_count += mrd->page_count;
+	}
 
-		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;
-		}
+	if (comp->total_page_count != total_page_count) {
+		WARN("%s: invalid object, desc total_page_count %u != %llu\n",
+		     __func__, comp->total_page_count, total_page_count);
+		return FFA_ERROR_INVALID_PARAMETER;
 	}
+
 	return 0;
 }
 
@@ -851,7 +952,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)
@@ -864,7 +966,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,
@@ -880,11 +982,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;
 			}
 		}
 
@@ -902,11 +1004,8 @@
 			       void *smc_handle)
 {
 	int ret;
-	size_t emad_size;
 	uint32_t handle_low;
 	uint32_t handle_high;
-	struct ffa_emad_v1_0 *emad;
-	struct ffa_emad_v1_0 *other_emad;
 
 	if (mbox->rxtx_page_count == 0U) {
 		WARN("%s: buffer pair not registered.\n", __func__);
@@ -914,9 +1013,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;
 	}
@@ -960,16 +1060,17 @@
 
 	if (obj->desc_filled == 0U) {
 		/* First fragment, descriptor header has been copied */
+		ret = spmc_validate_mtd_start(&obj->desc, ffa_version,
+					      fragment_length, obj->desc_size);
+		if (ret != 0) {
+			goto err_bad_desc;
+		}
+
 		obj->desc.handle = spmc_shmem_obj_state.next_handle++;
 		obj->desc.flags |= mtd_flag;
 	}
 
 	obj->desc_filled += fragment_length;
-	ret = spmc_shmem_check_obj(obj, ffa_version);
-	if (ret != 0) {
-		ret = FFA_ERROR_INVALID_PARAMETER;
-		goto err_bad_desc;
-	}
 
 	handle_low = (uint32_t)obj->desc.handle;
 	handle_high = obj->desc.handle >> 32;
@@ -982,63 +1083,14 @@
 
 	/* The full descriptor has been received, perform any final checks. */
 
-	/*
-	 * 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);
-		if (emad == NULL) {
-			ret = FFA_ERROR_INVALID_PARAMETER;
-			goto err_bad_desc;
-		}
-
-		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,
-					       &emad_size);
-		if (emad == NULL) {
-			ret = FFA_ERROR_INVALID_PARAMETER;
-			goto err_bad_desc;
-		}
-		for (size_t j = i + 1; j < obj->desc.emad_count; j++) {
-			other_emad = spmc_shmem_obj_get_emad(&obj->desc, j,
-							     ffa_version,
-							     &emad_size);
-			if (other_emad == NULL) {
-				ret = FFA_ERROR_INVALID_PARAMETER;
-				goto err_bad_desc;
-			}
-
-			if (emad->mapd.endpoint_id ==
-				other_emad->mapd.endpoint_id) {
-				WARN("%s: Duplicated endpoint id 0x%x\n",
-				     __func__, emad->mapd.endpoint_id);
-				ret = FFA_ERROR_INVALID_PARAMETER;
-				goto err_bad_desc;
-			}
-		}
+	ret = spmc_shmem_check_obj(obj, ffa_version);
+	if (ret != 0) {
+		goto err_bad_desc;
 	}
 
 	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;
 	}
 
@@ -1051,19 +1103,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;
@@ -1071,8 +1122,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);
@@ -1142,6 +1193,7 @@
 	struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
 	ffa_mtd_flag32_t mtd_flag;
 	uint32_t ffa_version = get_partition_ffa_version(secure_origin);
+	size_t min_desc_size;
 
 	if (address != 0U || page_count != 0U) {
 		WARN("%s: custom memory region for message not supported.\n",
@@ -1156,11 +1208,18 @@
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
 
-	/*
-	 * Check if the descriptor is smaller than the v1.0 descriptor. The
-	 * descriptor cannot be smaller than this structure.
-	 */
-	if (fragment_length < sizeof(struct ffa_mtd_v1_0)) {
+	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+		min_desc_size = sizeof(struct ffa_mtd_v1_0);
+	} else if (ffa_version == MAKE_FFA_VERSION(1, 1)) {
+		min_desc_size = sizeof(struct ffa_mtd);
+	} else {
+		WARN("%s: bad FF-A version.\n", __func__);
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Check if the descriptor is too small for the FF-A version. */
+	if (fragment_length < min_desc_size) {
 		WARN("%s: bad first fragment size %u < %zu\n",
 		     __func__, fragment_length, sizeof(struct ffa_mtd_v1_0));
 		return spmc_ffa_error_return(handle,
@@ -1482,11 +1541,6 @@
 
 		emad = spmc_shmem_obj_get_emad(req, i, ffa_version,
 					       &emad_size);
-		if (emad == NULL) {
-			WARN("%s: invalid emad structure.\n", __func__);
-			ret = FFA_ERROR_INVALID_PARAMETER;
-			goto err_unlock_all;
-		}
 
 		if ((uintptr_t) emad >= (uintptr_t)
 					((uint8_t *) req + total_length)) {
@@ -1510,21 +1564,12 @@
 
 		emad = spmc_shmem_obj_get_emad(req, i, ffa_version,
 					       &emad_size);
-		if (emad == NULL) {
-			ret = FFA_ERROR_INVALID_PARAMETER;
-			goto err_unlock_all;
-		}
 
 		for (size_t j = 0; j < obj->desc.emad_count; j++) {
 			other_emad = spmc_shmem_obj_get_emad(
 					&obj->desc, j, MAKE_FFA_VERSION(1, 1),
 					&emad_size);
 
-			if (other_emad == NULL) {
-				ret = FFA_ERROR_INVALID_PARAMETER;
-				goto err_unlock_all;
-			}
-
 			if (req->emad_count &&
 			    emad->mapd.endpoint_id ==
 			    other_emad->mapd.endpoint_id) {
diff --git a/services/std_svc/spm/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk
index f6691c3..513e8ef 100644
--- a/services/std_svc/spm/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm/spm_mm/spm_mm.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,10 +10,10 @@
 ifneq (${ARCH},aarch64)
         $(error "Error: SPM_MM is only supported on aarch64.")
 endif
-ifeq (${ENABLE_SVE_FOR_NS},1)
+ifneq (${ENABLE_SVE_FOR_NS},0)
         $(error "Error: SPM_MM is not compatible with ENABLE_SVE_FOR_NS")
 endif
-ifeq (${ENABLE_SME_FOR_NS},1)
+ifneq (${ENABLE_SME_FOR_NS},0)
         $(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS")
 endif
 ifeq (${CTX_INCLUDE_FPREGS},0)
diff --git a/services/std_svc/spm/spm_mm/spm_mm_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c
index 8525cd2..1ff7bb7 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_main.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_main.c
@@ -254,7 +254,7 @@
 	/*
 	 * The current secure partition design mandates
 	 * - at any point, only a single core can be
-	 *   executing in the secure partiton.
+	 *   executing in the secure partition.
 	 * - a core cannot be preempted by an interrupt
 	 *   while executing in secure partition.
 	 * Raise the running priority of the core to the
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index 8efbdc8..6f451c8 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 	$(error "Error: SPMD is only supported on aarch64.")
 endif
 
-ifeq (${ENABLE_SME_FOR_NS},1)
+ifneq (${ENABLE_SME_FOR_NS},0)
 	$(error "Error: SPMD is not compatible with ENABLE_SME_FOR_NS")
 endif
 
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index e85109d..6b16373 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -249,6 +249,76 @@
 	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
+ * handling of the interrupt to the platform handler, and return only upon
+ * successfully handling the Group0 interrupt.
+ ******************************************************************************/
+static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id,
+						  uint32_t flags,
+						  void *handle,
+						  void *cookie)
+{
+	uint32_t intid;
+
+	/* Sanity check the security state when the exception was generated. */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+	/* Sanity check the pointer to this cpu's context. */
+	assert(handle == cm_get_context(NON_SECURE));
+
+	assert(id == INTR_ID_UNAVAILABLE);
+
+	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
+
+	intid = plat_ic_get_pending_interrupt_id();
+
+	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
+		ERROR("Group0 interrupt %u not handled\n", intid);
+		panic();
+	}
+
+	return 0U;
+}
+#endif
+
+/*******************************************************************************
+ * spmd_handle_group0_intr_swd
+ * SPMC delegates handling of Group0 secure interrupt to EL3 firmware using
+ * FFA_EL3_INTR_HANDLE SMC call. Further, SPMD delegates the handling of the
+ * interrupt to the platform handler, and returns only upon successfully
+ * handling the Group0 interrupt.
+ ******************************************************************************/
+static uint64_t spmd_handle_group0_intr_swd(void *handle)
+{
+	uint32_t intid;
+
+	/* Sanity check the pointer to this cpu's context */
+	assert(handle == cm_get_context(SECURE));
+
+	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
+
+	intid = plat_ic_get_pending_interrupt_id();
+
+	/*
+	 * TODO: Currently due to a limitation in SPMD implementation, the
+	 * platform handler is expected to not delegate handling to NWd while
+	 * processing Group0 secure interrupt.
+	 */
+	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
+		/* Group0 interrupt was not handled by the platform. */
+		ERROR("Group0 interrupt %u not handled\n", intid);
+		panic();
+	}
+
+	/* Return success. */
+	SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		 FFA_PARAM_MBZ);
+}
+
 #if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
 static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size,
 				 unsigned int attr, uintptr_t *align_addr,
@@ -399,7 +469,7 @@
 	 * Check if S-EL2 is supported on this system if S-EL2
 	 * is required for SPM
 	 */
-	if (!is_armv8_4_sel2_present()) {
+	if (!is_feat_sel2_supported()) {
 		WARN("SPM Core run time S-EL2 is not supported.\n");
 		return -EINVAL;
 	}
@@ -491,6 +561,30 @@
 	if (rc != 0) {
 		panic();
 	}
+
+	/*
+	 * 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.
+	 */
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+					     spmd_group0_interrupt_handler_nwd,
+					     flags);
+	if (rc != 0) {
+		panic();
+	}
+#endif
 
 	return 0;
 }
@@ -1089,6 +1183,12 @@
 					handle, flags);
 		break; /* Not reached */
 #endif
+	case FFA_EL3_INTR_HANDLE:
+		if (secure_origin) {
+			return spmd_handle_group0_intr_swd(handle);
+		} else {
+			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
+		}
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
 		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index d21a622..ff6942e 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -93,6 +93,13 @@
 int spmd_pm_secondary_ep_register(uintptr_t entry_point);
 bool spmd_check_address_in_binary_image(uint64_t address);
 
+/*
+ * Platform hook in EL3 firmware to handle for Group0 secure interrupt.
+ * Return values:
+ *  0 = success
+ *  otherwise it returns a negative value
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t id);
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_PRIVATE_H */
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 2884a3b..e782d09 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <lib/psci/psci.h>
 #include <lib/runtime_instr.h>
 #include <services/drtm_svc.h>
+#include <services/errata_abi_svc.h>
 #include <services/pci_svc.h>
 #include <services/rmmd_svc.h>
 #include <services/sdei.h>
@@ -177,6 +178,13 @@
 	}
 #endif /* TRNG_SUPPORT */
 
+#if ERRATA_ABI_SUPPORT
+	if (is_errata_fid(smc_fid)) {
+		return errata_abi_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					      handle, flags);
+	}
+#endif /* ERRATA_ABI_SUPPORT */
+
 #if ENABLE_RME
 
 	if (is_rmmd_el3_fid(smc_fid)) {
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 042e844..b911d19 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -85,9 +85,9 @@
 
 .PHONY: all clean realclean --openssl
 
-all: ${BINARY}
+all: --openssl ${BINARY}
 
-${BINARY}: --openssl ${OBJECTS} Makefile
+${BINARY}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
                 const char platform_msg[] = "${PLAT_MSG}";' | \
diff --git a/tools/cert_create/include/cca/cca_cot.h b/tools/cert_create/include/cca/cca_cot.h
index 56585fb..152cb71 100644
--- a/tools/cert_create/include/cca/cca_cot.h
+++ b/tools/cert_create/include/cca/cca_cot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
 /* Certificate extensions. */
 enum {
 	/* Extensions used in certificates owned by the silicon provider. */
+	CCA_FW_NVCOUNTER_EXT,
 	TRUSTED_FW_NVCOUNTER_EXT,
 	TRUSTED_BOOT_FW_HASH_EXT,
 	TRUSTED_BOOT_FW_CONFIG_HASH_EXT,
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
index 0e7f3be..1d55486 100644
--- a/tools/cert_create/include/ext.h
+++ b/tools/cert_create/include/ext.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
  */
@@ -20,7 +20,8 @@
 /* NV-Counter types */
 enum nvctr_type_e {
 	NVCTR_TYPE_TFW,
-	NVCTR_TYPE_NTFW
+	NVCTR_TYPE_NTFW,
+	NVCTR_TYPE_CCAFW
 };
 
 /*
diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c
index 5a35ff6..e39b036 100644
--- a/tools/cert_create/src/cca/cot.c
+++ b/tools/cert_create/src/cca/cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@
 		.key = ROT_KEY,
 		.issuer = CCA_CONTENT_CERT,
 		.ext = {
-			TRUSTED_FW_NVCOUNTER_EXT,
+			CCA_FW_NVCOUNTER_EXT,
 			SOC_AP_FW_HASH_EXT,
 			SOC_FW_CONFIG_HASH_EXT,
 			RMM_HASH_EXT,
@@ -139,6 +139,17 @@
 
 /* Certificate extensions. */
 static ext_t cot_ext[] = {
+	[CCA_FW_NVCOUNTER_EXT] = {
+		.oid = CCA_FW_NVCOUNTER_OID,
+		.opt = "ccafw-nvctr",
+		.help_msg = "CCA Firmware Non-Volatile counter value",
+		.sn = "CCANVCounter",
+		.ln = "CCA Non-Volatile counter",
+		.asn1_type = V_ASN1_INTEGER,
+		.type = EXT_TYPE_NVCOUNTER,
+		.attr.nvctr_type = NVCTR_TYPE_CCAFW
+	},
+
 	[TRUSTED_FW_NVCOUNTER_EXT] = {
 		.oid = TRUSTED_FW_NVCOUNTER_OID,
 		.opt = "tfw-nvctr",
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/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index 3dd9877..116b28b 100644
--- a/tools/conventional-changelog-tf-a/package.json
+++ b/tools/conventional-changelog-tf-a/package.json
@@ -1,6 +1,6 @@
 {
   "name": "conventional-changelog-tf-a",
-  "version": "2.8.0",
+  "version": "2.9.0",
   "license": "BSD-3-Clause",
   "private": true,
   "main": "index.js",
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 2939b14..924e5fe 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -65,9 +65,9 @@
 
 .PHONY: all clean realclean --openssl
 
-all: ${BINARY}
+all: --openssl ${BINARY}
 
-${BINARY}: --openssl ${OBJECTS} Makefile
+${BINARY}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
                 ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index d7e0fe5..4bdebd9 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -54,18 +54,23 @@
 ifneq (${PLAT},)
 TF_PLATFORM_ROOT	:=	../../plat/
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
-PLAT_FIPTOOL_HELPER_MK := ${PLAT_DIR}/plat_fiptool.mk
+COMBINED_PATH_FRAG := plat_fiptool/
+PLAT_FIPTOOL_HELPER_MK := $(foreach path_frag,$(subst /, ,$(patsubst ../../plat/%/,%,${PLAT_DIR})),\
+			  $(eval COMBINED_PATH_FRAG := ${COMBINED_PATH_FRAG}/${path_frag})\
+			  $(wildcard ${COMBINED_PATH_FRAG}/plat_fiptool.mk))
 endif
 
-ifneq (,$(wildcard ${PLAT_FIPTOOL_HELPER_MK}))
+ifneq (,$(wildcard $(lastword ${PLAT_FIPTOOL_HELPER_MK})))
 include ${PLAT_FIPTOOL_HELPER_MK}
 endif
 
+DEPS := $(patsubst %.o,%.d,$(OBJECTS))
+
 .PHONY: all clean distclean --openssl
 
-all: ${PROJECT}
+all: --openssl ${PROJECT}
 
-${PROJECT}: --openssl ${OBJECTS} Makefile
+${PROJECT}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
 	@${ECHO_BLANK_LINE}
@@ -74,7 +79,9 @@
 
 %.o: %.c Makefile
 	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
+
+-include $(DEPS)
 
 --openssl:
 ifeq ($(DEBUG),1)
@@ -83,4 +90,4 @@
 
 
 clean:
-	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} $(DEPS))
diff --git a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
new file mode 100644
index 0000000..46b5179
--- /dev/null
+++ b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_DEF_UUID := yes
+
+ifeq (${PLAT_DEF_UUID}, yes)
+HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
+ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
+HOSTCCFLAGS += -DARM_ETHOSN_NPU_TZMP1
+endif
+INCLUDE_PATHS += -I./ -I${PLAT_DIR}fip -I../../include/
+OBJECTS += ${PLAT_DIR}fip/plat_def_uuid_config.o
+endif
diff --git a/plat/arm/board/tc/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
similarity index 100%
rename from plat/arm/board/tc/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
diff --git a/tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk
new file mode 100644
index 0000000..70ccfc5
--- /dev/null
+++ b/tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2021, NXP. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+INCLUDE_PATHS += -I./ \
+		 -I../../plat/arm/board/tc
+
+HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
+OBJECTS += plat_fiptool/arm/board/tc/plat_def_uuid_config.o
diff --git a/tools/nxp/plat_fiptool/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/nxp/plat_def_uuid_config.c
similarity index 100%
rename from tools/nxp/plat_fiptool/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/nxp/plat_def_uuid_config.c
diff --git a/tools/nxp/plat_fiptool/plat_fiptool.mk b/tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
similarity index 80%
rename from tools/nxp/plat_fiptool/plat_fiptool.mk
rename to tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
index ca2962a..6d7b07b 100644
--- a/tools/nxp/plat_fiptool/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2021, NXP. All rights reserved.
+# Copyright (c) 2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,7 +10,7 @@
 # in the plat_def_toc_entries[].
 PLAT_DEF_UUID_CONFIG_FILE_NAME	:= plat_def_uuid_config
 
-PLAT_DEF_UUID_CONFIG_FILE_PATH := ../nxp/plat_fiptool
+PLAT_DEF_UUID_CONFIG_FILE_PATH := plat_fiptool/nxp/
 
 PLAT_DEF_OID := yes
 PLAT_DEF_UUID := yes
@@ -18,8 +19,6 @@
 
 INCLUDE_PATHS += -I${PLAT_DEF_UUID_OID_CONFIG_PATH} \
 		 -I./
-# Clean the stale object file.
-$(shell rm ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o)
 
 ifeq (${PLAT_DEF_OID},yes)
 HOSTCCFLAGS += -DPLAT_DEF_OID
diff --git a/plat/st/stm32mp1/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
similarity index 63%
rename from plat/st/stm32mp1/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
index efaf567..4df4144 100644
--- a/plat/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/plat/st/stm32mp1/plat_fiptool.mk b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
similarity index 87%
rename from plat/st/stm32mp1/plat_fiptool.mk
rename to tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
index 00570c2..1ba47c1 100644
--- a/plat/st/stm32mp1/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
@@ -16,7 +16,7 @@
 ifeq (${PLAT_DEF_UUID},yes)
 HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
 
-${PLAT_DEF_UUID_FILE_NAME}.o: ${PLAT_DIR}${PLAT_DEF_UUID_FILE_NAME}.c
+${PLAT_DEF_UUID_FILE_NAME}.o: plat_fiptool/st/stm32mp1/${PLAT_DEF_UUID_FILE_NAME}.c
 	${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 PLAT_OBJECTS += ${PLAT_DEF_UUID_FILE_NAME}.o
diff --git a/tools/fiptool/win_posix.h b/tools/fiptool/win_posix.h
index 6f0d8e6..1340640 100644
--- a/tools/fiptool/win_posix.h
+++ b/tools/fiptool/win_posix.h
@@ -149,7 +149,7 @@
  * Windows does not have the getopt family of functions, as it normally
  * uses '/' instead of '-' as the command line option delimiter.
  * These functions provide a Windows version that  uses '-', which precludes
- * using '-' as the intial letter of a program argument.
+ * using '-' as the initial letter of a program argument.
  * This is not seen as a problem in the specific instance of fiptool,
  * and enables existing makefiles to work on a Windows build environment.
  */
diff --git a/tools/memory/__init__.py b/tools/memory/__init__.py
new file mode 100644
index 0000000..0b4c8d3
--- /dev/null
+++ b/tools/memory/__init__.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
diff --git a/tools/memory/memory/__init__.py b/tools/memory/memory/__init__.py
new file mode 100644
index 0000000..0b4c8d3
--- /dev/null
+++ b/tools/memory/memory/__init__.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
diff --git a/tools/memory/memory/buildparser.py b/tools/memory/memory/buildparser.py
new file mode 100755
index 0000000..dedff79
--- /dev/null
+++ b/tools/memory/memory/buildparser.py
@@ -0,0 +1,88 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import re
+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, map_backend=False):
+        self._modules = dict()
+        self._path = path
+        self.map_backend = map_backend
+        self._parse_modules()
+
+    def __getitem__(self, module: str):
+        """Returns an TfaElfParser instance indexed by module."""
+        return self._modules[module]
+
+    def _parse_modules(self):
+        """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 files to analyse in path {self._path}!"
+            )
+
+    @property
+    def symbols(self) -> list:
+        return [
+            (*sym, k) for k, v in self._modules.items() for sym in v.symbols
+        ]
+
+    @staticmethod
+    def filter_symbols(symbols: list, regex: str = None) -> list:
+        """Returns a map of symbols to modules."""
+        regex = r".*" if not regex else regex
+        return sorted(
+            filter(lambda s: re.match(regex, s[0]), symbols),
+            key=lambda s: (-s[1], s[0]),
+            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."""
+        return sorted(self._modules.keys())
diff --git a/tools/memory/memory/elfparser.py b/tools/memory/memory/elfparser.py
new file mode 100644
index 0000000..2dd2513
--- /dev/null
+++ b/tools/memory/memory/elfparser.py
@@ -0,0 +1,161 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# 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.
+
+    Provides a basic interface for reading the symbol table and other
+    attributes of an ELF file. The constructor accepts a file-like object with
+    the contents an ELF file.
+    """
+
+    def __init__(self, elf_file: BinaryIO):
+        self._segments = {}
+        self._memory_layout = {}
+
+        elf = ELFFile(elf_file)
+
+        self._symbols = {
+            sym.name: sym.entry["st_value"]
+            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
new file mode 100755
index 0000000..99149b5
--- /dev/null
+++ b/tools/memory/memory/memmap.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from pathlib import Path
+
+import click
+from memory.buildparser import TfaBuildParser
+from memory.printer import TfaPrettyPrinter
+
+
+@click.command()
+@click.option(
+    "-r",
+    "--root",
+    type=Path,
+    default=None,
+    help="Root containing build output.",
+)
+@click.option(
+    "-p",
+    "--platform",
+    show_default=True,
+    default="fvp",
+    help="The platform targeted for analysis.",
+)
+@click.option(
+    "-b",
+    "--build-type",
+    default="release",
+    help="The target build type.",
+    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,
+    help="Generate a map of important TF symbols.",
+)
+@click.option("-w", "--width", type=int, envvar="COLUMNS")
+@click.option(
+    "-d",
+    is_flag=True,
+    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, 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|UNALIGNED|END)__$"
+        )
+        printer.print_symbol_table(
+            parser.filter_symbols(parser.symbols, expr), parser.module_names
+        )
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/memory/memory/printer.py b/tools/memory/memory/printer.py
new file mode 100755
index 0000000..4b18560
--- /dev/null
+++ b/tools/memory/memory/printer.py
@@ -0,0 +1,163 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# 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.
+
+    This class provides interfaces for printing various memory layout views of
+    ELF files in a TF-A build. It can be used to understand how the memory is
+    structured and consumed.
+    """
+
+    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
+
+    def format_args(self, *args, width=10, fmt=None):
+        if not fmt and type(args[0]) is int:
+            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,
+        section_name: str,
+        rel_pos: int,
+        columns: int,
+        width: int = None,
+        is_edge: bool = False,
+    ):
+        empty_col = "{:{}{}}"
+
+        # Some symbols are longer than the column width, truncate them until
+        # we find a more elegant way to display them!
+        len_over = len(section_name) - width
+        if len_over > 0:
+            section_name = section_name[len_over:-len_over]
+
+        sec_row = f"+{section_name:-^{width-1}}+"
+        sep, fill = ("+", "-") if is_edge else ("|", "")
+
+        sec_row_l = empty_col.format(sep, fill + "<", width) * rel_pos
+        sec_row_r = empty_col.format(sep, fill + ">", width) * (
+            columns - rel_pos - 1
+        )
+
+        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 = 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 = (
+            f"0=#0{address_fixed_width}x" if not self.as_decimal else ">10"
+        )
+
+        _symbol_map = [
+            " " * start
+            + "".join(self.format_args(*modules, fmt=f"^{col_width}"))
+        ]
+        last_addr = None
+
+        for i, (name, addr, mod) in enumerate(symbols):
+            # Do not print out an address twice if two symbols overlap,
+            # for example, at the end of one region and start of another.
+            leading = (
+                f"{addr:{num_fmt}}" + " " if addr != last_addr else " " * start
+            )
+
+            _symbol_map.append(
+                self.map_elf_symbol(
+                    leading,
+                    name,
+                    modules.index(mod),
+                    len(modules),
+                    width=col_width,
+                    is_edge=(not i or i == len(symbols) - 1),
+                )
+            )
+
+            last_addr = addr
+
+        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")
diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py
deleted file mode 100755
index ef53f7e..0000000
--- a/tools/memory/print_memory_map.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-import re
-import os
-import sys
-import operator
-
-# List of folder/map to parse
-bl_images = ['bl1', 'bl2', 'bl31']
-
-# List of symbols to search for
-blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__',
-                '__BL2_END__',
-                '__BL31_END__',
-                '__RO_START__', '__RO_END_UNALIGNED__', '__RO_END__',
-                '__TEXT_START__', '__TEXT_END__',
-                '__TEXT_RESIDENT_START__', '__TEXT_RESIDENT_END__',
-                '__RODATA_START__', '__RODATA_END__',
-                '__DATA_START__', '__DATA_END__',
-                '__STACKS_START__', '__STACKS_END__',
-                '__BSS_START__', '__BSS_END__',
-                '__COHERENT_RAM_START__', '__COHERENT_RAM_END__',
-                '__CPU_OPS_START__', '__CPU_OPS_END__',
-                '__FCONF_POPULATOR_START__', '__FCONF_POPULATOR_END__',
-                '__GOT_START__', '__GOT_END__',
-                '__PARSER_LIB_DESCS_START__', '__PARSER_LIB_DESCS_END__',
-                '__PMF_TIMESTAMP_START__', '__PMF_TIMESTAMP_END__',
-                '__PMF_SVC_DESCS_START__', '__PMF_SVC_DESCS_END__',
-                '__RELA_START__', '__RELA_END__',
-                '__RT_SVC_DESCS_START__', '__RT_SVC_DESCS_END__',
-                '__BASE_XLAT_TABLE_START__', '__BASE_XLAT_TABLE_END__',
-                '__XLAT_TABLE_START__', '__XLAT_TABLE_END__',
-               ]
-
-# Regex to extract address from map file
-address_pattern = re.compile(r"\b0x\w*")
-
-# List of found element: [address, symbol, file]
-address_list = []
-
-# Get the directory from command line or use a default one
-inverted_print = True
-if len(sys.argv) >= 2:
-    build_dir = sys.argv[1]
-    if len(sys.argv) >= 3:
-        inverted_print = sys.argv[2] == '0'
-else:
-    build_dir = 'build/fvp/debug'
-
-max_len = max(len(word) for word in blx_symbols) + 2
-if (max_len % 2) != 0:
-    max_len += 1
-
-# Extract all the required symbols from the map files
-for image in bl_images:
-    file_path = os.path.join(build_dir, image, '{}.map'.format(image))
-    if os.path.isfile(file_path):
-        with open (file_path, 'rt') as mapfile:
-            for line in mapfile:
-                for symbol in blx_symbols:
-                    skip_symbol = 0
-                    # Regex to find symbol definition
-                    line_pattern = re.compile(r"\b0x\w*\s*" + symbol + "\s= .")
-                    match = line_pattern.search(line)
-                    if match:
-                        # Extract address from line
-                        match = address_pattern.search(line)
-                        if match:
-                            if '_END__' in symbol:
-                                sym_start = symbol.replace('_END__', '_START__')
-                                if [match.group(0), sym_start, image] in address_list:
-                                    address_list.remove([match.group(0), sym_start, image])
-                                    skip_symbol = 1
-                            if skip_symbol == 0:
-                                address_list.append([match.group(0), symbol, image])
-
-# Sort by address
-address_list.sort(key=operator.itemgetter(0))
-
-# Invert list for lower address at bottom
-if inverted_print:
-    address_list = reversed(address_list)
-
-# Generate memory view
-print(('{:-^%d}' % (max_len * 3 + 20 + 7)).format('Memory Map from: ' + build_dir))
-for address in address_list:
-    if "bl1" in address[2]:
-        print(address[0], ('+{:-^%d}+ |{:^%d}| |{:^%d}|' % (max_len, max_len, max_len)).format(address[1], '', ''))
-    elif "bl2" in address[2]:
-        print(address[0], ('|{:^%d}| +{:-^%d}+ |{:^%d}|' % (max_len, max_len, max_len)).format('', address[1], ''))
-    elif "bl31" in address[2]:
-        print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1]))
-    else:
-        print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1]))
-
-print(('{:^20}{:_^%d}   {:_^%d}   {:_^%d}' % (max_len, max_len, max_len)).format('', '', '', ''))
-print(('{:^20}{:^%d}   {:^%d}   {:^%d}' % (max_len, max_len, max_len)).format('address', 'bl1', 'bl2', 'bl31'))
diff --git a/tools/nxp/create_pbl/create_pbl.c b/tools/nxp/create_pbl/create_pbl.c
index 792747f..c277e39 100644
--- a/tools/nxp/create_pbl/create_pbl.c
+++ b/tools/nxp/create_pbl/create_pbl.c
@@ -912,7 +912,7 @@
 		while (word != 0x808f0000 && word != 0x80ff0000) {
 			pbl_size++;
 			/* 11th words in RCW has PBL length. Update it
-			 * with new length. 2 comamnds get added
+			 * with new length. 2 commands get added
 			 * Block copy + CCSR Write/CSF header write
 			 */
 			if (pbl_size == 11) {